Compare commits

..

No commits in common. "master" and "v0.41.1" have entirely different histories.

16 changed files with 379 additions and 715 deletions

View file

@ -18,9 +18,12 @@ gen:
protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:proto/ proto/roveapi/roveapi.proto protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:proto/ proto/roveapi/roveapi.proto
test: test:
@echo Run unit and integration tests @echo Unit tests
docker-compose -f docker-compose-test.yml up --build --exit-code-from=rove-tests --abort-on-container-exit rove-tests go test -v ./...
docker-compose -f docker-compose-test.yml down
@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 go tool cover -html=/tmp/coverage-data/c.out -o /tmp/coverage.html
@echo Done, coverage data can be found in /tmp/coverage.html @echo Done, coverage data can be found in /tmp/coverage.html

View file

@ -1,8 +1,9 @@
Rove 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. 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.

View file

@ -4,8 +4,6 @@ import (
"fmt" "fmt"
"log" "log"
"net" "net"
"os"
"path"
"sync" "sync"
"github.com/mdiluz/rove/pkg/persistence" "github.com/mdiluz/rove/pkg/persistence"
@ -13,12 +11,8 @@ import (
"github.com/mdiluz/rove/proto/roveapi" "github.com/mdiluz/rove/proto/roveapi"
"github.com/robfig/cron" "github.com/robfig/cron"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/reflection"
) )
var cert = os.Getenv("CERT_NAME")
const ( const (
// PersistentData will allow the server to load and save it's state // PersistentData will allow the server to load and save it's state
PersistentData = iota PersistentData = iota
@ -109,22 +103,8 @@ func (s *Server) Initialise(fillWorld bool) (err error) {
if err != nil { if err != nil {
log.Fatalf("failed to listen: %v", err) log.Fatalf("failed to listen: %v", err)
} }
s.grpcServ = grpc.NewServer()
// 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...)
roveapi.RegisterRoveServer(s.grpcServ, s) roveapi.RegisterRoveServer(s.grpcServ, s)
reflection.Register(s.grpcServ)
return nil return nil
} }

View file

@ -1,7 +1,6 @@
package internal package internal
import ( import (
"os"
"testing" "testing"
) )
@ -31,7 +30,6 @@ func TestNewServer_OptionPersistentData(t *testing.T) {
} }
func TestServer_Run(t *testing.T) { func TestServer_Run(t *testing.T) {
os.Setenv("NO_TLS", "1")
server := NewServer() server := NewServer()
if server == nil { if server == nil {
t.Error("Failed to create server") t.Error("Failed to create server")
@ -47,7 +45,6 @@ func TestServer_Run(t *testing.T) {
} }
func TestServer_RunPersistentData(t *testing.T) { func TestServer_RunPersistentData(t *testing.T) {
os.Setenv("NO_TLS", "1")
server := NewServer(OptionPersistentData()) server := NewServer(OptionPersistentData())
if server == nil { if server == nil {
t.Error("Failed to create server") t.Error("Failed to create server")

View file

@ -25,9 +25,6 @@ const (
// GlyphRoverDormant represents a dormant rover // GlyphRoverDormant represents a dormant rover
GlyphRoverDormant = Glyph('r') GlyphRoverDormant = Glyph('r')
// GlyphRoverParts represents spare rover parts
GlyphRoverParts = Glyph('*')
// GlyphRockSmall is a small stashable rock // GlyphRockSmall is a small stashable rock
GlyphRockSmall = Glyph('o') GlyphRockSmall = Glyph('o')
@ -61,8 +58,6 @@ func ObjectGlyph(o roveapi.Object) Glyph {
return GlyphRoverDormant return GlyphRoverDormant
case roveapi.Object_RockLarge: case roveapi.Object_RockLarge:
return GlyphRockLarge return GlyphRockLarge
case roveapi.Object_RoverParts:
return GlyphRoverParts
} }
log.Fatalf("Unknown object type: %c", o) log.Fatalf("Unknown object type: %c", o)

View file

@ -1,7 +1,6 @@
package main package main
import ( import (
"crypto/tls"
"encoding/json" "encoding/json"
"fmt" "fmt"
"io/ioutil" "io/ioutil"
@ -9,7 +8,6 @@ import (
"os" "os"
"path" "path"
"path/filepath" "path/filepath"
"strconv"
"time" "time"
"github.com/mdiluz/rove/cmd/rove/internal" "github.com/mdiluz/rove/cmd/rove/internal"
@ -17,7 +15,6 @@ import (
"github.com/mdiluz/rove/proto/roveapi" "github.com/mdiluz/rove/proto/roveapi"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
"google.golang.org/grpc/credentials"
) )
var home = os.Getenv("HOME") var home = os.Getenv("HOME")
@ -25,30 +22,24 @@ var defaultDataPath = path.Join(home, ".local/share/")
// Command usage // Command usage
func printUsage() { func printUsage() {
fmt.Fprintln(os.Stderr, "Usage: rove ARG [OPT...]") fmt.Fprintf(os.Stderr, "Usage: rove COMMAND [ARGS...]\n")
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintln(os.Stderr, "\nCommands")
fmt.Fprintln(os.Stderr, "Arguments:") fmt.Fprintln(os.Stderr, "\tserver-status prints the server status")
fmt.Fprintln(os.Stderr, "\tversion outputs version") fmt.Fprintln(os.Stderr, "\tregister NAME registers an account and stores it (use with -name)")
fmt.Fprintln(os.Stderr, "\thelp outputs this usage text") fmt.Fprintln(os.Stderr, "\tcommand COMMAND [VAL...] issue commands to rover, accepts multiple, see below")
fmt.Fprintln(os.Stderr, "\tconfig [HOST] outputs the local config, optionally sets host") fmt.Fprintln(os.Stderr, "\tradar gathers radar data for the current rover")
fmt.Fprintln(os.Stderr, "\tserver-status prints the server status") fmt.Fprintln(os.Stderr, "\tstatus gets status info for current rover")
fmt.Fprintln(os.Stderr, "\tregister NAME registers an account and spawns a rover") fmt.Fprintln(os.Stderr, "\tconfig [HOST] outputs the local config info, optionally sets host")
fmt.Fprintln(os.Stderr, "\tradar prints radar data in ASCII form") fmt.Fprintln(os.Stderr, "\thelp outputs this usage information")
fmt.Fprintln(os.Stderr, "\tstatus gets rover status") fmt.Fprintln(os.Stderr, "\tversion outputs version info")
fmt.Fprintln(os.Stderr, "\tcommand CMD [VAL...] [REPEAT] sets the command queue, accepts multiple in sequence") fmt.Fprintln(os.Stderr, "\nRover commands:")
fmt.Fprintf(os.Stderr, "\n") fmt.Fprintln(os.Stderr, "\ttoggle toggles the sails, either catching the wind, or charging from the sun")
fmt.Fprintln(os.Stderr, "Rover commands:") fmt.Fprintln(os.Stderr, "\tstash stores the object at the rover location in the inventory")
fmt.Fprintln(os.Stderr, "\ttoggle toggles the current sail mode") fmt.Fprintln(os.Stderr, "\trepair uses an inventory object to repair the rover")
fmt.Fprintln(os.Stderr, "\tstash stores the object at the rover location in the inventory") fmt.Fprintln(os.Stderr, "\tbroadcast MSG broadcast a simple ASCII triplet to nearby rovers")
fmt.Fprintln(os.Stderr, "\trepair repairs the rover using inventory item") fmt.Fprintln(os.Stderr, "\tsalvage salvages a dormant rover for parts")
fmt.Fprintln(os.Stderr, "\tbroadcast MSG broadcast a simple ASCII triplet to nearby rovers") fmt.Fprintln(os.Stderr, "\nEnvironment")
fmt.Fprintln(os.Stderr, "\tsalvage salvages a dormant rover for parts") fmt.Fprintln(os.Stderr, "\tROVE_USER_DATA path to user data, defaults to "+defaultDataPath)
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)
} }
const gRPCport = 9090 const gRPCport = 9090
@ -188,15 +179,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]) 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 // 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 { if err != nil {
return err return err
} }
@ -248,8 +232,6 @@ func InnerMain(command string, args ...string) error {
// Iterate through each command // Iterate through each command
var commands []*roveapi.Command var commands []*roveapi.Command
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
var cmd *roveapi.Command
switch args[i] { switch args[i] {
case "turn": case "turn":
i++ i++
@ -260,10 +242,12 @@ func InnerMain(command string, args ...string) error {
if b == roveapi.Bearing_BearingUnknown { if b == roveapi.Bearing_BearingUnknown {
return fmt.Errorf("turn command must be given a valid bearing %s", args[i]) return fmt.Errorf("turn command must be given a valid bearing %s", args[i])
} }
cmd = &roveapi.Command{ commands = append(commands,
Command: roveapi.CommandType_turn, &roveapi.Command{
Bearing: b, Command: roveapi.CommandType_turn,
} Bearing: b,
},
)
case "broadcast": case "broadcast":
i++ i++
if len(args) == i { if len(args) == i {
@ -271,51 +255,20 @@ func InnerMain(command string, args ...string) error {
} else if len(args[i]) > 3 { } else if len(args[i]) > 3 {
return fmt.Errorf("broadcast command must be given ASCII triplet of 3 or less: %s", args[i]) return fmt.Errorf("broadcast command must be given ASCII triplet of 3 or less: %s", args[i])
} }
cmd = &roveapi.Command{ commands = append(commands,
Command: roveapi.CommandType_broadcast, &roveapi.Command{
Data: []byte(args[i]), 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,
}
default: default:
// By default just use the command literally // By default just use the command literally
cmd = &roveapi.Command{ commands = append(commands,
Command: roveapi.CommandType(roveapi.CommandType_value[args[i]]), &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{ _, err := client.Command(ctx, &roveapi.CommandRequest{
@ -403,15 +356,6 @@ func InnerMain(command string, args ...string) error {
func main() { func main() {
// Bail without any args // Bail without any args
if len(os.Args) == 1 { 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() printUsage()
os.Exit(1) os.Exit(1)
} }

View file

@ -13,7 +13,6 @@ import (
) )
func Test_InnerMain(t *testing.T) { func Test_InnerMain(t *testing.T) {
os.Setenv("NO_TLS", "1")
// Use temporary local user data // Use temporary local user data
tmp, err := ioutil.TempDir(os.TempDir(), "rove-") 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", "toggle"))
assert.NoError(t, InnerMain("command", "stash")) assert.NoError(t, InnerMain("command", "stash"))
assert.NoError(t, InnerMain("command", "repair")) 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", "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 // Give it malformed commands
assert.Error(t, InnerMain("command", "unknown")) assert.Error(t, InnerMain("command", "unknown"))
assert.Error(t, InnerMain("command", "broadcast")) assert.Error(t, InnerMain("command", "broadcast"))
assert.Error(t, InnerMain("command", "upgrade"))
assert.Error(t, InnerMain("command", "1"))
} }

View file

@ -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

View file

@ -16,10 +16,21 @@ services:
- DATA_PATH=/mnt/rove-server - DATA_PATH=/mnt/rove-server
- WORDS_FILE=data/words_alpha.txt - WORDS_FILE=data/words_alpha.txt
- TICK_RATE=3 - TICK_RATE=3
- CERT_NAME=${CERT_NAME}
volumes: volumes:
- persistent-data:/mnt/rove-server:rw - persistent-data:/mnt/rove-server:rw
- /etc/letsencrypt/:/etc/letsencrypt/
command: [ "./rove-server"] 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

View file

@ -9,15 +9,6 @@ import (
"github.com/stretchr/testify/assert" "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) { func TestCommand_Toggle(t *testing.T) {
w := NewWorld(8) w := NewWorld(8)
a, err := w.SpawnRover("") a, err := w.SpawnRover("")
@ -220,86 +211,11 @@ func TestCommand_Transfer(t *testing.T) {
} }
func TestCommand_Wait(t *testing.T) { func TestCommand_Invalid(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) w := NewWorld(8)
name, err := w.SpawnRover("") name, err := w.SpawnRover("")
assert.NoError(t, err) 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_none})
err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_upgrade})
assert.Error(t, err) 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)
} }

View file

@ -74,7 +74,7 @@ type Rover struct {
// DefaultRover returns a default rover object with default settings // DefaultRover returns a default rover object with default settings
func DefaultRover() *Rover { func DefaultRover() *Rover {
return &Rover{ return &Rover{
Range: 10, Range: 4,
Integrity: 10, Integrity: 10,
MaximumIntegrity: 10, MaximumIntegrity: 10,
Capacity: 10, Capacity: 10,

View file

@ -15,9 +15,6 @@ import (
const ( const (
// ticksPerNormalMove defines the number of ticks it should take for a "normal" speed move // ticksPerNormalMove defines the number of ticks it should take for a "normal" speed move
ticksPerNormalMove = 4 ticksPerNormalMove = 4
// upgradeCost is the cost in rover parts needed to upgrade a rover specification
upgradeCost = 5
) )
// CommandStream is a list of commands to execute in order // CommandStream is a list of commands to execute in order
@ -449,65 +446,6 @@ func (w *World) RoverToggle(rover string) (roveapi.SailPosition, error) {
return r.SailPosition, nil 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 // RoverTurn will turn the rover
func (w *World) RoverTurn(rover string, bearing roveapi.Bearing) (roveapi.Bearing, error) { func (w *World) RoverTurn(rover string, bearing roveapi.Bearing) (roveapi.Bearing, error) {
w.worldMutex.Lock() w.worldMutex.Lock()
@ -644,11 +582,6 @@ func (w *World) Enqueue(rover string, commands ...*roveapi.Command) error {
if c.GetBearing() == roveapi.Bearing_BearingUnknown { if c.GetBearing() == roveapi.Bearing_BearingUnknown {
return fmt.Errorf("turn command given unknown bearing") 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_toggle:
case roveapi.CommandType_stash: case roveapi.CommandType_stash:
case roveapi.CommandType_repair: case roveapi.CommandType_repair:
@ -679,16 +612,15 @@ func (w *World) Tick() {
if len(cmds) != 0 { if len(cmds) != 0 {
// Execute the command // 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) log.Println(err)
// TODO: Report this error somehow // TODO: Report this error somehow
}
} else if done { // Extract the first command in the queue
// Extract the first command in the queue // Only if the command queue still has entries
// Only if the command queue still has entries (the command may have modified this queue) if _, ok := w.CommandQueue[rover]; ok {
if _, ok := w.CommandQueue[rover]; ok { w.CommandQueue[rover] = cmds[1:]
w.CommandQueue[rover] = cmds[1:]
}
} }
} else { } else {
@ -777,35 +709,49 @@ func (w *World) Tick() {
} }
// ExecuteCommand will execute a single command // 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) log.Printf("Executing command: %+v for %s\n", c.Command, rover)
switch c.Command { switch c.Command {
case roveapi.CommandType_toggle: case roveapi.CommandType_toggle:
_, err = w.RoverToggle(rover) if _, err := w.RoverToggle(rover); err != nil {
return err
}
case roveapi.CommandType_stash: case roveapi.CommandType_stash:
_, err = w.RoverStash(rover) if _, err := w.RoverStash(rover); err != nil {
return err
}
case roveapi.CommandType_repair: case roveapi.CommandType_repair:
_, err = w.RoverRepair(rover) if _, err := w.RoverRepair(rover); err != nil {
return err
}
case roveapi.CommandType_broadcast: case roveapi.CommandType_broadcast:
err = w.RoverBroadcast(rover, c.GetData()) if err := w.RoverBroadcast(rover, c.GetData()); err != nil {
return err
}
case roveapi.CommandType_turn: case roveapi.CommandType_turn:
_, err = w.RoverTurn(rover, c.GetBearing()) if _, err := w.RoverTurn(rover, c.GetBearing()); err != nil {
return err
}
case roveapi.CommandType_salvage: case roveapi.CommandType_salvage:
_, err = w.RoverSalvage(rover) if _, err := w.RoverSalvage(rover); err != nil {
return err
}
case roveapi.CommandType_transfer: case roveapi.CommandType_transfer:
_, err = w.RoverTransfer(rover) if _, err := w.RoverTransfer(rover); err != nil {
case roveapi.CommandType_upgrade: return err
_, err = w.RoverUpgrade(rover, c.GetUpgrade()) }
case roveapi.CommandType_wait:
// Nothing to do
default: default:
return true, fmt.Errorf("unknown command: %s", c.Command) return fmt.Errorf("unknown command: %s", c.Command)
} }
// Decrement the repeat number return
c.Repeat--
return c.Repeat < 0, err
} }
// Daytime returns if it's currently daytime // Daytime returns if it's currently daytime

View file

@ -109,16 +109,15 @@ func TestWorld_RadarFromRover(t *testing.T) {
world.Atlas.SetObject(maths.Vector{X: 0, Y: 0}, Object{Type: roveapi.Object_ObjectUnknown}) 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") 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) radar, objs, err := world.RadarFromRover(a)
assert.NoError(t, err, "Failed to get radar from rover") 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(radar), "Radar returned wrong length")
assert.Equal(t, fullRange*fullRange, len(objs), "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 // Check the radar results are stable
radar1, objs1, err := world.RadarFromRover(a) radar1, objs1, err := world.RadarFromRover(a)

View file

@ -1,6 +1,10 @@
package rove package rove
import ( import (
"encoding/json"
"log"
"math/rand"
"github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/proto/roveapi" "github.com/mdiluz/rove/proto/roveapi"
"github.com/ojrac/opensimplex-go" "github.com/ojrac/opensimplex-go"
@ -31,7 +35,6 @@ func NewNoiseWorldGen(seed int64) WorldGen {
const ( const (
terrainNoiseScale = 15 terrainNoiseScale = 15
rockNoiseScale = 3 rockNoiseScale = 3
partsNoiseScale = 2
) )
// GetTile returns the chosen tile at a location // GetTile returns the chosen tile at a location
@ -49,22 +52,49 @@ func (g *NoiseWorldGen) GetTile(v maths.Vector) roveapi.Tile {
// GetObject returns the chosen object at a location // GetObject returns the chosen object at a location
func (g *NoiseWorldGen) GetObject(v maths.Vector) (obj Object) { 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 { switch {
// Prioritise rocks case o > 0.6:
case r > 0.6:
obj.Type = roveapi.Object_RockLarge obj.Type = roveapi.Object_RockLarge
case r > 0.5: case o > 0.5:
obj.Type = roveapi.Object_RockSmall obj.Type = roveapi.Object_RockSmall
}
default: // Very rarely spawn a dormant rover
// Otherwise, try some rover parts if obj.Type == roveapi.Object_ObjectUnknown {
p := g.noise.Eval2(float64(v.X)/partsNoiseScale, float64(v.Y)/partsNoiseScale) // TODO: Make this better, ideally with noise
switch { if v.X%25 == 0 && v.Y%25 == 0 && v.X != 0 && v.Y != 0 {
case p > 0.7: obj.Type = roveapi.Object_RoverDormant
obj.Type = roveapi.Object_RoverParts
} }
} }
// Post process any spawned objects
switch obj.Type {
case roveapi.Object_RoverDormant:
// Create the rover
r := DefaultRover()
// Set the rover variables
r.Pos = v
// Upgrade this rover randomly
r.MaximumCharge += rand.Int() % 3
r.MaximumIntegrity += rand.Int() % 3
r.Capacity += rand.Int() % 3
r.Range += rand.Int() % 3
// 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 return obj
} }

View file

@ -39,51 +39,43 @@ type CommandType int32
const ( const (
CommandType_none CommandType = 0 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 // Toggles the sails, either catching the wind, or charging from the sun
CommandType_toggle CommandType = 2 CommandType_toggle CommandType = 1
// Turns the rover in the specified bearing (requires bearing) // Turns the rover in the specified bearing (requires bearing)
CommandType_turn CommandType = 3 CommandType_turn CommandType = 2
// Stashes item at current location in rover inventory // Stashes item at current location in rover inventory
CommandType_stash CommandType = 4 CommandType_stash CommandType = 3
// Repairs the rover using an inventory object // Repairs the rover using an inventory object
CommandType_repair CommandType = 5 CommandType_repair CommandType = 4
// Broadcasts a message to nearby rovers (requires data) // Broadcasts a message to nearby rovers (requires data)
CommandType_broadcast CommandType = 6 CommandType_broadcast CommandType = 5
// Salvages a neighboring dormant rover for parts // Salvages a neighboring dormant rover for parts
CommandType_salvage CommandType = 7 CommandType_salvage CommandType = 6
// Transfers remote control into dormant rover // Transfers remote control into dormant rover
CommandType_transfer CommandType = 8 CommandType_transfer CommandType = 7
// Upgrades a chosen rover specification using 5 rover parts
CommandType_upgrade CommandType = 9
) )
// Enum value maps for CommandType. // Enum value maps for CommandType.
var ( var (
CommandType_name = map[int32]string{ CommandType_name = map[int32]string{
0: "none", 0: "none",
1: "wait", 1: "toggle",
2: "toggle", 2: "turn",
3: "turn", 3: "stash",
4: "stash", 4: "repair",
5: "repair", 5: "broadcast",
6: "broadcast", 6: "salvage",
7: "salvage", 7: "transfer",
8: "transfer",
9: "upgrade",
} }
CommandType_value = map[string]int32{ CommandType_value = map[string]int32{
"none": 0, "none": 0,
"wait": 1, "toggle": 1,
"toggle": 2, "turn": 2,
"turn": 3, "stash": 3,
"stash": 4, "repair": 4,
"repair": 5, "broadcast": 5,
"broadcast": 6, "salvage": 6,
"salvage": 7, "transfer": 7,
"transfer": 8,
"upgrade": 9,
} }
) )
@ -183,62 +175,6 @@ func (Bearing) EnumDescriptor() ([]byte, []int) {
return file_roveapi_roveapi_proto_rawDescGZIP(), []int{1} 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 // Types of objects
type Object int32 type Object int32
@ -253,8 +189,7 @@ const (
Object_RockSmall Object = 3 Object_RockSmall Object = 3
// RockLarge is a large blocking rock // RockLarge is a large blocking rock
Object_RockLarge Object = 4 Object_RockLarge Object = 4
// RoverParts is one unit of rover parts, used for repairing and fixing the // RoverParts is one unit of rover parts, used for repairing and fixing the rover
// rover
Object_RoverParts Object = 5 Object_RoverParts Object = 5
) )
@ -289,11 +224,11 @@ func (x Object) String() string {
} }
func (Object) Descriptor() protoreflect.EnumDescriptor { 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 { 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 { func (x Object) Number() protoreflect.EnumNumber {
@ -302,7 +237,7 @@ func (x Object) Number() protoreflect.EnumNumber {
// Deprecated: Use Object.Descriptor instead. // Deprecated: Use Object.Descriptor instead.
func (Object) EnumDescriptor() ([]byte, []int) { func (Object) EnumDescriptor() ([]byte, []int) {
return file_roveapi_roveapi_proto_rawDescGZIP(), []int{3} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{2}
} }
type Tile int32 type Tile int32
@ -345,11 +280,11 @@ func (x Tile) String() string {
} }
func (Tile) Descriptor() protoreflect.EnumDescriptor { 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 { 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 { func (x Tile) Number() protoreflect.EnumNumber {
@ -358,7 +293,7 @@ func (x Tile) Number() protoreflect.EnumNumber {
// Deprecated: Use Tile.Descriptor instead. // Deprecated: Use Tile.Descriptor instead.
func (Tile) EnumDescriptor() ([]byte, []int) { 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 // SailPosition represents the position of the sola sail
@ -397,11 +332,11 @@ func (x SailPosition) String() string {
} }
func (SailPosition) Descriptor() protoreflect.EnumDescriptor { 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 { 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 { func (x SailPosition) Number() protoreflect.EnumNumber {
@ -410,7 +345,7 @@ func (x SailPosition) Number() protoreflect.EnumNumber {
// Deprecated: Use SailPosition.Descriptor instead. // Deprecated: Use SailPosition.Descriptor instead.
func (SailPosition) EnumDescriptor() ([]byte, []int) { 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 // ServerStatusRequest is an empty placeholder
@ -701,15 +636,10 @@ type Command struct {
// The command type // The command type
Command CommandType `protobuf:"varint,1,opt,name=command,proto3,enum=roveapi.CommandType" json:"command,omitempty"` 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 // broadcast - a simple message, must be composed of up to 3 printable ASCII glyphs (32-126)
Repeat int32 `protobuf:"varint,2,opt,name=repeat,proto3" json:"repeat,omitempty"` Data []byte `protobuf:"bytes,2,opt,name=data,proto3" json:"data,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 // move - the bearing for the rover to turn to
Bearing Bearing `protobuf:"varint,4,opt,name=bearing,proto3,enum=roveapi.Bearing" json:"bearing,omitempty"` Bearing Bearing `protobuf:"varint,3,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"`
} }
func (x *Command) Reset() { func (x *Command) Reset() {
@ -751,13 +681,6 @@ func (x *Command) GetCommand() CommandType {
return CommandType_none return CommandType_none
} }
func (x *Command) GetRepeat() int32 {
if x != nil {
return x.Repeat
}
return 0
}
func (x *Command) GetData() []byte { func (x *Command) GetData() []byte {
if x != nil { if x != nil {
return x.Data return x.Data
@ -772,13 +695,6 @@ func (x *Command) GetBearing() Bearing {
return Bearing_BearingUnknown 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 // CommandRequest describes a set of commands to be requested for the rover
type CommandRequest struct { type CommandRequest struct {
state protoimpl.MessageState state protoimpl.MessageState
@ -1492,157 +1408,144 @@ var file_roveapi_roveapi_proto_rawDesc = []byte{
0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, 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, 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, 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, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x79, 0x0a, 0x07, 0x43, 0x6f, 0x6d,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18,
0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e,
0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6d,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x16, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x18, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x02, 0x20, 0x01,
0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x72, 0x65, 0x70, 0x65, 0x61, 0x74, 0x12, 0x12, 0x0a, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72,
0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x69, 0x6e, 0x67, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65,
0x61, 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x04, 0x20, 0x01, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61,
0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x22, 0x6a, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52,
0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x2f, 0x0a, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x07, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70,
0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x67, 0x72, 0x61, 0x64, 0x65, 0x52, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x22, 0x6a, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02,
0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43,
0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75,
0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01,
0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41,
0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6f, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x75, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18,
0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e,
0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x75, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x54, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x07, 0x6f,
0x61, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x72,
0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x6f,
0x12, 0x23, 0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x54, 0x69, 0x6c, 0x65, 0x52, 0x05, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x74, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x29, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61,
0x18, 0x03, 0x20, 0x03, 0x28, 0x0e, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f,
0x2e, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69,
0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12,
0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65,
0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0c, 0x0a, 0x01,
0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18,
0x03, 0x4c, 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0xad, 0x01, 0x0a, 0x13, 0x52, 0x6f, 0x76,
0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04,
0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20,
0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61,
0x01, 0x79, 0x22, 0xad, 0x01, 0x0a, 0x13, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x61,
0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75,
0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x14, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69,
0x61, 0x6e, 0x67, 0x65, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x74, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61,
0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x72, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d,
0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x22, 0x82, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x76,
0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72,
0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x24, 0x0a, 0x0d, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65,
0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, 0x05, 0x20, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61,
0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x39, 0x0a, 0x0c, 0x73, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69,
0x67, 0x65, 0x22, 0x82, 0x02, 0x0a, 0x0b, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x72, 0x6f, 0x76,
0x75, 0x73, 0x12, 0x2a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, 0x01, 0x20, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f,
0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x6e, 0x52, 0x0c, 0x73, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12,
0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x39, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01,
0x0a, 0x0c, 0x73, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05,
0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0c, 0x73, 0x61, 0x69, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63,
0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61,
0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x72, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d,
0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f,
0x72, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71,
0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x84, 0x01,
0x05, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x38, 0x0a, 0x0a, 0x0d, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12,
0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x2b, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x06, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x63, 0x74,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x04,
0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x84, 0x01, 0x0a, 0x0d, 0x52, 0x6f, 0x76, 0x65, 0x77, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76,
0x72, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x04, 0x77, 0x69,
0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b,
0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04,
0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x24, 0x0a, 0x04, 0x77, 0x69, 0x6e, 0x64, 0x18, 0x02, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xa4, 0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x20, 0x01, 0x28, 0x0e, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x42, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18,
0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x52, 0x04, 0x77, 0x69, 0x6e, 0x64, 0x12, 0x20, 0x0a, 0x04, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e,
0x6c, 0x6f, 0x67, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
0x65, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x22, 0xa4, 0x6f, 0x6e, 0x73, 0x52, 0x04, 0x73, 0x70, 0x65, 0x63, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61,
0x01, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65,
0x65, 0x12, 0x30, 0x0a, 0x04, 0x73, 0x70, 0x65, 0x63, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52,
0x1c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x53, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x69,
0x70, 0x65, 0x63, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x04, 0x73, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65,
0x70, 0x65, 0x63, 0x12, 0x2c, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x02, 0x20, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67,
0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x73, 0x52, 0x08, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x2a, 0x6e, 0x0a, 0x0b, 0x43,
0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f,
0x73, 0x12, 0x32, 0x0a, 0x08, 0x72, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x03, 0x20, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x6f, 0x67, 0x67, 0x6c, 0x65, 0x10, 0x01,
0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x6f, 0x12, 0x08, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x10, 0x02, 0x12, 0x09, 0x0a, 0x05, 0x73, 0x74,
0x76, 0x65, 0x72, 0x52, 0x65, 0x61, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x52, 0x08, 0x72, 0x65, 0x61, 0x61, 0x73, 0x68, 0x10, 0x03, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x10,
0x64, 0x69, 0x6e, 0x67, 0x73, 0x2a, 0x85, 0x01, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x10, 0x05,
0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x12, 0x0b, 0x0a, 0x07, 0x73, 0x61, 0x6c, 0x76, 0x61, 0x67, 0x65, 0x10, 0x06, 0x12, 0x0c, 0x0a,
0x08, 0x0a, 0x04, 0x77, 0x61, 0x69, 0x74, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x06, 0x74, 0x6f, 0x67, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x10, 0x07, 0x2a, 0x83, 0x01, 0x0a, 0x07,
0x67, 0x6c, 0x65, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x74, 0x75, 0x72, 0x6e, 0x10, 0x03, 0x12, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x65, 0x61, 0x72, 0x69,
0x09, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x73, 0x68, 0x10, 0x04, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x65, 0x6e, 0x67, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x4e,
0x70, 0x61, 0x69, 0x72, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x6f, 0x72, 0x74, 0x68, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x45,
0x61, 0x73, 0x74, 0x10, 0x06, 0x12, 0x0b, 0x0a, 0x07, 0x73, 0x61, 0x6c, 0x76, 0x61, 0x67, 0x65, 0x61, 0x73, 0x74, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x73, 0x74, 0x10, 0x03, 0x12,
0x10, 0x07, 0x12, 0x0c, 0x0a, 0x08, 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 0x10, 0x08, 0x0d, 0x0a, 0x09, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x04, 0x12, 0x09,
0x12, 0x0b, 0x0a, 0x07, 0x75, 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x10, 0x09, 0x2a, 0x83, 0x01, 0x0a, 0x05, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x6f, 0x75,
0x0a, 0x07, 0x42, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x12, 0x12, 0x0a, 0x0e, 0x42, 0x65, 0x61, 0x74, 0x68, 0x57, 0x65, 0x73, 0x74, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x65, 0x73, 0x74,
0x72, 0x69, 0x6e, 0x67, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x57, 0x65, 0x73, 0x74, 0x10,
0x05, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x10, 0x01, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x08, 0x2a, 0x6a, 0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x4f,
0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x45, 0x61, 0x73, 0x74, 0x10, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0d,
0x03, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x45, 0x61, 0x73, 0x74, 0x10, 0x04, 0x0a, 0x09, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x4c, 0x69, 0x76, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a,
0x12, 0x09, 0x0a, 0x05, 0x53, 0x6f, 0x75, 0x74, 0x68, 0x10, 0x05, 0x12, 0x0d, 0x0a, 0x09, 0x53, 0x0c, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x10, 0x02, 0x12,
0x6f, 0x75, 0x74, 0x68, 0x57, 0x65, 0x73, 0x74, 0x10, 0x06, 0x12, 0x08, 0x0a, 0x04, 0x57, 0x65, 0x0d, 0x0a, 0x09, 0x52, 0x6f, 0x63, 0x6b, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x10, 0x03, 0x12, 0x0d,
0x73, 0x74, 0x10, 0x07, 0x12, 0x0d, 0x0a, 0x09, 0x4e, 0x6f, 0x72, 0x74, 0x68, 0x57, 0x65, 0x73, 0x0a, 0x09, 0x52, 0x6f, 0x63, 0x6b, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, 0x0e, 0x0a,
0x74, 0x10, 0x08, 0x2a, 0x69, 0x0a, 0x0c, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x70, 0x67, 0x72, 0x0a, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, 0x10, 0x05, 0x2a, 0x37, 0x0a,
0x61, 0x64, 0x65, 0x12, 0x17, 0x0a, 0x13, 0x52, 0x6f, 0x76, 0x65, 0x72, 0x55, 0x70, 0x67, 0x72, 0x04, 0x54, 0x69, 0x6c, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x69, 0x6c, 0x65, 0x55, 0x6e, 0x6b,
0x61, 0x64, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x09, 0x0a, 0x05, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x6f, 0x63, 0x6b, 0x10, 0x01,
0x52, 0x61, 0x6e, 0x67, 0x65, 0x10, 0x01, 0x12, 0x0c, 0x0a, 0x08, 0x43, 0x61, 0x70, 0x61, 0x63, 0x12, 0x0a, 0x0a, 0x06, 0x47, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04,
0x69, 0x74, 0x79, 0x10, 0x02, 0x12, 0x14, 0x0a, 0x10, 0x4d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x53, 0x61, 0x6e, 0x64, 0x10, 0x03, 0x2a, 0x4c, 0x0a, 0x0c, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f,
0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x10, 0x03, 0x12, 0x11, 0x0a, 0x0d, 0x4d, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77,
0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x2a, 0x6a, 0x6e, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x00, 0x12,
0x0a, 0x06, 0x4f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x12, 0x11, 0x0a, 0x0d, 0x4f, 0x62, 0x6a, 0x65, 0x10, 0x0a, 0x0c, 0x43, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x6e, 0x64, 0x10,
0x63, 0x74, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x10, 0x00, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x01, 0x12, 0x11, 0x0a, 0x0d, 0x53, 0x6f, 0x6c, 0x61, 0x72, 0x43, 0x68, 0x61, 0x72, 0x67, 0x69,
0x6f, 0x76, 0x65, 0x72, 0x4c, 0x69, 0x76, 0x65, 0x10, 0x01, 0x12, 0x10, 0x0a, 0x0c, 0x52, 0x6f, 0x6e, 0x67, 0x10, 0x02, 0x32, 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x4d, 0x0a,
0x76, 0x65, 0x72, 0x44, 0x6f, 0x72, 0x6d, 0x61, 0x6e, 0x74, 0x10, 0x02, 0x12, 0x0d, 0x0a, 0x09, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e,
0x52, 0x6f, 0x63, 0x6b, 0x53, 0x6d, 0x61, 0x6c, 0x6c, 0x10, 0x03, 0x12, 0x0d, 0x0a, 0x09, 0x52, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74,
0x6f, 0x63, 0x6b, 0x4c, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, 0x0e, 0x0a, 0x0a, 0x52, 0x6f, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x6f,
0x76, 0x65, 0x72, 0x50, 0x61, 0x72, 0x74, 0x73, 0x10, 0x05, 0x2a, 0x37, 0x0a, 0x04, 0x54, 0x69, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74,
0x6c, 0x65, 0x12, 0x0f, 0x0a, 0x0b, 0x54, 0x69, 0x6c, 0x65, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08,
0x6e, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x52, 0x6f, 0x63, 0x6b, 0x10, 0x01, 0x12, 0x0a, 0x0a, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61,
0x06, 0x47, 0x72, 0x61, 0x76, 0x65, 0x6c, 0x10, 0x02, 0x12, 0x08, 0x0a, 0x04, 0x53, 0x61, 0x6e, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65,
0x64, 0x10, 0x03, 0x2a, 0x4c, 0x0a, 0x0c, 0x53, 0x61, 0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67,
0x69, 0x6f, 0x6e, 0x12, 0x17, 0x0a, 0x13, 0x55, 0x6e, 0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x53, 0x61, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x69, 0x6c, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x10, 0x00, 0x12, 0x10, 0x0a, 0x0c, 0x3e, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x72, 0x6f, 0x76,
0x43, 0x61, 0x74, 0x63, 0x68, 0x69, 0x6e, 0x67, 0x57, 0x69, 0x6e, 0x64, 0x10, 0x01, 0x12, 0x11, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75,
0x0a, 0x0d, 0x53, 0x6f, 0x6c, 0x61, 0x72, 0x43, 0x68, 0x61, 0x72, 0x67, 0x69, 0x6e, 0x67, 0x10, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f,
0x02, 0x32, 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x4d, 0x0a, 0x0c, 0x53, 0x65, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12,
0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, 0x2e, 0x72, 0x6f, 0x76, 0x38, 0x0a, 0x05, 0x52, 0x61, 0x64, 0x61, 0x72, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61,
0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a,
0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52,
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, 0x3b, 0x0a, 0x06, 0x53, 0x74, 0x61,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74,
0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x6f,
0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70,
0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x26, 0x5a, 0x24, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62,
0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3e, 0x0a, 0x07, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x64, 0x69, 0x6c, 0x75, 0x7a, 0x2f, 0x72, 0x6f, 0x76, 0x65,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x62, 0x06,
0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
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 ( var (
@ -1657,68 +1560,66 @@ func file_roveapi_roveapi_proto_rawDescGZIP() []byte {
return file_roveapi_roveapi_proto_rawDescData return file_roveapi_roveapi_proto_rawDescData
} }
var file_roveapi_roveapi_proto_enumTypes = make([]protoimpl.EnumInfo, 6) var file_roveapi_roveapi_proto_enumTypes = make([]protoimpl.EnumInfo, 5)
var file_roveapi_roveapi_proto_msgTypes = make([]protoimpl.MessageInfo, 17) var file_roveapi_roveapi_proto_msgTypes = make([]protoimpl.MessageInfo, 17)
var file_roveapi_roveapi_proto_goTypes = []interface{}{ var file_roveapi_roveapi_proto_goTypes = []interface{}{
(CommandType)(0), // 0: roveapi.CommandType (CommandType)(0), // 0: roveapi.CommandType
(Bearing)(0), // 1: roveapi.Bearing (Bearing)(0), // 1: roveapi.Bearing
(RoverUpgrade)(0), // 2: roveapi.RoverUpgrade (Object)(0), // 2: roveapi.Object
(Object)(0), // 3: roveapi.Object (Tile)(0), // 3: roveapi.Tile
(Tile)(0), // 4: roveapi.Tile (SailPosition)(0), // 4: roveapi.SailPosition
(SailPosition)(0), // 5: roveapi.SailPosition (*ServerStatusRequest)(nil), // 5: roveapi.ServerStatusRequest
(*ServerStatusRequest)(nil), // 6: roveapi.ServerStatusRequest (*ServerStatusResponse)(nil), // 6: roveapi.ServerStatusResponse
(*ServerStatusResponse)(nil), // 7: roveapi.ServerStatusResponse (*RegisterRequest)(nil), // 7: roveapi.RegisterRequest
(*RegisterRequest)(nil), // 8: roveapi.RegisterRequest (*Account)(nil), // 8: roveapi.Account
(*Account)(nil), // 9: roveapi.Account (*RegisterResponse)(nil), // 9: roveapi.RegisterResponse
(*RegisterResponse)(nil), // 10: roveapi.RegisterResponse (*Command)(nil), // 10: roveapi.Command
(*Command)(nil), // 11: roveapi.Command (*CommandRequest)(nil), // 11: roveapi.CommandRequest
(*CommandRequest)(nil), // 12: roveapi.CommandRequest (*CommandResponse)(nil), // 12: roveapi.CommandResponse
(*CommandResponse)(nil), // 13: roveapi.CommandResponse (*RadarRequest)(nil), // 13: roveapi.RadarRequest
(*RadarRequest)(nil), // 14: roveapi.RadarRequest (*RadarResponse)(nil), // 14: roveapi.RadarResponse
(*RadarResponse)(nil), // 15: roveapi.RadarResponse (*StatusRequest)(nil), // 15: roveapi.StatusRequest
(*StatusRequest)(nil), // 16: roveapi.StatusRequest (*Log)(nil), // 16: roveapi.Log
(*Log)(nil), // 17: roveapi.Log (*Vector)(nil), // 17: roveapi.Vector
(*Vector)(nil), // 18: roveapi.Vector (*RoverSpecifications)(nil), // 18: roveapi.RoverSpecifications
(*RoverSpecifications)(nil), // 19: roveapi.RoverSpecifications (*RoverStatus)(nil), // 19: roveapi.RoverStatus
(*RoverStatus)(nil), // 20: roveapi.RoverStatus (*RoverReadings)(nil), // 20: roveapi.RoverReadings
(*RoverReadings)(nil), // 21: roveapi.RoverReadings (*StatusResponse)(nil), // 21: roveapi.StatusResponse
(*StatusResponse)(nil), // 22: roveapi.StatusResponse
} }
var file_roveapi_roveapi_proto_depIdxs = []int32{ 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 0, // 1: roveapi.Command.command:type_name -> roveapi.CommandType
1, // 2: roveapi.Command.bearing:type_name -> roveapi.Bearing 1, // 2: roveapi.Command.bearing:type_name -> roveapi.Bearing
2, // 3: roveapi.Command.upgrade:type_name -> roveapi.RoverUpgrade 8, // 3: roveapi.CommandRequest.account:type_name -> roveapi.Account
9, // 4: roveapi.CommandRequest.account:type_name -> roveapi.Account 10, // 4: roveapi.CommandRequest.commands:type_name -> roveapi.Command
11, // 5: roveapi.CommandRequest.commands:type_name -> roveapi.Command 8, // 5: roveapi.RadarRequest.account:type_name -> roveapi.Account
9, // 6: roveapi.RadarRequest.account:type_name -> roveapi.Account 3, // 6: roveapi.RadarResponse.tiles:type_name -> roveapi.Tile
4, // 7: roveapi.RadarResponse.tiles:type_name -> roveapi.Tile 2, // 7: roveapi.RadarResponse.objects:type_name -> roveapi.Object
3, // 8: roveapi.RadarResponse.objects:type_name -> roveapi.Object 8, // 8: roveapi.StatusRequest.account:type_name -> roveapi.Account
9, // 9: roveapi.StatusRequest.account:type_name -> roveapi.Account 1, // 9: roveapi.RoverStatus.bearing:type_name -> roveapi.Bearing
1, // 10: roveapi.RoverStatus.bearing:type_name -> roveapi.Bearing 4, // 10: roveapi.RoverStatus.sailPosition:type_name -> roveapi.SailPosition
5, // 11: roveapi.RoverStatus.sailPosition:type_name -> roveapi.SailPosition 10, // 11: roveapi.RoverStatus.queuedCommands:type_name -> roveapi.Command
11, // 12: roveapi.RoverStatus.queuedCommands:type_name -> roveapi.Command 17, // 12: roveapi.RoverReadings.position:type_name -> roveapi.Vector
18, // 13: roveapi.RoverReadings.position:type_name -> roveapi.Vector 1, // 13: roveapi.RoverReadings.wind:type_name -> roveapi.Bearing
1, // 14: roveapi.RoverReadings.wind:type_name -> roveapi.Bearing 16, // 14: roveapi.RoverReadings.logs:type_name -> roveapi.Log
17, // 15: roveapi.RoverReadings.logs:type_name -> roveapi.Log 18, // 15: roveapi.StatusResponse.spec:type_name -> roveapi.RoverSpecifications
19, // 16: roveapi.StatusResponse.spec:type_name -> roveapi.RoverSpecifications 19, // 16: roveapi.StatusResponse.status:type_name -> roveapi.RoverStatus
20, // 17: roveapi.StatusResponse.status:type_name -> roveapi.RoverStatus 20, // 17: roveapi.StatusResponse.readings:type_name -> roveapi.RoverReadings
21, // 18: roveapi.StatusResponse.readings:type_name -> roveapi.RoverReadings 5, // 18: roveapi.Rove.ServerStatus:input_type -> roveapi.ServerStatusRequest
6, // 19: roveapi.Rove.ServerStatus:input_type -> roveapi.ServerStatusRequest 7, // 19: roveapi.Rove.Register:input_type -> roveapi.RegisterRequest
8, // 20: roveapi.Rove.Register:input_type -> roveapi.RegisterRequest 11, // 20: roveapi.Rove.Command:input_type -> roveapi.CommandRequest
12, // 21: roveapi.Rove.Command:input_type -> roveapi.CommandRequest 13, // 21: roveapi.Rove.Radar:input_type -> roveapi.RadarRequest
14, // 22: roveapi.Rove.Radar:input_type -> roveapi.RadarRequest 15, // 22: roveapi.Rove.Status:input_type -> roveapi.StatusRequest
16, // 23: roveapi.Rove.Status:input_type -> roveapi.StatusRequest 6, // 23: roveapi.Rove.ServerStatus:output_type -> roveapi.ServerStatusResponse
7, // 24: roveapi.Rove.ServerStatus:output_type -> roveapi.ServerStatusResponse 9, // 24: roveapi.Rove.Register:output_type -> roveapi.RegisterResponse
10, // 25: roveapi.Rove.Register:output_type -> roveapi.RegisterResponse 12, // 25: roveapi.Rove.Command:output_type -> roveapi.CommandResponse
13, // 26: roveapi.Rove.Command:output_type -> roveapi.CommandResponse 14, // 26: roveapi.Rove.Radar:output_type -> roveapi.RadarResponse
15, // 27: roveapi.Rove.Radar:output_type -> roveapi.RadarResponse 21, // 27: roveapi.Rove.Status:output_type -> roveapi.StatusResponse
22, // 28: roveapi.Rove.Status:output_type -> roveapi.StatusResponse 23, // [23:28] is the sub-list for method output_type
24, // [24:29] is the sub-list for method output_type 18, // [18:23] is the sub-list for method input_type
19, // [19:24] is the sub-list for method input_type 18, // [18:18] is the sub-list for extension type_name
19, // [19:19] is the sub-list for extension type_name 18, // [18:18] is the sub-list for extension extendee
19, // [19:19] is the sub-list for extension extendee 0, // [0:18] is the sub-list for field type_name
0, // [0:19] is the sub-list for field type_name
} }
func init() { file_roveapi_roveapi_proto_init() } func init() { file_roveapi_roveapi_proto_init() }
@ -1937,7 +1838,7 @@ func file_roveapi_roveapi_proto_init() {
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_roveapi_roveapi_proto_rawDesc, RawDescriptor: file_roveapi_roveapi_proto_rawDesc,
NumEnums: 6, NumEnums: 5,
NumMessages: 17, NumMessages: 17,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,

View file

@ -89,24 +89,20 @@ message RegisterResponse {
// CommandType defines the type of a command to give to the rover // CommandType defines the type of a command to give to the rover
enum CommandType { enum CommandType {
none = 0; none = 0;
// Waits before performing the next command
wait = 1;
// Toggles the sails, either catching the wind, or charging from the sun // Toggles the sails, either catching the wind, or charging from the sun
toggle = 2; toggle = 1;
// Turns the rover in the specified bearing (requires bearing) // Turns the rover in the specified bearing (requires bearing)
turn = 3; turn = 2;
// Stashes item at current location in rover inventory // Stashes item at current location in rover inventory
stash = 4; stash = 3;
// Repairs the rover using an inventory object // Repairs the rover using an inventory object
repair = 5; repair = 4;
// Broadcasts a message to nearby rovers (requires data) // Broadcasts a message to nearby rovers (requires data)
broadcast = 6; broadcast = 5;
// Salvages a neighboring dormant rover for parts // Salvages a neighboring dormant rover for parts
salvage = 7; salvage = 6;
// Transfers remote control into dormant rover // Transfers remote control into dormant rover
transfer = 8; transfer = 7;
// Upgrades a chosen rover specification using 5 rover parts
upgrade = 9;
} }
// Bearing represents a compass direction // Bearing represents a compass direction
@ -123,32 +119,16 @@ enum Bearing {
NorthWest = 8; 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 // Command is a single command for a rover
message Command { message Command {
// The command type // The command type
CommandType command = 1; CommandType command = 1;
// The number of times to repeat the command after the first // broadcast - a simple message, must be composed of up to 3 printable ASCII glyphs (32-126)
int32 repeat = 2; bytes data = 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 // move - the bearing for the rover to turn to
Bearing bearing = 4; Bearing bearing = 3;
// upgrade - the upgrade to apply to the rover
RoverUpgrade upgrade = 5;
} }
// CommandRequest describes a set of commands to be requested for the rover // CommandRequest describes a set of commands to be requested for the rover
@ -184,8 +164,7 @@ enum Object {
// RockLarge is a large blocking rock // RockLarge is a large blocking rock
RockLarge = 4; RockLarge = 4;
// RoverParts is one unit of rover parts, used for repairing and fixing the // RoverParts is one unit of rover parts, used for repairing and fixing the rover
// rover
RoverParts = 5; RoverParts = 5;
} }