Merge pull request #20 from mdiluz/more-improvements

Various refactors and improvements
This commit is contained in:
Marc Di Luzio 2020-07-10 20:39:40 +01:00 committed by GitHub
commit 3f2ae97048
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
32 changed files with 853 additions and 1750 deletions

View file

@ -3,7 +3,7 @@ VERSION := $(shell git describe --always --long --dirty --tags)
build: build:
@echo Running no-output build @echo Running no-output build
go mod download go mod download
go build -ldflags="-X 'github.com/mdiluz/rove/pkg/version.Version=${VERSION}'" ./... go build -ldflags="-X 'github.com/mdiluz/rove/cmd/version.Version=${VERSION}'" ./...
install: install:
@echo Installing to GOPATH @echo Installing to GOPATH
@ -12,14 +12,10 @@ install:
gen: gen:
@echo Installing go dependencies @echo Installing go dependencies
go install \ go install github.com/golang/protobuf/protoc-gen-go
github.com/grpc-ecosystem/grpc-gateway/protoc-gen-grpc-gateway \
github.com/grpc-ecosystem/grpc-gateway/protoc-gen-swagger \
github.com/golang/protobuf/protoc-gen-go
go mod download go mod download
@echo Generating rove server gRPC and gateway @echo Generating rove server gRPC
protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:pkg/ proto/rove/rove.proto protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:proto/ proto/roveapi/roveapi.proto
protoc --proto_path proto --grpc-gateway_out=paths=source_relative:pkg/ proto/rove/rove.proto
test: test:
@echo Unit tests @echo Unit tests

View file

@ -8,4 +8,4 @@ Rove is an asynchronous nomadic game about exploring as part of a loose communit
This repository is a [living document](https://github.com/mdiluz/rove/tree/master/docs) of current game design, as well as source code for the `rove-server` deployment and the `rove` command line client. This repository is a [living document](https://github.com/mdiluz/rove/tree/master/docs) of current game design, as well as source code for the `rove-server` deployment and the `rove` command line client.
See [rove.proto](https://github.com/mdiluz/rove/blob/master/proto/rove/rove.proto) for the current server-client API. See [roveapi.proto](https://github.com/mdiluz/rove/blob/master/proto/rove/roveapi.proto) for the current server-client API.

View file

@ -0,0 +1,28 @@
package internal
// Accountant decribes something that stores accounts and account values
type Accountant interface {
// RegisterAccount will register a new account and return it's info
RegisterAccount(name string) (acc Account, err error)
// AssignData stores a custom account key value pair
AssignData(account string, key string, value string) error
// GetValue returns custom account data for a specific key
GetValue(account string, key string) (string, error)
// VerifySecret will verify whether the account secret matches with the
VerifySecret(account string, secret string) (bool, error)
// GetSecret gets the secret associated with an account
GetSecret(account string) (string, error)
}
// Account represents a registered user
type Account struct {
// Name simply describes the account and must be unique
Name string `json:"name"`
// Data represents internal account data
Data map[string]string `json:"data"`
}

View file

@ -1,4 +1,4 @@
package accounts package internal
import ( import (
"testing" "testing"
@ -8,7 +8,7 @@ import (
func TestNewAccountant(t *testing.T) { func TestNewAccountant(t *testing.T) {
// Very basic verify here for now // Very basic verify here for now
accountant := NewAccountant() accountant := NewSimpleAccountant()
if accountant == nil { if accountant == nil {
t.Error("Failed to create accountant") t.Error("Failed to create accountant")
} }
@ -16,7 +16,7 @@ func TestNewAccountant(t *testing.T) {
func TestAccountant_RegisterAccount(t *testing.T) { func TestAccountant_RegisterAccount(t *testing.T) {
accountant := NewAccountant() accountant := NewSimpleAccountant()
// Start by making two accounts // Start by making two accounts
@ -44,10 +44,7 @@ func TestAccountant_RegisterAccount(t *testing.T) {
} }
func TestAccountant_AssignGetData(t *testing.T) { func TestAccountant_AssignGetData(t *testing.T) {
accountant := NewAccountant() accountant := NewSimpleAccountant()
if len(accountant.Accounts) != 0 {
t.Error("New accountant created with non-zero account number")
}
name := uuid.New().String() name := uuid.New().String()
a, err := accountant.RegisterAccount(name) a, err := accountant.RegisterAccount(name)

View file

@ -5,14 +5,14 @@ import (
"fmt" "fmt"
"log" "log"
"github.com/mdiluz/rove/pkg/game"
"github.com/mdiluz/rove/pkg/rove" "github.com/mdiluz/rove/pkg/rove"
"github.com/mdiluz/rove/pkg/version" "github.com/mdiluz/rove/pkg/version"
"github.com/mdiluz/rove/proto/roveapi"
) )
// ServerStatus returns the status of the current server to a gRPC request // ServerStatus returns the status of the current server to a gRPC request
func (s *Server) ServerStatus(context.Context, *rove.ServerStatusRequest) (*rove.ServerStatusResponse, error) { func (s *Server) ServerStatus(context.Context, *roveapi.ServerStatusRequest) (*roveapi.ServerStatusResponse, error) {
response := &rove.ServerStatusResponse{ response := &roveapi.ServerStatusResponse{
Ready: true, Ready: true,
Version: version.Version, Version: version.Version,
TickRate: int32(s.minutesPerTick), TickRate: int32(s.minutesPerTick),
@ -28,7 +28,7 @@ func (s *Server) ServerStatus(context.Context, *rove.ServerStatusRequest) (*rove
} }
// Register registers a new account for a gRPC request // Register registers a new account for a gRPC request
func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove.RegisterResponse, error) { func (s *Server) Register(ctx context.Context, req *roveapi.RegisterRequest) (*roveapi.RegisterResponse, error) {
log.Printf("Handling register request: %s\n", req.Name) log.Printf("Handling register request: %s\n", req.Name)
if len(req.Name) == 0 { if len(req.Name) == 0 {
@ -45,8 +45,8 @@ func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove
return nil, fmt.Errorf("internal server error when saving world: %s", err) return nil, fmt.Errorf("internal server error when saving world: %s", err)
} else { } else {
return &rove.RegisterResponse{ return &roveapi.RegisterResponse{
Account: &rove.Account{ Account: &roveapi.Account{
Name: acc.Name, Name: acc.Name,
Secret: acc.Data["secret"], Secret: acc.Data["secret"],
}, },
@ -55,7 +55,7 @@ func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove
} }
// Status returns rover information for a gRPC request // Status returns rover information for a gRPC request
func (s *Server) Status(ctx context.Context, req *rove.StatusRequest) (response *rove.StatusResponse, err error) { 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) log.Printf("Handling status request: %s\n", req.Account.Name)
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
@ -77,50 +77,50 @@ func (s *Server) Status(ctx context.Context, req *rove.StatusRequest) (response
} }
i, q := s.world.RoverCommands(resp) i, q := s.world.RoverCommands(resp)
var incoming, queued []*rove.Command var incoming, queued []*roveapi.Command
for _, i := range i { for _, i := range i {
c := &rove.Command{ c := &roveapi.Command{
Command: i.Command, Command: i.Command,
} }
switch i.Command { switch i.Command {
case rove.CommandType_move: case roveapi.CommandType_move:
c.Data = &rove.Command_Bearing{ c.Data = &roveapi.Command_Bearing{
Bearing: i.Bearing, Bearing: i.Bearing,
} }
case rove.CommandType_broadcast: case roveapi.CommandType_broadcast:
c.Data = &rove.Command_Message{ c.Data = &roveapi.Command_Message{
Message: i.Message, Message: i.Message,
} }
} }
incoming = append(incoming, c) incoming = append(incoming, c)
} }
for _, q := range q { for _, q := range q {
c := &rove.Command{ c := &roveapi.Command{
Command: q.Command, Command: q.Command,
} }
switch q.Command { switch q.Command {
case rove.CommandType_move: case roveapi.CommandType_move:
c.Data = &rove.Command_Bearing{ c.Data = &roveapi.Command_Bearing{
Bearing: q.Bearing, Bearing: q.Bearing,
} }
case rove.CommandType_broadcast: case roveapi.CommandType_broadcast:
c.Data = &rove.Command_Message{ c.Data = &roveapi.Command_Message{
Message: q.Message, Message: q.Message,
} }
} }
queued = append(queued, c) queued = append(queued, c)
} }
var logs []*rove.Log var logs []*roveapi.Log
for _, log := range rover.Logs { for _, log := range rover.Logs {
logs = append(logs, &rove.Log{ logs = append(logs, &roveapi.Log{
Text: log.Text, Text: log.Text,
Time: fmt.Sprintf("%d", log.Time.Unix()), // proto uses strings under the hood for 64bit ints anyway Time: fmt.Sprintf("%d", log.Time.Unix()), // proto uses strings under the hood for 64bit ints anyway
}) })
} }
response = &rove.StatusResponse{ response = &roveapi.StatusResponse{
Name: rover.Name, Name: rover.Name,
Position: &rove.Vector{ Position: &roveapi.Vector{
X: int32(rover.Pos.X), X: int32(rover.Pos.X),
Y: int32(rover.Pos.Y), Y: int32(rover.Pos.Y),
}, },
@ -140,7 +140,7 @@ func (s *Server) Status(ctx context.Context, req *rove.StatusRequest) (response
} }
// Radar returns the radar information for a rover // Radar returns the radar information for a rover
func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.RadarResponse, error) { func (s *Server) Radar(ctx context.Context, req *roveapi.RadarRequest) (*roveapi.RadarResponse, error) {
log.Printf("Handling radar request: %s\n", req.Account.Name) log.Printf("Handling radar request: %s\n", req.Account.Name)
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
@ -150,7 +150,7 @@ func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.Radar
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name) return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
} }
response := &rove.RadarResponse{} response := &roveapi.RadarResponse{}
resp, err := s.accountant.GetValue(req.Account.Name, "rover") resp, err := s.accountant.GetValue(req.Account.Name, "rover")
if err != nil { if err != nil {
@ -172,7 +172,7 @@ func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.Radar
} }
// Command issues commands to the world based on a gRPC request // Command issues commands to the world based on a gRPC request
func (s *Server) Command(ctx context.Context, req *rove.CommandRequest) (*rove.CommandResponse, error) { 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) log.Printf("Handling command request: %s and %+v\n", req.Account.Name, req.Commands)
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil { if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
@ -187,15 +187,15 @@ func (s *Server) Command(ctx context.Context, req *rove.CommandRequest) (*rove.C
return nil, err return nil, err
} }
var cmds []game.Command var cmds []rove.Command
for _, c := range req.Commands { for _, c := range req.Commands {
n := game.Command{ n := rove.Command{
Command: c.Command, Command: c.Command,
} }
switch c.Command { switch c.Command {
case rove.CommandType_move: case roveapi.CommandType_move:
n.Bearing = c.GetBearing() n.Bearing = c.GetBearing()
case rove.CommandType_broadcast: case roveapi.CommandType_broadcast:
n.Message = c.GetMessage() n.Message = c.GetMessage()
} }
cmds = append(cmds, n) cmds = append(cmds, n)
@ -205,5 +205,5 @@ func (s *Server) Command(ctx context.Context, req *rove.CommandRequest) (*rove.C
return nil, err return nil, err
} }
return &rove.CommandResponse{}, nil return &roveapi.CommandResponse{}, nil
} }

View file

@ -6,10 +6,9 @@ import (
"net" "net"
"sync" "sync"
"github.com/mdiluz/rove/pkg/accounts"
"github.com/mdiluz/rove/pkg/game"
"github.com/mdiluz/rove/pkg/persistence" "github.com/mdiluz/rove/pkg/persistence"
"github.com/mdiluz/rove/pkg/rove" "github.com/mdiluz/rove/pkg/rove"
"github.com/mdiluz/rove/proto/roveapi"
"github.com/robfig/cron" "github.com/robfig/cron"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -26,10 +25,10 @@ const (
type Server struct { type Server struct {
// Internal state // Internal state
world *game.World world *rove.World
// Accountant // Accountant
accountant *accounts.Accountant accountant Accountant
// gRPC server // gRPC server
netListener net.Listener netListener net.Listener
@ -80,8 +79,8 @@ func NewServer(opts ...ServerOption) *Server {
address: "", address: "",
persistence: EphemeralData, persistence: EphemeralData,
schedule: cron.New(), schedule: cron.New(),
world: game.NewWorld(32), world: rove.NewWorld(32),
accountant: accounts.NewAccountant(), accountant: NewSimpleAccountant(),
} }
// Apply all options // Apply all options
@ -109,7 +108,7 @@ func (s *Server) Initialise(fillWorld bool) (err error) {
log.Fatalf("failed to listen: %v", err) log.Fatalf("failed to listen: %v", err)
} }
s.grpcServ = grpc.NewServer() s.grpcServ = grpc.NewServer()
rove.RegisterRoveServer(s.grpcServ, s) roveapi.RegisterRoveServer(s.grpcServ, s)
return nil return nil
} }
@ -189,7 +188,7 @@ func (s *Server) SaveWorld() error {
if s.persistence == PersistentData { if s.persistence == PersistentData {
s.world.RLock() s.world.RLock()
defer s.world.RUnlock() 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) return fmt.Errorf("failed to save out persistent data: %s", err)
} }
} }
@ -201,7 +200,7 @@ func (s *Server) LoadWorld() error {
if s.persistence == PersistentData { if s.persistence == PersistentData {
s.world.Lock() s.world.Lock()
defer s.world.Unlock() 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 return err
} }
} }

View file

@ -1,4 +1,4 @@
package accounts package internal
import ( import (
"fmt" "fmt"
@ -7,29 +7,20 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
) )
// Account represents a registered user // SimpleAccountant manages a set of accounts
type Account struct { type SimpleAccountant struct {
// Name simply describes the account and must be unique
Name string `json:"name"`
// Data represents internal account data
Data map[string]string `json:"data"`
}
// Accountant manages a set of accounts
type Accountant struct {
Accounts map[string]Account `json:"accounts"` Accounts map[string]Account `json:"accounts"`
} }
// NewAccountant creates a new accountant // NewSimpleAccountant creates a new accountant
func NewAccountant() *Accountant { func NewSimpleAccountant() Accountant {
return &Accountant{ return &SimpleAccountant{
Accounts: make(map[string]Account), Accounts: make(map[string]Account),
} }
} }
// RegisterAccount adds an account to the set of internal accounts // RegisterAccount adds an account to the set of internal accounts
func (a *Accountant) RegisterAccount(name string) (acc Account, err error) { func (a *SimpleAccountant) RegisterAccount(name string) (acc Account, err error) {
// Set up the account info // Set up the account info
acc.Name = name acc.Name = name
@ -55,7 +46,7 @@ func (a *Accountant) RegisterAccount(name string) (acc Account, err error) {
} }
// VerifySecret verifies if an account secret is correct // VerifySecret verifies if an account secret is correct
func (a *Accountant) VerifySecret(account string, secret string) (bool, error) { func (a *SimpleAccountant) VerifySecret(account string, secret string) (bool, error) {
// Find the account matching the ID // Find the account matching the ID
if this, ok := a.Accounts[account]; ok { if this, ok := a.Accounts[account]; ok {
return this.Data["secret"] == secret, nil return this.Data["secret"] == secret, nil
@ -64,8 +55,18 @@ func (a *Accountant) VerifySecret(account string, secret string) (bool, error) {
return false, fmt.Errorf("no account found for id: %s", account) return false, fmt.Errorf("no account found for id: %s", account)
} }
// GetSecret gets the internal secret
func (a *SimpleAccountant) GetSecret(account string) (string, error) {
// Find the account matching the ID
if this, ok := a.Accounts[account]; ok {
return this.Data["secret"], nil
}
return "", fmt.Errorf("no account found for id: %s", account)
}
// AssignData assigns data to an account // AssignData assigns data to an account
func (a *Accountant) AssignData(account string, key string, value string) error { func (a *SimpleAccountant) AssignData(account string, key string, value string) error {
// Find the account matching the ID // Find the account matching the ID
if this, ok := a.Accounts[account]; ok { if this, ok := a.Accounts[account]; ok {
@ -79,7 +80,7 @@ func (a *Accountant) AssignData(account string, key string, value string) error
} }
// GetValue gets the rover rover for the account // GetValue gets the rover rover for the account
func (a *Accountant) GetValue(account string, key string) (string, error) { func (a *SimpleAccountant) GetValue(account string, key string) (string, error) {
// Find the account matching the ID // Find the account matching the ID
this, ok := a.Accounts[account] this, ok := a.Accounts[account]
if !ok { if !ok {

View file

@ -52,7 +52,9 @@ func InnerMain() {
log.Printf("Initialising version %s...\n", version.Version) log.Printf("Initialising version %s...\n", version.Version)
// Set the persistence path // Set the persistence path
if err := persistence.SetPath(data); err != nil { if len(data) == 0 {
log.Fatal("DATA_PATH not set")
} else if err := persistence.SetPath(data); err != nil {
log.Fatal(err) log.Fatal(err)
} }

View file

@ -11,10 +11,9 @@ import (
"time" "time"
"github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/objects"
"github.com/mdiluz/rove/pkg/rove"
"github.com/mdiluz/rove/pkg/version" "github.com/mdiluz/rove/pkg/version"
"github.com/mdiluz/rove/proto/roveapi"
"golang.org/x/net/context" "golang.org/x/net/context"
"google.golang.org/grpc" "google.golang.org/grpc"
) )
@ -66,7 +65,7 @@ func ConfigPath() string {
if len(override) > 0 { if len(override) > 0 {
datapath = override datapath = override
} }
datapath = path.Join(datapath, "rove.json") datapath = path.Join(datapath, "roveapi.json")
return datapath return datapath
} }
@ -163,14 +162,14 @@ func InnerMain(command string, args ...string) error {
if err != nil { if err != nil {
return err return err
} }
var client = rove.NewRoveClient(clientConn) var client = roveapi.NewRoveClient(clientConn)
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel() defer cancel()
// Handle all the commands // Handle all the commands
switch command { switch command {
case "server-status": case "server-status":
response, err := client.ServerStatus(ctx, &rove.ServerStatusRequest{}) response, err := client.ServerStatus(ctx, &roveapi.ServerStatusRequest{})
switch { switch {
case err != nil: case err != nil:
return err return err
@ -188,7 +187,7 @@ func InnerMain(command string, args ...string) error {
return fmt.Errorf("must pass name to 'register'") return fmt.Errorf("must pass name to 'register'")
} }
resp, err := client.Register(ctx, &rove.RegisterRequest{ resp, err := client.Register(ctx, &roveapi.RegisterRequest{
Name: args[0], Name: args[0],
}) })
switch { switch {
@ -209,20 +208,20 @@ func InnerMain(command string, args ...string) error {
} }
// Iterate through each command // Iterate through each command
var commands []*rove.Command var commands []*roveapi.Command
for i := 0; i < len(args); i++ { for i := 0; i < len(args); i++ {
switch args[i] { switch args[i] {
case "move": case "move":
i++ i++
if len(args) == i { if len(args) == i {
return fmt.Errorf("move command must be passed bearing") return fmt.Errorf("move command must be passed bearing")
} else if _, err := bearing.FromString(args[i]); err != nil { } else if _, err := maths.FromString(args[i]); err != nil {
return err return err
} }
commands = append(commands, commands = append(commands,
&rove.Command{ &roveapi.Command{
Command: rove.CommandType_move, Command: roveapi.CommandType_move,
Data: &rove.Command_Bearing{Bearing: args[i]}, Data: &roveapi.Command_Bearing{Bearing: args[i]},
}, },
) )
case "broadcast": case "broadcast":
@ -233,23 +232,23 @@ func InnerMain(command string, args ...string) error {
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])
} }
commands = append(commands, commands = append(commands,
&rove.Command{ &roveapi.Command{
Command: rove.CommandType_broadcast, Command: roveapi.CommandType_broadcast,
Data: &rove.Command_Message{Message: []byte(args[i])}, Data: &roveapi.Command_Message{Message: []byte(args[i])},
}, },
) )
default: default:
// By default just use the command literally // By default just use the command literally
commands = append(commands, commands = append(commands,
&rove.Command{ &roveapi.Command{
Command: rove.CommandType(rove.CommandType_value[args[i]]), Command: roveapi.CommandType(roveapi.CommandType_value[args[i]]),
}, },
) )
} }
} }
_, err := client.Command(ctx, &rove.CommandRequest{ _, err := client.Command(ctx, &roveapi.CommandRequest{
Account: &rove.Account{ Account: &roveapi.Account{
Name: config.Account.Name, Name: config.Account.Name,
Secret: config.Account.Secret, Secret: config.Account.Secret,
}, },
@ -269,8 +268,8 @@ func InnerMain(command string, args ...string) error {
return err return err
} }
response, err := client.Radar(ctx, &rove.RadarRequest{ response, err := client.Radar(ctx, &roveapi.RadarRequest{
Account: &rove.Account{ Account: &roveapi.Account{
Name: config.Account.Name, Name: config.Account.Name,
Secret: config.Account.Secret, Secret: config.Account.Secret,
}, },
@ -288,7 +287,7 @@ func InnerMain(command string, args ...string) error {
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
t := response.Tiles[i+num*j] t := response.Tiles[i+num*j]
o := response.Objects[i+num*j] o := response.Objects[i+num*j]
if o != byte(objects.None) { if o != byte(atlas.ObjectNone) {
fmt.Printf("%c", o) fmt.Printf("%c", o)
} else if t != byte(atlas.TileNone) { } else if t != byte(atlas.TileNone) {
fmt.Printf("%c", t) fmt.Printf("%c", t)
@ -306,8 +305,8 @@ func InnerMain(command string, args ...string) error {
return err return err
} }
response, err := client.Status(ctx, &rove.StatusRequest{ response, err := client.Status(ctx, &roveapi.StatusRequest{
Account: &rove.Account{ Account: &roveapi.Account{
Name: config.Account.Name, Name: config.Account.Name,
Secret: config.Account.Secret, Secret: config.Account.Secret,
}, },

1
go.mod
View file

@ -14,7 +14,6 @@ require (
golang.org/x/net v0.0.0-20200602114024-627f9648deb9 golang.org/x/net v0.0.0-20200602114024-627f9648deb9
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // indirect
golang.org/x/text v0.3.3 // indirect golang.org/x/text v0.3.3 // indirect
google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013
google.golang.org/grpc v1.30.0 google.golang.org/grpc v1.30.0
google.golang.org/protobuf v1.25.0 google.golang.org/protobuf v1.25.0
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect

View file

@ -1,13 +1,7 @@
package atlas package atlas
import ( import (
"log"
"math/rand"
"github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/objects"
"github.com/mdiluz/rove/pkg/vector"
"github.com/ojrac/opensimplex-go"
) )
// Tile describes the type of terrain // Tile describes the type of terrain
@ -27,257 +21,14 @@ const (
TileSand = Tile('~') TileSand = Tile('~')
) )
// Chunk represents a fixed square grid of tiles // Atlas represents a 2D world atlas of tiles and objects
type Chunk struct { type Atlas interface {
// Tiles represents the tiles within the chunk // SetTile sets a location on the Atlas to a type of tile
Tiles []byte `json:"tiles"` SetTile(v maths.Vector, tile Tile)
// Objects represents the objects within the chunk // SetObject will set a location on the Atlas to contain an object
// only one possible object per tile for now SetObject(v maths.Vector, obj Object)
Objects map[int]objects.Object `json:"objects"`
} // QueryPosition queries a position on the atlas
QueryPosition(v maths.Vector) (byte, Object)
// Atlas represents a grid of Chunks
type Atlas struct {
// Chunks represents all chunks in the world
// This is intentionally not a 2D array so it can be expanded in all directions
Chunks []Chunk `json:"chunks"`
// LowerBound is the origin of the bottom left corner of the current chunks in world space (current chunks cover >= this value)
LowerBound vector.Vector `json:"lowerBound"`
// UpperBound is the top left corner of the current chunks (curent chunks cover < this value)
UpperBound vector.Vector `json:"upperBound"`
// ChunkSize is the x/y dimensions of each square chunk
ChunkSize int `json:"chunksize"`
// terrainNoise describes the noise function for the terrain
terrainNoise opensimplex.Noise
// terrainNoise describes the noise function for the terrain
objectNoise opensimplex.Noise
}
const (
noiseSeed = 1024
terrainNoiseScale = 6
objectNoiseScale = 3
)
// NewAtlas creates a new empty atlas
func NewAtlas(chunkSize int) Atlas {
// Start up with one chunk
a := Atlas{
ChunkSize: chunkSize,
Chunks: make([]Chunk, 1),
LowerBound: vector.Vector{X: 0, Y: 0},
UpperBound: vector.Vector{X: chunkSize, Y: chunkSize},
terrainNoise: opensimplex.New(noiseSeed),
objectNoise: opensimplex.New(noiseSeed),
}
// Initialise the first chunk
a.populate(0)
return a
}
// SetTile sets an individual tile's kind
func (a *Atlas) SetTile(v vector.Vector, tile Tile) {
c := a.worldSpaceToChunkWithGrow(v)
local := a.worldSpaceToChunkLocal(v)
a.setTile(c, local, byte(tile))
}
// SetObject sets the object on a tile
func (a *Atlas) SetObject(v vector.Vector, obj objects.Object) {
c := a.worldSpaceToChunkWithGrow(v)
local := a.worldSpaceToChunkLocal(v)
a.setObject(c, local, obj)
}
// QueryPosition will return information for a specific position
func (a *Atlas) QueryPosition(v vector.Vector) (byte, objects.Object) {
c := a.worldSpaceToChunkWithGrow(v)
local := a.worldSpaceToChunkLocal(v)
a.populate(c)
chunk := a.Chunks[c]
i := a.chunkTileIndex(local)
return chunk.Tiles[i], chunk.Objects[i]
}
// chunkTileID returns the tile index within a chunk
func (a *Atlas) chunkTileIndex(local vector.Vector) int {
return local.X + local.Y*a.ChunkSize
}
// populate will fill a chunk with data
func (a *Atlas) populate(chunk int) {
c := a.Chunks[chunk]
if c.Tiles != nil {
return
}
c.Tiles = make([]byte, a.ChunkSize*a.ChunkSize)
c.Objects = make(map[int]objects.Object)
origin := a.chunkOriginInWorldSpace(chunk)
for i := 0; i < a.ChunkSize; i++ {
for j := 0; j < a.ChunkSize; j++ {
// Get the terrain noise value for this location
t := a.terrainNoise.Eval2(float64(origin.X+i)/terrainNoiseScale, float64(origin.Y+j)/terrainNoiseScale)
var tile Tile
switch {
case t > 0.5:
tile = TileGravel
case t > 0.05:
tile = TileSand
default:
tile = TileRock
}
c.Tiles[j*a.ChunkSize+i] = byte(tile)
// Get the object noise value for this location
o := a.objectNoise.Eval2(float64(origin.X+i)/objectNoiseScale, float64(origin.Y+j)/objectNoiseScale)
var obj = objects.None
switch {
case o > 0.6:
obj = objects.LargeRock
case o > 0.5:
obj = objects.SmallRock
}
if obj != objects.None {
c.Objects[j*a.ChunkSize+i] = objects.Object{Type: obj}
}
}
}
// Set up any objects
for i := 0; i < len(c.Tiles); i++ {
if rand.Intn(16) == 0 {
c.Objects[i] = objects.Object{Type: objects.LargeRock}
} else if rand.Intn(32) == 0 {
c.Objects[i] = objects.Object{Type: objects.SmallRock}
}
}
a.Chunks[chunk] = c
}
// setTile sets a tile in a specific chunk
func (a *Atlas) setTile(chunk int, local vector.Vector, tile byte) {
a.populate(chunk)
c := a.Chunks[chunk]
c.Tiles[a.chunkTileIndex(local)] = tile
a.Chunks[chunk] = c
}
// setObject sets an object in a specific chunk
func (a *Atlas) setObject(chunk int, local vector.Vector, object objects.Object) {
a.populate(chunk)
c := a.Chunks[chunk]
i := a.chunkTileIndex(local)
if object.Type != objects.None {
c.Objects[i] = object
} else {
delete(c.Objects, i)
}
a.Chunks[chunk] = c
}
// worldSpaceToChunkLocal gets a chunk local coordinate for a tile
func (a *Atlas) worldSpaceToChunkLocal(v vector.Vector) vector.Vector {
return vector.Vector{X: maths.Pmod(v.X, a.ChunkSize), Y: maths.Pmod(v.Y, a.ChunkSize)}
}
// worldSpaceToChunkID gets the current chunk ID for a position in the world
func (a *Atlas) worldSpaceToChunkIndex(v vector.Vector) int {
// Shift the vector by our current min
v = v.Added(a.LowerBound.Negated())
// Divide by the current size and floor, to get chunk-scaled vector from the lower bound
v = v.DividedFloor(a.ChunkSize)
// Calculate the width
width := a.UpperBound.X - a.LowerBound.X
widthInChunks := width / a.ChunkSize
// Along the corridor and up the stairs
return (v.Y * widthInChunks) + v.X
}
// chunkOriginInWorldSpace returns the origin of the chunk in world space
func (a *Atlas) chunkOriginInWorldSpace(chunk int) vector.Vector {
// Calculate the width
width := a.UpperBound.X - a.LowerBound.X
widthInChunks := width / a.ChunkSize
// Reverse the along the corridor and up the stairs
v := vector.Vector{
X: chunk % widthInChunks,
Y: chunk / widthInChunks,
}
// Multiply up to world scale
v = v.Multiplied(a.ChunkSize)
// Shift by the lower bound
return v.Added(a.LowerBound)
}
// getNewBounds gets new lower and upper bounds for the world space given a vector
func (a *Atlas) getNewBounds(v vector.Vector) (lower vector.Vector, upper vector.Vector) {
lower = vector.Min(v, a.LowerBound)
upper = vector.Max(v.Added(vector.Vector{X: 1, Y: 1}), a.UpperBound)
lower = vector.Vector{
X: maths.RoundDown(lower.X, a.ChunkSize),
Y: maths.RoundDown(lower.Y, a.ChunkSize),
}
upper = vector.Vector{
X: maths.RoundUp(upper.X, a.ChunkSize),
Y: maths.RoundUp(upper.Y, a.ChunkSize),
}
return
}
// worldSpaceToTrunkWithGrow will expand the current atlas for a given world space position if needed
func (a *Atlas) worldSpaceToChunkWithGrow(v vector.Vector) int {
// If we're within bounds, just return the current chunk
if v.X >= a.LowerBound.X && v.Y >= a.LowerBound.Y && v.X < a.UpperBound.X && v.Y < a.UpperBound.Y {
return a.worldSpaceToChunkIndex(v)
}
// Calculate the new bounds
lower, upper := a.getNewBounds(v)
size := upper.Added(lower.Negated())
size = size.Divided(a.ChunkSize)
// Create the new empty atlas
newAtlas := Atlas{
ChunkSize: a.ChunkSize,
LowerBound: lower,
UpperBound: upper,
Chunks: make([]Chunk, size.X*size.Y),
terrainNoise: a.terrainNoise,
objectNoise: a.objectNoise,
}
// Log that we're resizing
log.Printf("Re-allocating world, old: %+v,%+v new: %+v,%+v\n", a.LowerBound, a.UpperBound, newAtlas.LowerBound, newAtlas.UpperBound)
// Copy all old chunks into the new atlas
for chunk, chunkData := range a.Chunks {
// Calculate the chunk ID in the new atlas
origin := a.chunkOriginInWorldSpace(chunk)
newChunk := newAtlas.worldSpaceToChunkIndex(origin)
// Copy over the old chunk to the new atlas
newAtlas.Chunks[newChunk] = chunkData
}
// Overwrite the old atlas with this one
*a = newAtlas
return a.worldSpaceToChunkIndex(v)
} }

View file

@ -4,66 +4,65 @@ import (
"fmt" "fmt"
"testing" "testing"
"github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/vector"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
func TestAtlas_NewAtlas(t *testing.T) { func TestAtlas_NewAtlas(t *testing.T) {
a := NewAtlas(1) a := NewChunkAtlas(1).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
assert.Equal(t, 1, a.ChunkSize) assert.Equal(t, 1, a.ChunkSize)
assert.Equal(t, 1, len(a.Chunks)) // Should start empty assert.Equal(t, 1, len(a.Chunks)) // Should start empty
} }
func TestAtlas_toChunk(t *testing.T) { func TestAtlas_toChunk(t *testing.T) {
a := NewAtlas(1) a := NewChunkAtlas(1).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn the chunks // Get a tile to spawn the chunks
a.QueryPosition(vector.Vector{X: -1, Y: -1}) a.QueryPosition(maths.Vector{X: -1, Y: -1})
a.QueryPosition(vector.Vector{X: 0, Y: 0}) a.QueryPosition(maths.Vector{X: 0, Y: 0})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
// 2 | 3 // 2 | 3
// ----- // -----
// 0 | 1 // 0 | 1
chunkID := a.worldSpaceToChunkIndex(vector.Vector{X: 0, Y: 0}) chunkID := a.worldSpaceToChunkIndex(maths.Vector{X: 0, Y: 0})
assert.Equal(t, 3, chunkID) assert.Equal(t, 3, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 0, Y: -1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 0, Y: -1})
assert.Equal(t, 1, chunkID) assert.Equal(t, 1, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: -1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -1, Y: -1})
assert.Equal(t, 0, chunkID) assert.Equal(t, 0, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: 0}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -1, Y: 0})
assert.Equal(t, 2, chunkID) assert.Equal(t, 2, chunkID)
a = NewAtlas(2) a = NewChunkAtlas(2).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn the chunks // Get a tile to spawn the chunks
a.QueryPosition(vector.Vector{X: -2, Y: -2}) a.QueryPosition(maths.Vector{X: -2, Y: -2})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
a.QueryPosition(vector.Vector{X: 1, Y: 1}) a.QueryPosition(maths.Vector{X: 1, Y: 1})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
// 2 | 3 // 2 | 3
// ----- // -----
// 0 | 1 // 0 | 1
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: 1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: 1})
assert.Equal(t, 3, chunkID) assert.Equal(t, 3, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: -2}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: -2})
assert.Equal(t, 1, chunkID) assert.Equal(t, 1, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: -2}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -2, Y: -2})
assert.Equal(t, 0, chunkID) assert.Equal(t, 0, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -2, Y: 1})
assert.Equal(t, 2, chunkID) assert.Equal(t, 2, chunkID)
a = NewAtlas(2) a = NewChunkAtlas(2).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn a 4x4 grid of chunks // Get a tile to spawn a 4x4 grid of chunks
a.QueryPosition(vector.Vector{X: 3, Y: 3}) a.QueryPosition(maths.Vector{X: 3, Y: 3})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
a.QueryPosition(vector.Vector{X: -3, Y: -3}) a.QueryPosition(maths.Vector{X: -3, Y: -3})
assert.Equal(t, 4*4, len(a.Chunks)) assert.Equal(t, 4*4, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
@ -74,19 +73,19 @@ func TestAtlas_toChunk(t *testing.T) {
// 4 | 5 || 6 | 7 // 4 | 5 || 6 | 7
// ---------------- // ----------------
// 0 | 1 || 2 | 3 // 0 | 1 || 2 | 3
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: 3}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: 3})
assert.Equal(t, 14, chunkID) assert.Equal(t, 14, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: -3}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: -3})
assert.Equal(t, 2, chunkID) assert.Equal(t, 2, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: -1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -1, Y: -1})
assert.Equal(t, 5, chunkID) assert.Equal(t, 5, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 2}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -2, Y: 2})
assert.Equal(t, 13, chunkID) assert.Equal(t, 13, chunkID)
a = NewAtlas(3) a = NewChunkAtlas(3).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn a 4x4 grid of chunks // Get a tile to spawn a 4x4 grid of chunks
a.QueryPosition(vector.Vector{X: 3, Y: 3}) a.QueryPosition(maths.Vector{X: 3, Y: 3})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
@ -94,51 +93,51 @@ func TestAtlas_toChunk(t *testing.T) {
// ------- // -------
// || 0| 1 // || 0| 1
// ======= // =======
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: 1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: 1})
assert.Equal(t, 0, chunkID) assert.Equal(t, 0, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 3, Y: 1}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 3, Y: 1})
assert.Equal(t, 1, chunkID) assert.Equal(t, 1, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: 4}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: 4})
assert.Equal(t, 2, chunkID) assert.Equal(t, 2, chunkID)
chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 5, Y: 5}) chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 5, Y: 5})
assert.Equal(t, 3, chunkID) assert.Equal(t, 3, chunkID)
} }
func TestAtlas_toWorld(t *testing.T) { func TestAtlas_toWorld(t *testing.T) {
a := NewAtlas(1) a := NewChunkAtlas(1).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn some chunks // Get a tile to spawn some chunks
a.QueryPosition(vector.Vector{X: -1, Y: -1}) a.QueryPosition(maths.Vector{X: -1, Y: -1})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
// 2 | 3 // 2 | 3
// ----- // -----
// 0 | 1 // 0 | 1
assert.Equal(t, vector.Vector{X: -1, Y: -1}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, maths.Vector{X: -1, Y: -1}, a.chunkOriginInWorldSpace(0))
assert.Equal(t, vector.Vector{X: 0, Y: -1}, a.chunkOriginInWorldSpace(1)) assert.Equal(t, maths.Vector{X: 0, Y: -1}, a.chunkOriginInWorldSpace(1))
a = NewAtlas(2) a = NewChunkAtlas(2).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn the chunks // Get a tile to spawn the chunks
a.QueryPosition(vector.Vector{X: -2, Y: -2}) a.QueryPosition(maths.Vector{X: -2, Y: -2})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
a.QueryPosition(vector.Vector{X: 1, Y: 1}) a.QueryPosition(maths.Vector{X: 1, Y: 1})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
// 2 | 3 // 2 | 3
// ----- // -----
// 0 | 1 // 0 | 1
assert.Equal(t, vector.Vector{X: -2, Y: -2}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, maths.Vector{X: -2, Y: -2}, a.chunkOriginInWorldSpace(0))
assert.Equal(t, vector.Vector{X: -2, Y: 0}, a.chunkOriginInWorldSpace(2)) assert.Equal(t, maths.Vector{X: -2, Y: 0}, a.chunkOriginInWorldSpace(2))
a = NewAtlas(2) a = NewChunkAtlas(2).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn a 4x4 grid of chunks // Get a tile to spawn a 4x4 grid of chunks
a.QueryPosition(vector.Vector{X: 3, Y: 3}) a.QueryPosition(maths.Vector{X: 3, Y: 3})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
a.QueryPosition(vector.Vector{X: -3, Y: -3}) a.QueryPosition(maths.Vector{X: -3, Y: -3})
assert.Equal(t, 4*4, len(a.Chunks)) assert.Equal(t, 4*4, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
@ -149,13 +148,13 @@ func TestAtlas_toWorld(t *testing.T) {
// 4 | 5 || 6 | 7 // 4 | 5 || 6 | 7
// ---------------- // ----------------
// 0 | 1 || 2 | 3 // 0 | 1 || 2 | 3
assert.Equal(t, vector.Vector{X: -4, Y: -4}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, maths.Vector{X: -4, Y: -4}, a.chunkOriginInWorldSpace(0))
assert.Equal(t, vector.Vector{X: 2, Y: -2}, a.chunkOriginInWorldSpace(7)) assert.Equal(t, maths.Vector{X: 2, Y: -2}, a.chunkOriginInWorldSpace(7))
a = NewAtlas(3) a = NewChunkAtlas(3).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
// Get a tile to spawn a 4x4 grid of chunks // Get a tile to spawn a 4x4 grid of chunks
a.QueryPosition(vector.Vector{X: 3, Y: 3}) a.QueryPosition(maths.Vector{X: 3, Y: 3})
assert.Equal(t, 2*2, len(a.Chunks)) assert.Equal(t, 2*2, len(a.Chunks))
// Chunks should look like: // Chunks should look like:
@ -163,67 +162,67 @@ func TestAtlas_toWorld(t *testing.T) {
// ------- // -------
// || 0| 1 // || 0| 1
// ======= // =======
assert.Equal(t, vector.Vector{X: 0, Y: 0}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, maths.Vector{X: 0, Y: 0}, a.chunkOriginInWorldSpace(0))
} }
func TestAtlas_GetSetTile(t *testing.T) { func TestAtlas_GetSetTile(t *testing.T) {
a := NewAtlas(10) a := NewChunkAtlas(10)
assert.NotNil(t, a) assert.NotNil(t, a)
// Set the origin tile to 1 and test it // Set the origin tile to 1 and test it
a.SetTile(vector.Vector{X: 0, Y: 0}, 1) a.SetTile(maths.Vector{X: 0, Y: 0}, 1)
tile, _ := a.QueryPosition(vector.Vector{X: 0, Y: 0}) tile, _ := a.QueryPosition(maths.Vector{X: 0, Y: 0})
assert.Equal(t, byte(1), tile) assert.Equal(t, byte(1), tile)
// Set another tile to 1 and test it // Set another tile to 1 and test it
a.SetTile(vector.Vector{X: 5, Y: -2}, 2) a.SetTile(maths.Vector{X: 5, Y: -2}, 2)
tile, _ = a.QueryPosition(vector.Vector{X: 5, Y: -2}) tile, _ = a.QueryPosition(maths.Vector{X: 5, Y: -2})
assert.Equal(t, byte(2), tile) assert.Equal(t, byte(2), tile)
} }
func TestAtlas_GetSetObject(t *testing.T) { func TestAtlas_GetSetObject(t *testing.T) {
a := NewAtlas(10) a := NewChunkAtlas(10)
assert.NotNil(t, a) assert.NotNil(t, a)
// Set the origin tile to 1 and test it // Set the origin tile to 1 and test it
a.SetObject(vector.Vector{X: 0, Y: 0}, objects.Object{Type: objects.LargeRock}) a.SetObject(maths.Vector{X: 0, Y: 0}, Object{Type: ObjectLargeRock})
_, obj := a.QueryPosition(vector.Vector{X: 0, Y: 0}) _, obj := a.QueryPosition(maths.Vector{X: 0, Y: 0})
assert.Equal(t, objects.Object{Type: objects.LargeRock}, obj) assert.Equal(t, Object{Type: ObjectLargeRock}, obj)
// Set another tile to 1 and test it // Set another tile to 1 and test it
a.SetObject(vector.Vector{X: 5, Y: -2}, objects.Object{Type: objects.SmallRock}) a.SetObject(maths.Vector{X: 5, Y: -2}, Object{Type: ObjectSmallRock})
_, obj = a.QueryPosition(vector.Vector{X: 5, Y: -2}) _, obj = a.QueryPosition(maths.Vector{X: 5, Y: -2})
assert.Equal(t, objects.Object{Type: objects.SmallRock}, obj) assert.Equal(t, Object{Type: ObjectSmallRock}, obj)
} }
func TestAtlas_Grown(t *testing.T) { func TestAtlas_Grown(t *testing.T) {
// Start with a small example // Start with a small example
a := NewAtlas(2) a := NewChunkAtlas(2).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
assert.Equal(t, 1, len(a.Chunks)) assert.Equal(t, 1, len(a.Chunks))
// Set a few tiles to values // Set a few tiles to values
a.SetTile(vector.Vector{X: 0, Y: 0}, 1) a.SetTile(maths.Vector{X: 0, Y: 0}, 1)
a.SetTile(vector.Vector{X: -1, Y: -1}, 2) a.SetTile(maths.Vector{X: -1, Y: -1}, 2)
a.SetTile(vector.Vector{X: 1, Y: -2}, 3) a.SetTile(maths.Vector{X: 1, Y: -2}, 3)
// Check tile values // Check tile values
tile, _ := a.QueryPosition(vector.Vector{X: 0, Y: 0}) tile, _ := a.QueryPosition(maths.Vector{X: 0, Y: 0})
assert.Equal(t, byte(1), tile) assert.Equal(t, byte(1), tile)
tile, _ = a.QueryPosition(vector.Vector{X: -1, Y: -1}) tile, _ = a.QueryPosition(maths.Vector{X: -1, Y: -1})
assert.Equal(t, byte(2), tile) assert.Equal(t, byte(2), tile)
tile, _ = a.QueryPosition(vector.Vector{X: 1, Y: -2}) tile, _ = a.QueryPosition(maths.Vector{X: 1, Y: -2})
assert.Equal(t, byte(3), tile) assert.Equal(t, byte(3), tile)
tile, _ = a.QueryPosition(vector.Vector{X: 0, Y: 0}) tile, _ = a.QueryPosition(maths.Vector{X: 0, Y: 0})
assert.Equal(t, byte(1), tile) assert.Equal(t, byte(1), tile)
tile, _ = a.QueryPosition(vector.Vector{X: -1, Y: -1}) tile, _ = a.QueryPosition(maths.Vector{X: -1, Y: -1})
assert.Equal(t, byte(2), tile) assert.Equal(t, byte(2), tile)
tile, _ = a.QueryPosition(vector.Vector{X: 1, Y: -2}) tile, _ = a.QueryPosition(maths.Vector{X: 1, Y: -2})
assert.Equal(t, byte(3), tile) assert.Equal(t, byte(3), tile)
} }
@ -233,17 +232,17 @@ func TestAtlas_GetSetCorrect(t *testing.T) {
for x := -i * 2; x < i*2; x++ { for x := -i * 2; x < i*2; x++ {
for y := -i * 2; y < i*2; y++ { for y := -i * 2; y < i*2; y++ {
a := NewAtlas(i) a := NewChunkAtlas(i).(*chunkBasedAtlas)
assert.NotNil(t, a) assert.NotNil(t, a)
assert.Equal(t, 1, len(a.Chunks)) assert.Equal(t, 1, len(a.Chunks))
pos := vector.Vector{X: x, Y: y} pos := maths.Vector{X: x, Y: y}
a.SetTile(pos, TileRock) a.SetTile(pos, TileRock)
a.SetObject(pos, objects.Object{Type: objects.LargeRock}) a.SetObject(pos, Object{Type: ObjectLargeRock})
tile, obj := a.QueryPosition(pos) tile, obj := a.QueryPosition(pos)
assert.Equal(t, TileRock, Tile(tile)) assert.Equal(t, TileRock, Tile(tile))
assert.Equal(t, objects.Object{Type: objects.LargeRock}, obj) assert.Equal(t, Object{Type: ObjectLargeRock}, obj)
} }
} }
@ -251,16 +250,16 @@ func TestAtlas_GetSetCorrect(t *testing.T) {
} }
func TestAtlas_WorldGen(t *testing.T) { func TestAtlas_WorldGen(t *testing.T) {
a := NewAtlas(8) a := NewChunkAtlas(8)
// Spawn a large world // Spawn a large world
_, _ = a.QueryPosition(vector.Vector{X: 20, Y: 20}) _, _ = a.QueryPosition(maths.Vector{X: 20, Y: 20})
// Print out the world for manual evaluation // Print out the world for manual evaluation
num := 20 num := 20
for j := num - 1; j >= 0; j-- { for j := num - 1; j >= 0; j-- {
for i := 0; i < num; i++ { for i := 0; i < num; i++ {
t, o := a.QueryPosition(vector.Vector{X: i, Y: j}) t, o := a.QueryPosition(maths.Vector{X: i, Y: j})
if o.Type != objects.None { if o.Type != ObjectNone {
fmt.Printf("%c", o.Type) fmt.Printf("%c", o.Type)
} else if t != byte(TileNone) { } else if t != byte(TileNone) {
fmt.Printf("%c", t) fmt.Printf("%c", t)

264
pkg/atlas/chunkAtlas.go Normal file
View file

@ -0,0 +1,264 @@
package atlas
import (
"log"
"math/rand"
"github.com/mdiluz/rove/pkg/maths"
"github.com/ojrac/opensimplex-go"
)
// chunk represents a fixed square grid of tiles
type chunk struct {
// Tiles represents the tiles within the chunk
Tiles []byte `json:"tiles"`
// Objects represents the objects within the chunk
// only one possible object per tile for now
Objects map[int]Object `json:"objects"`
}
// chunkBasedAtlas represents a grid of Chunks
type chunkBasedAtlas struct {
// Chunks represents all chunks in the world
// This is intentionally not a 2D array so it can be expanded in all directions
Chunks []chunk `json:"chunks"`
// LowerBound is the origin of the bottom left corner of the current chunks in world space (current chunks cover >= this value)
LowerBound maths.Vector `json:"lowerBound"`
// UpperBound is the top left corner of the current chunks (curent chunks cover < this value)
UpperBound maths.Vector `json:"upperBound"`
// ChunkSize is the x/y dimensions of each square chunk
ChunkSize int `json:"chunksize"`
// terrainNoise describes the noise function for the terrain
terrainNoise opensimplex.Noise
// terrainNoise describes the noise function for the terrain
objectNoise opensimplex.Noise
}
const (
noiseSeed = 1024
terrainNoiseScale = 6
objectNoiseScale = 3
)
// NewChunkAtlas creates a new empty atlas
func NewChunkAtlas(chunkSize int) Atlas {
// Start up with one chunk
a := chunkBasedAtlas{
ChunkSize: chunkSize,
Chunks: make([]chunk, 1),
LowerBound: maths.Vector{X: 0, Y: 0},
UpperBound: maths.Vector{X: chunkSize, Y: chunkSize},
terrainNoise: opensimplex.New(noiseSeed),
objectNoise: opensimplex.New(noiseSeed),
}
// Initialise the first chunk
a.populate(0)
return &a
}
// SetTile sets an individual tile's kind
func (a *chunkBasedAtlas) SetTile(v maths.Vector, tile Tile) {
c := a.worldSpaceToChunkWithGrow(v)
local := a.worldSpaceToChunkLocal(v)
a.setTile(c, local, byte(tile))
}
// SetObject sets the object on a tile
func (a *chunkBasedAtlas) SetObject(v maths.Vector, obj Object) {
c := a.worldSpaceToChunkWithGrow(v)
local := a.worldSpaceToChunkLocal(v)
a.setObject(c, local, obj)
}
// QueryPosition will return information for a specific position
func (a *chunkBasedAtlas) QueryPosition(v maths.Vector) (byte, Object) {
c := a.worldSpaceToChunkWithGrow(v)
local := a.worldSpaceToChunkLocal(v)
a.populate(c)
chunk := a.Chunks[c]
i := a.chunkTileIndex(local)
return chunk.Tiles[i], chunk.Objects[i]
}
// chunkTileID returns the tile index within a chunk
func (a *chunkBasedAtlas) chunkTileIndex(local maths.Vector) int {
return local.X + local.Y*a.ChunkSize
}
// populate will fill a chunk with data
func (a *chunkBasedAtlas) populate(chunk int) {
c := a.Chunks[chunk]
if c.Tiles != nil {
return
}
c.Tiles = make([]byte, a.ChunkSize*a.ChunkSize)
c.Objects = make(map[int]Object)
origin := a.chunkOriginInWorldSpace(chunk)
for i := 0; i < a.ChunkSize; i++ {
for j := 0; j < a.ChunkSize; j++ {
// Get the terrain noise value for this location
t := a.terrainNoise.Eval2(float64(origin.X+i)/terrainNoiseScale, float64(origin.Y+j)/terrainNoiseScale)
var tile Tile
switch {
case t > 0.5:
tile = TileGravel
case t > 0.05:
tile = TileSand
default:
tile = TileRock
}
c.Tiles[j*a.ChunkSize+i] = byte(tile)
// Get the object noise value for this location
o := a.objectNoise.Eval2(float64(origin.X+i)/objectNoiseScale, float64(origin.Y+j)/objectNoiseScale)
var obj = ObjectNone
switch {
case o > 0.6:
obj = ObjectLargeRock
case o > 0.5:
obj = ObjectSmallRock
}
if obj != ObjectNone {
c.Objects[j*a.ChunkSize+i] = Object{Type: obj}
}
}
}
// Set up any objects
for i := 0; i < len(c.Tiles); i++ {
if rand.Intn(16) == 0 {
c.Objects[i] = Object{Type: ObjectLargeRock}
} else if rand.Intn(32) == 0 {
c.Objects[i] = Object{Type: ObjectSmallRock}
}
}
a.Chunks[chunk] = c
}
// setTile sets a tile in a specific chunk
func (a *chunkBasedAtlas) setTile(chunk int, local maths.Vector, tile byte) {
a.populate(chunk)
c := a.Chunks[chunk]
c.Tiles[a.chunkTileIndex(local)] = tile
a.Chunks[chunk] = c
}
// setObject sets an object in a specific chunk
func (a *chunkBasedAtlas) setObject(chunk int, local maths.Vector, object Object) {
a.populate(chunk)
c := a.Chunks[chunk]
i := a.chunkTileIndex(local)
if object.Type != ObjectNone {
c.Objects[i] = object
} else {
delete(c.Objects, i)
}
a.Chunks[chunk] = c
}
// worldSpaceToChunkLocal gets a chunk local coordinate for a tile
func (a *chunkBasedAtlas) worldSpaceToChunkLocal(v maths.Vector) maths.Vector {
return maths.Vector{X: maths.Pmod(v.X, a.ChunkSize), Y: maths.Pmod(v.Y, a.ChunkSize)}
}
// worldSpaceToChunkID gets the current chunk ID for a position in the world
func (a *chunkBasedAtlas) worldSpaceToChunkIndex(v maths.Vector) int {
// Shift the vector by our current min
v = v.Added(a.LowerBound.Negated())
// Divide by the current size and floor, to get chunk-scaled vector from the lower bound
v = v.DividedFloor(a.ChunkSize)
// Calculate the width
width := a.UpperBound.X - a.LowerBound.X
widthInChunks := width / a.ChunkSize
// Along the corridor and up the stairs
return (v.Y * widthInChunks) + v.X
}
// chunkOriginInWorldSpace returns the origin of the chunk in world space
func (a *chunkBasedAtlas) chunkOriginInWorldSpace(chunk int) maths.Vector {
// Calculate the width
width := a.UpperBound.X - a.LowerBound.X
widthInChunks := width / a.ChunkSize
// Reverse the along the corridor and up the stairs
v := maths.Vector{
X: chunk % widthInChunks,
Y: chunk / widthInChunks,
}
// Multiply up to world scale
v = v.Multiplied(a.ChunkSize)
// Shift by the lower bound
return v.Added(a.LowerBound)
}
// getNewBounds gets new lower and upper bounds for the world space given a vector
func (a *chunkBasedAtlas) getNewBounds(v maths.Vector) (lower maths.Vector, upper maths.Vector) {
lower = maths.Min2(v, a.LowerBound)
upper = maths.Max2(v.Added(maths.Vector{X: 1, Y: 1}), a.UpperBound)
lower = maths.Vector{
X: maths.RoundDown(lower.X, a.ChunkSize),
Y: maths.RoundDown(lower.Y, a.ChunkSize),
}
upper = maths.Vector{
X: maths.RoundUp(upper.X, a.ChunkSize),
Y: maths.RoundUp(upper.Y, a.ChunkSize),
}
return
}
// worldSpaceToTrunkWithGrow will expand the current atlas for a given world space position if needed
func (a *chunkBasedAtlas) worldSpaceToChunkWithGrow(v maths.Vector) int {
// If we're within bounds, just return the current chunk
if v.X >= a.LowerBound.X && v.Y >= a.LowerBound.Y && v.X < a.UpperBound.X && v.Y < a.UpperBound.Y {
return a.worldSpaceToChunkIndex(v)
}
// Calculate the new bounds
lower, upper := a.getNewBounds(v)
size := upper.Added(lower.Negated())
size = size.Divided(a.ChunkSize)
// Create the new empty atlas
newAtlas := chunkBasedAtlas{
ChunkSize: a.ChunkSize,
LowerBound: lower,
UpperBound: upper,
Chunks: make([]chunk, size.X*size.Y),
terrainNoise: a.terrainNoise,
objectNoise: a.objectNoise,
}
// Log that we're resizing
log.Printf("Re-allocating world, old: %+v,%+v new: %+v,%+v\n", a.LowerBound, a.UpperBound, newAtlas.LowerBound, newAtlas.UpperBound)
// Copy all old chunks into the new atlas
for chunk, chunkData := range a.Chunks {
// Calculate the chunk ID in the new atlas
origin := a.chunkOriginInWorldSpace(chunk)
newChunk := newAtlas.worldSpaceToChunkIndex(origin)
// Copy over the old chunk to the new atlas
newAtlas.Chunks[newChunk] = chunkData
}
// Overwrite the old atlas with this one
*a = newAtlas
return a.worldSpaceToChunkIndex(v)
}

View file

@ -1,21 +1,21 @@
package objects package atlas
// Type represents an object type // Type represents an object type
type Type byte type Type byte
// Types of objects // Types of objects
const ( const (
// None represents no object at all // ObjectNone represents no object at all
None = Type(0) ObjectNone = Type(0)
// Rover represents a live rover // ObjectRover represents a live rover
Rover = Type('R') ObjectRover = Type('R')
// SmallRock is a small stashable rock // ObjectSmallRock is a small stashable rock
SmallRock = Type('o') ObjectSmallRock = Type('o')
// LargeRock is a large blocking rock // ObjectLargeRock is a large blocking rock
LargeRock = Type('O') ObjectLargeRock = Type('O')
) )
// Object represents an object in the world // Object represents an object in the world
@ -26,8 +26,8 @@ type Object struct {
// IsBlocking checks if an object is a blocking object // IsBlocking checks if an object is a blocking object
func (o *Object) IsBlocking() bool { func (o *Object) IsBlocking() bool {
var blocking = [...]Type{ var blocking = [...]Type{
Rover, ObjectRover,
LargeRock, ObjectLargeRock,
} }
for _, t := range blocking { for _, t := range blocking {
@ -41,7 +41,7 @@ func (o *Object) IsBlocking() bool {
// IsStashable checks if an object is stashable // IsStashable checks if an object is stashable
func (o *Object) IsStashable() bool { func (o *Object) IsStashable() bool {
var stashable = [...]Type{ var stashable = [...]Type{
SmallRock, ObjectSmallRock,
} }
for _, t := range stashable { for _, t := range stashable {

View file

@ -1,10 +1,8 @@
package bearing package maths
import ( import (
"fmt" "fmt"
"strings" "strings"
"github.com/mdiluz/rove/pkg/vector"
) )
// Bearing describes a compass direction // Bearing describes a compass direction
@ -67,7 +65,7 @@ func FromString(s string) (Bearing, error) {
return -1, fmt.Errorf("unknown bearing: %s", s) return -1, fmt.Errorf("unknown bearing: %s", s)
} }
var bearingVectors = []vector.Vector{ var bearingVectors = []Vector{
{X: 0, Y: 1}, // N {X: 0, Y: 1}, // N
{X: 1, Y: 1}, // NE {X: 1, Y: 1}, // NE
{X: 1, Y: 0}, // E {X: 1, Y: 0}, // E
@ -79,6 +77,6 @@ var bearingVectors = []vector.Vector{
} }
// Vector converts a Direction to a Vector // Vector converts a Direction to a Vector
func (d Bearing) Vector() vector.Vector { func (d Bearing) Vector() Vector {
return bearingVectors[d] return bearingVectors[d]
} }

View file

@ -1,9 +1,8 @@
package bearing package maths
import ( import (
"testing" "testing"
"github.com/mdiluz/rove/pkg/vector"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -12,7 +11,7 @@ func TestDirection(t *testing.T) {
assert.Equal(t, "North", dir.String()) assert.Equal(t, "North", dir.String())
assert.Equal(t, "N", dir.ShortString()) assert.Equal(t, "N", dir.ShortString())
assert.Equal(t, vector.Vector{X: 0, Y: 1}, dir.Vector()) assert.Equal(t, Vector{X: 0, Y: 1}, dir.Vector())
dir, err := FromString("N") dir, err := FromString("N")
assert.NoError(t, err) assert.NoError(t, err)

View file

@ -1,9 +1,7 @@
package vector package maths
import ( import (
"math" "math"
"github.com/mdiluz/rove/pkg/maths"
) )
// Vector desribes a 3D vector // Vector desribes a 3D vector
@ -71,15 +69,15 @@ func (v Vector) DividedFloor(val int) Vector {
// Abs returns an absolute version of the vector // Abs returns an absolute version of the vector
func (v Vector) Abs() Vector { func (v Vector) Abs() Vector {
return Vector{maths.Abs(v.X), maths.Abs(v.Y)} return Vector{Abs(v.X), Abs(v.Y)}
} }
// Min returns the minimum values in both vectors // Min2 returns the minimum values in both vectors
func Min(v1 Vector, v2 Vector) Vector { func Min2(v1 Vector, v2 Vector) Vector {
return Vector{maths.Min(v1.X, v2.X), maths.Min(v1.Y, v2.Y)} return Vector{Min(v1.X, v2.X), Min(v1.Y, v2.Y)}
} }
// Max returns the max values in both vectors // Max2 returns the max values in both vectors
func Max(v1 Vector, v2 Vector) Vector { func Max2(v1 Vector, v2 Vector) Vector {
return Vector{maths.Max(v1.X, v2.X), maths.Max(v1.Y, v2.Y)} return Vector{Max(v1.X, v2.X), Max(v1.Y, v2.Y)}
} }

View file

@ -1,4 +1,4 @@
package vector package maths
import ( import (
"math" "math"

View file

@ -1,10 +1,10 @@
package game package rove
import "github.com/mdiluz/rove/pkg/rove" import "github.com/mdiluz/rove/proto/roveapi"
// Command represends a single command to execute // Command represends a single command to execute
type Command struct { type Command struct {
Command rove.CommandType `json:"command"` Command roveapi.CommandType `json:"command"`
// Used in the move command // Used in the move command
Bearing string `json:"bearing,omitempty"` Bearing string `json:"bearing,omitempty"`

View file

@ -1,10 +1,10 @@
package game package rove
import ( import (
"testing" "testing"
"github.com/mdiluz/rove/pkg/rove" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/vector" "github.com/mdiluz/rove/proto/roveapi"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -12,7 +12,7 @@ func TestCommand_Move(t *testing.T) {
world := NewWorld(8) world := NewWorld(8)
a, err := world.SpawnRover() a, err := world.SpawnRover()
assert.NoError(t, err) assert.NoError(t, err)
pos := vector.Vector{ pos := maths.Vector{
X: 1.0, X: 1.0,
Y: 2.0, Y: 2.0,
} }
@ -21,7 +21,7 @@ func TestCommand_Move(t *testing.T) {
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
// Try the move command // Try the move command
moveCommand := Command{Command: rove.CommandType_move, Bearing: "N"} moveCommand := Command{Command: roveapi.CommandType_move, Bearing: "N"}
assert.NoError(t, world.Enqueue(a, moveCommand), "Failed to execute move command") assert.NoError(t, world.Enqueue(a, moveCommand), "Failed to execute move command")
// Tick the world // Tick the world
@ -30,7 +30,7 @@ func TestCommand_Move(t *testing.T) {
newPos, err := world.RoverPosition(a) newPos, err := world.RoverPosition(a)
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
pos.Add(vector.Vector{X: 0.0, Y: 1}) pos.Add(maths.Vector{X: 0.0, Y: 1})
assert.Equal(t, pos, newPos, "Failed to correctly set position for rover") assert.Equal(t, pos, newPos, "Failed to correctly set position for rover")
} }
@ -38,7 +38,7 @@ func TestCommand_Recharge(t *testing.T) {
world := NewWorld(8) world := NewWorld(8)
a, err := world.SpawnRover() a, err := world.SpawnRover()
assert.NoError(t, err) assert.NoError(t, err)
pos := vector.Vector{ pos := maths.Vector{
X: 1.0, X: 1.0,
Y: 2.0, Y: 2.0,
} }
@ -47,7 +47,7 @@ func TestCommand_Recharge(t *testing.T) {
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
// Move to use up some charge // Move to use up some charge
moveCommand := Command{Command: rove.CommandType_move, Bearing: "N"} moveCommand := Command{Command: roveapi.CommandType_move, Bearing: "N"}
assert.NoError(t, world.Enqueue(a, moveCommand), "Failed to queue move command") assert.NoError(t, world.Enqueue(a, moveCommand), "Failed to queue move command")
// Tick the world // Tick the world
@ -57,7 +57,7 @@ func TestCommand_Recharge(t *testing.T) {
rover, _ := world.GetRover(a) rover, _ := world.GetRover(a)
assert.Equal(t, rover.MaximumCharge-1, rover.Charge) assert.Equal(t, rover.MaximumCharge-1, rover.Charge)
chargeCommand := Command{Command: rove.CommandType_recharge} chargeCommand := Command{Command: roveapi.CommandType_recharge}
assert.NoError(t, world.Enqueue(a, chargeCommand), "Failed to queue recharge command") assert.NoError(t, world.Enqueue(a, chargeCommand), "Failed to queue recharge command")
// Tick the world // Tick the world

View file

@ -1,12 +1,12 @@
package game package rove
import ( import (
"fmt" "fmt"
"log" "log"
"time" "time"
"github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/vector" "github.com/mdiluz/rove/pkg/maths"
) )
// RoverLogEntry describes a single log entry for the rover // RoverLogEntry describes a single log entry for the rover
@ -24,13 +24,13 @@ type Rover struct {
Name string `json:"name"` Name string `json:"name"`
// Pos represents where this rover is in the world // Pos represents where this rover is in the world
Pos vector.Vector `json:"pos"` Pos maths.Vector `json:"pos"`
// Range represents the distance the unit's radar can see // Range represents the distance the unit's radar can see
Range int `json:"range"` Range int `json:"range"`
// Inventory represents any items the rover is carrying // Inventory represents any items the rover is carrying
Inventory []objects.Object `json:"inventory"` Inventory []atlas.Object `json:"inventory"`
// Capacity is the maximum number of inventory items // Capacity is the maximum number of inventory items
Capacity int `json:"capacity"` Capacity int `json:"capacity"`

View file

@ -1,4 +1,4 @@
package game package rove
import ( import (
"bufio" "bufio"
@ -10,40 +10,35 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/proto/roveapi"
"github.com/mdiluz/rove/pkg/rove"
"github.com/mdiluz/rove/pkg/vector"
) )
// World describes a self contained universe and everything in it // World describes a self contained universe and everything in it
type World struct { type World struct {
// TicksPerDay is the amount of ticks in a single day
TicksPerDay int `json:"ticks-per-day"`
// Current number of ticks from the start
CurrentTicks int `json:"current-ticks"`
// Rovers is a id->data map of all the rovers in the game // Rovers is a id->data map of all the rovers in the game
Rovers map[string]Rover `json:"rovers"` Rovers map[string]Rover `json:"rovers"`
// Atlas represends the world map of chunks and tiles // Atlas represends the world map of chunks and tiles
Atlas atlas.Atlas `json:"atlas"` Atlas atlas.Atlas `json:"atlas"`
// Mutex to lock around all world operations
worldMutex sync.RWMutex
// Commands is the set of currently executing command streams per rover // Commands is the set of currently executing command streams per rover
CommandQueue map[string]CommandStream `json:"commands"` CommandQueue map[string]CommandStream `json:"commands"`
// Incoming represents the set of commands to add to the queue at the end of the current tick // Incoming represents the set of commands to add to the queue at the end of the current tick
CommandIncoming map[string]CommandStream `json:"incoming"` CommandIncoming map[string]CommandStream `json:"incoming"`
// Mutex to lock around all world operations
worldMutex sync.RWMutex
// Mutex to lock around command operations // Mutex to lock around command operations
cmdMutex sync.RWMutex cmdMutex sync.RWMutex
// Set of possible words to use for names // Set of possible words to use for names
words []string words []string
// TicksPerDay is the amount of ticks in a single day
TicksPerDay int `json:"ticks-per-day"`
// Current number of ticks from the start
CurrentTicks int `json:"current-ticks"`
} }
var wordsFile = os.Getenv("WORDS_FILE") var wordsFile = os.Getenv("WORDS_FILE")
@ -70,7 +65,7 @@ func NewWorld(chunkSize int) *World {
Rovers: make(map[string]Rover), Rovers: make(map[string]Rover),
CommandQueue: make(map[string]CommandStream), CommandQueue: make(map[string]CommandStream),
CommandIncoming: make(map[string]CommandStream), CommandIncoming: make(map[string]CommandStream),
Atlas: atlas.NewAtlas(chunkSize), Atlas: atlas.NewChunkAtlas(chunkSize),
words: lines, words: lines,
TicksPerDay: 24, TicksPerDay: 24,
CurrentTicks: 0, CurrentTicks: 0,
@ -106,9 +101,9 @@ func (w *World) SpawnRover() (string, error) {
} }
// Spawn in a random place near the origin // Spawn in a random place near the origin
rover.Pos = vector.Vector{ rover.Pos = maths.Vector{
X: w.Atlas.ChunkSize/2 - rand.Intn(w.Atlas.ChunkSize), X: 10 - rand.Intn(20),
Y: w.Atlas.ChunkSize/2 - rand.Intn(w.Atlas.ChunkSize), Y: 10 - rand.Intn(20),
} }
// Seach until we error (run out of world) // Seach until we error (run out of world)
@ -118,7 +113,7 @@ func (w *World) SpawnRover() (string, error) {
break break
} else { } else {
// Try and spawn to the east of the blockage // Try and spawn to the east of the blockage
rover.Pos.Add(vector.Vector{X: 1, Y: 0}) rover.Pos.Add(maths.Vector{X: 1, Y: 0})
} }
} }
@ -218,19 +213,19 @@ func (w *World) DestroyRover(rover string) error {
} }
// RoverPosition returns the position of the rover // RoverPosition returns the position of the rover
func (w *World) RoverPosition(rover string) (vector.Vector, error) { func (w *World) RoverPosition(rover string) (maths.Vector, error) {
w.worldMutex.RLock() w.worldMutex.RLock()
defer w.worldMutex.RUnlock() defer w.worldMutex.RUnlock()
i, ok := w.Rovers[rover] i, ok := w.Rovers[rover]
if !ok { if !ok {
return vector.Vector{}, fmt.Errorf("no rover matching id") return maths.Vector{}, fmt.Errorf("no rover matching id")
} }
return i.Pos, nil return i.Pos, nil
} }
// SetRoverPosition sets the position of the rover // SetRoverPosition sets the position of the rover
func (w *World) SetRoverPosition(rover string, pos vector.Vector) error { func (w *World) SetRoverPosition(rover string, pos maths.Vector) error {
w.worldMutex.Lock() w.worldMutex.Lock()
defer w.worldMutex.Unlock() defer w.worldMutex.Unlock()
@ -245,7 +240,7 @@ func (w *World) SetRoverPosition(rover string, pos vector.Vector) error {
} }
// RoverInventory returns the inventory of a requested rover // RoverInventory returns the inventory of a requested rover
func (w *World) RoverInventory(rover string) ([]objects.Object, error) { func (w *World) RoverInventory(rover string) ([]atlas.Object, error) {
w.worldMutex.RLock() w.worldMutex.RLock()
defer w.worldMutex.RUnlock() defer w.worldMutex.RUnlock()
@ -257,7 +252,7 @@ func (w *World) RoverInventory(rover string) ([]objects.Object, error) {
} }
// WarpRover sets an rovers position // WarpRover sets an rovers position
func (w *World) WarpRover(rover string, pos vector.Vector) error { func (w *World) WarpRover(rover string, pos maths.Vector) error {
w.worldMutex.Lock() w.worldMutex.Lock()
defer w.worldMutex.Unlock() defer w.worldMutex.Unlock()
@ -282,13 +277,13 @@ func (w *World) WarpRover(rover string, pos vector.Vector) error {
} }
// MoveRover attempts to move a rover in a specific direction // MoveRover attempts to move a rover in a specific direction
func (w *World) MoveRover(rover string, b bearing.Bearing) (vector.Vector, error) { func (w *World) MoveRover(rover string, b maths.Bearing) (maths.Vector, error) {
w.worldMutex.Lock() w.worldMutex.Lock()
defer w.worldMutex.Unlock() defer w.worldMutex.Unlock()
i, ok := w.Rovers[rover] i, ok := w.Rovers[rover]
if !ok { if !ok {
return vector.Vector{}, fmt.Errorf("no rover matching id") return maths.Vector{}, fmt.Errorf("no rover matching id")
} }
// Ensure the rover has energy // Ensure the rover has energy
@ -323,35 +318,35 @@ func (w *World) MoveRover(rover string, b bearing.Bearing) (vector.Vector, error
} }
// RoverStash will stash an item at the current rovers position // RoverStash will stash an item at the current rovers position
func (w *World) RoverStash(rover string) (objects.Type, error) { func (w *World) RoverStash(rover string) (atlas.Type, error) {
w.worldMutex.Lock() w.worldMutex.Lock()
defer w.worldMutex.Unlock() defer w.worldMutex.Unlock()
r, ok := w.Rovers[rover] r, ok := w.Rovers[rover]
if !ok { if !ok {
return objects.None, fmt.Errorf("no rover matching id") return atlas.ObjectNone, fmt.Errorf("no rover matching id")
} }
// Can't pick up when full // Can't pick up when full
if len(r.Inventory) >= r.Capacity { if len(r.Inventory) >= r.Capacity {
return objects.None, nil return atlas.ObjectNone, nil
} }
// Ensure the rover has energy // Ensure the rover has energy
if r.Charge <= 0 { if r.Charge <= 0 {
return objects.None, nil return atlas.ObjectNone, nil
} }
r.Charge-- r.Charge--
_, obj := w.Atlas.QueryPosition(r.Pos) _, obj := w.Atlas.QueryPosition(r.Pos)
if !obj.IsStashable() { if !obj.IsStashable() {
return objects.None, nil return atlas.ObjectNone, nil
} }
r.AddLogEntryf("stashed %c", obj.Type) r.AddLogEntryf("stashed %c", obj.Type)
r.Inventory = append(r.Inventory, obj) r.Inventory = append(r.Inventory, obj)
w.Rovers[rover] = r w.Rovers[rover] = r
w.Atlas.SetObject(r.Pos, objects.Object{Type: objects.None}) w.Atlas.SetObject(r.Pos, atlas.Object{Type: atlas.ObjectNone})
return obj.Type, nil return obj.Type, nil
} }
@ -371,11 +366,11 @@ func (w *World) RadarFromRover(rover string) (radar []byte, objs []byte, err err
roverPos := r.Pos roverPos := r.Pos
// Get the radar min and max values // Get the radar min and max values
radarMin := vector.Vector{ radarMin := maths.Vector{
X: roverPos.X - r.Range, X: roverPos.X - r.Range,
Y: roverPos.Y - r.Range, Y: roverPos.Y - r.Range,
} }
radarMax := vector.Vector{ radarMax := maths.Vector{
X: roverPos.X + r.Range, X: roverPos.X + r.Range,
Y: roverPos.Y + r.Range, Y: roverPos.Y + r.Range,
} }
@ -385,7 +380,7 @@ func (w *World) RadarFromRover(rover string) (radar []byte, objs []byte, err err
objs = make([]byte, radarSpan*radarSpan) objs = make([]byte, radarSpan*radarSpan)
for j := radarMin.Y; j <= radarMax.Y; j++ { for j := radarMin.Y; j <= radarMax.Y; j++ {
for i := radarMin.X; i <= radarMax.X; i++ { for i := radarMin.X; i <= radarMax.X; i++ {
q := vector.Vector{X: i, Y: j} q := maths.Vector{X: i, Y: j}
tile, obj := w.Atlas.QueryPosition(q) tile, obj := w.Atlas.QueryPosition(q)
@ -406,7 +401,7 @@ func (w *World) RadarFromRover(rover string) (radar []byte, objs []byte, err err
if dist.X <= r.Range && dist.Y <= r.Range { if dist.X <= r.Range && dist.Y <= r.Range {
relative := r.Pos.Added(radarMin.Negated()) relative := r.Pos.Added(radarMin.Negated())
index := relative.X + relative.Y*radarSpan index := relative.X + relative.Y*radarSpan
objs[index] = byte(objects.Rover) objs[index] = byte(atlas.ObjectRover)
} }
} }
@ -430,11 +425,11 @@ func (w *World) Enqueue(rover string, commands ...Command) error {
// First validate the commands // First validate the commands
for _, c := range commands { for _, c := range commands {
switch c.Command { switch c.Command {
case rove.CommandType_move: case roveapi.CommandType_move:
if _, err := bearing.FromString(c.Bearing); err != nil { if _, err := maths.FromString(c.Bearing); err != nil {
return fmt.Errorf("unknown bearing: %s", c.Bearing) return fmt.Errorf("unknown bearing: %s", c.Bearing)
} }
case rove.CommandType_broadcast: case roveapi.CommandType_broadcast:
if len(c.Message) > 3 { if len(c.Message) > 3 {
return fmt.Errorf("too many characters in message (limit 3): %d", len(c.Message)) return fmt.Errorf("too many characters in message (limit 3): %d", len(c.Message))
} }
@ -443,9 +438,9 @@ func (w *World) Enqueue(rover string, commands ...Command) error {
return fmt.Errorf("invalid message character: %c", b) return fmt.Errorf("invalid message character: %c", b)
} }
} }
case rove.CommandType_stash: case roveapi.CommandType_stash:
case rove.CommandType_repair: case roveapi.CommandType_repair:
case rove.CommandType_recharge: case roveapi.CommandType_recharge:
// Nothing to verify // Nothing to verify
default: default:
return fmt.Errorf("unknown command: %s", c.Command) return fmt.Errorf("unknown command: %s", c.Command)
@ -509,19 +504,19 @@ func (w *World) ExecuteCommand(c *Command, rover string) (err error) {
log.Printf("Executing command: %+v for %s\n", *c, rover) log.Printf("Executing command: %+v for %s\n", *c, rover)
switch c.Command { switch c.Command {
case rove.CommandType_move: case roveapi.CommandType_move:
if dir, err := bearing.FromString(c.Bearing); err != nil { if dir, err := maths.FromString(c.Bearing); err != nil {
return err return err
} else if _, err := w.MoveRover(rover, dir); err != nil { } else if _, err := w.MoveRover(rover, dir); err != nil {
return err return err
} }
case rove.CommandType_stash: case roveapi.CommandType_stash:
if _, err := w.RoverStash(rover); err != nil { if _, err := w.RoverStash(rover); err != nil {
return err return err
} }
case rove.CommandType_repair: case roveapi.CommandType_repair:
r, err := w.GetRover(rover) r, err := w.GetRover(rover)
if err != nil { if err != nil {
return err return err
@ -533,12 +528,12 @@ func (w *World) ExecuteCommand(c *Command, rover string) (err error) {
r.AddLogEntryf("repaired self to %d", r.Integrity) r.AddLogEntryf("repaired self to %d", r.Integrity)
w.Rovers[rover] = r w.Rovers[rover] = r
} }
case rove.CommandType_recharge: case roveapi.CommandType_recharge:
_, err := w.RoverRecharge(rover) _, err := w.RoverRecharge(rover)
if err != nil { if err != nil {
return err return err
} }
case rove.CommandType_broadcast: case roveapi.CommandType_broadcast:
if err := w.RoverBroadcast(rover, c.Message); err != nil { if err := w.RoverBroadcast(rover, c.Message); err != nil {
return err return err
} }

View file

@ -1,13 +1,11 @@
package game package rove
import ( import (
"testing" "testing"
"github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/atlas"
"github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/maths"
"github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/proto/roveapi"
"github.com/mdiluz/rove/pkg/rove"
"github.com/mdiluz/rove/pkg/vector"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
) )
@ -68,7 +66,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) {
a, err := world.SpawnRover() a, err := world.SpawnRover()
assert.NoError(t, err) assert.NoError(t, err)
pos := vector.Vector{ pos := maths.Vector{
X: 0.0, X: 0.0,
Y: 0.0, Y: 0.0,
} }
@ -80,10 +78,10 @@ func TestWorld_GetSetMovePosition(t *testing.T) {
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
assert.Equal(t, pos, newPos, "Failed to correctly set position for rover") assert.Equal(t, pos, newPos, "Failed to correctly set position for rover")
b := bearing.North b := maths.North
newPos, err = world.MoveRover(a, b) newPos, err = world.MoveRover(a, b)
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
pos.Add(vector.Vector{X: 0, Y: 1}) pos.Add(maths.Vector{X: 0, Y: 1})
assert.Equal(t, pos, newPos, "Failed to correctly move position for rover") assert.Equal(t, pos, newPos, "Failed to correctly move position for rover")
rover, err := world.GetRover(a) rover, err := world.GetRover(a)
@ -92,7 +90,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) {
assert.Contains(t, rover.Logs[len(rover.Logs)-1].Text, "moved", "Rover logs should contain the move") assert.Contains(t, rover.Logs[len(rover.Logs)-1].Text, "moved", "Rover logs should contain the move")
// Place a tile in front of the rover // Place a tile in front of the rover
world.Atlas.SetObject(vector.Vector{X: 0, Y: 2}, objects.Object{Type: objects.LargeRock}) world.Atlas.SetObject(maths.Vector{X: 0, Y: 2}, atlas.Object{Type: atlas.ObjectLargeRock})
newPos, err = world.MoveRover(a, b) newPos, err = world.MoveRover(a, b)
assert.NoError(t, err, "Failed to move rover") assert.NoError(t, err, "Failed to move rover")
assert.Equal(t, pos, newPos, "Failed to correctly not move position for rover into wall") assert.Equal(t, pos, newPos, "Failed to correctly not move position for rover into wall")
@ -111,9 +109,9 @@ func TestWorld_RadarFromRover(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Warp the rovers into position // Warp the rovers into position
bpos := vector.Vector{X: -3, Y: -3} bpos := maths.Vector{X: -3, Y: -3}
assert.NoError(t, world.WarpRover(b, bpos), "Failed to warp rover") assert.NoError(t, world.WarpRover(b, bpos), "Failed to warp rover")
assert.NoError(t, world.WarpRover(a, vector.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")
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")
@ -122,8 +120,8 @@ func TestWorld_RadarFromRover(t *testing.T) {
assert.Equal(t, fullRange*fullRange, len(objs), "Radar returned wrong length") assert.Equal(t, fullRange*fullRange, len(objs), "Radar returned wrong length")
// Test the expected values // Test the expected values
assert.Equal(t, byte(objects.Rover), objs[1+fullRange]) assert.Equal(t, byte(atlas.ObjectRover), objs[1+fullRange])
assert.Equal(t, byte(objects.Rover), objs[4+4*fullRange]) assert.Equal(t, byte(atlas.ObjectRover), 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)
@ -139,11 +137,12 @@ func TestWorld_RoverStash(t *testing.T) {
a, err := world.SpawnRover() a, err := world.SpawnRover()
assert.NoError(t, err) assert.NoError(t, err)
pos := vector.Vector{ pos := maths.Vector{
X: 0.0, X: 0.0,
Y: 0.0, Y: 0.0,
} }
world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectNone})
err = world.WarpRover(a, pos) err = world.WarpRover(a, pos)
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
@ -155,22 +154,22 @@ func TestWorld_RoverStash(t *testing.T) {
for i := 0; i < rover.Capacity; i++ { for i := 0; i < rover.Capacity; i++ {
// Place an object // Place an object
world.Atlas.SetObject(pos, objects.Object{Type: objects.SmallRock}) world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectSmallRock})
// Pick it up // Pick it up
o, err := world.RoverStash(a) o, err := world.RoverStash(a)
assert.NoError(t, err, "Failed to stash") assert.NoError(t, err, "Failed to stash")
assert.Equal(t, objects.SmallRock, o, "Failed to get correct object") assert.Equal(t, atlas.ObjectSmallRock, o, "Failed to get correct object")
// Check it's gone // Check it's gone
_, obj := world.Atlas.QueryPosition(pos) _, obj := world.Atlas.QueryPosition(pos)
assert.Equal(t, objects.None, obj.Type, "Stash failed to remove object from atlas") assert.Equal(t, atlas.ObjectNone, obj.Type, "Stash failed to remove object from atlas")
// Check we have it // Check we have it
inv, err := world.RoverInventory(a) inv, err := world.RoverInventory(a)
assert.NoError(t, err, "Failed to get inventory") assert.NoError(t, err, "Failed to get inventory")
assert.Equal(t, i+1, len(inv)) assert.Equal(t, i+1, len(inv))
assert.Equal(t, objects.Object{Type: objects.SmallRock}, inv[i]) assert.Equal(t, atlas.Object{Type: atlas.ObjectSmallRock}, inv[i])
// Check that this did reduce the charge // Check that this did reduce the charge
info, err := world.GetRover(a) info, err := world.GetRover(a)
@ -187,16 +186,16 @@ func TestWorld_RoverStash(t *testing.T) {
} }
// Place an object // Place an object
world.Atlas.SetObject(pos, objects.Object{Type: objects.SmallRock}) world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectSmallRock})
// Try to pick it up // Try to pick it up
o, err := world.RoverStash(a) o, err := world.RoverStash(a)
assert.NoError(t, err, "Failed to stash") assert.NoError(t, err, "Failed to stash")
assert.Equal(t, objects.None, o, "Failed to get correct object") assert.Equal(t, atlas.ObjectNone, o, "Failed to get correct object")
// Check it's still there // Check it's still there
_, obj := world.Atlas.QueryPosition(pos) _, obj := world.Atlas.QueryPosition(pos)
assert.Equal(t, objects.SmallRock, obj.Type, "Stash failed to remove object from atlas") assert.Equal(t, atlas.ObjectSmallRock, obj.Type, "Stash failed to remove object from atlas")
// Check we don't have it // Check we don't have it
inv, err := world.RoverInventory(a) inv, err := world.RoverInventory(a)
@ -214,7 +213,7 @@ func TestWorld_RoverDamage(t *testing.T) {
a, err := world.SpawnRover() a, err := world.SpawnRover()
assert.NoError(t, err) assert.NoError(t, err)
pos := vector.Vector{ pos := maths.Vector{
X: 0.0, X: 0.0,
Y: 0.0, Y: 0.0,
} }
@ -225,9 +224,9 @@ func TestWorld_RoverDamage(t *testing.T) {
info, err := world.GetRover(a) info, err := world.GetRover(a)
assert.NoError(t, err, "couldn't get rover info") assert.NoError(t, err, "couldn't get rover info")
world.Atlas.SetObject(vector.Vector{X: 0.0, Y: 1.0}, objects.Object{Type: objects.LargeRock}) world.Atlas.SetObject(maths.Vector{X: 0.0, Y: 1.0}, atlas.Object{Type: atlas.ObjectLargeRock})
vec, err := world.MoveRover(a, bearing.North) vec, err := world.MoveRover(a, maths.North)
assert.NoError(t, err, "Failed to move rover") assert.NoError(t, err, "Failed to move rover")
assert.Equal(t, pos, vec, "Rover managed to move into large rock") assert.Equal(t, pos, vec, "Rover managed to move into large rock")
@ -242,13 +241,13 @@ func TestWorld_RoverRepair(t *testing.T) {
a, err := world.SpawnRover() a, err := world.SpawnRover()
assert.NoError(t, err) assert.NoError(t, err)
pos := vector.Vector{ pos := maths.Vector{
X: 0.0, X: 0.0,
Y: 0.0, Y: 0.0,
} }
world.Atlas.SetTile(pos, atlas.TileNone) world.Atlas.SetTile(pos, atlas.TileNone)
world.Atlas.SetObject(pos, objects.Object{Type: objects.None}) world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectNone})
err = world.WarpRover(a, pos) err = world.WarpRover(a, pos)
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
@ -257,15 +256,15 @@ func TestWorld_RoverRepair(t *testing.T) {
assert.NoError(t, err, "couldn't get rover info") assert.NoError(t, err, "couldn't get rover info")
// Pick up something to repair with // Pick up something to repair with
world.Atlas.SetObject(pos, objects.Object{Type: objects.SmallRock}) world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectSmallRock})
o, err := world.RoverStash(a) o, err := world.RoverStash(a)
assert.NoError(t, err, "Failed to stash") assert.NoError(t, err, "Failed to stash")
assert.Equal(t, objects.SmallRock, o, "Failed to get correct object") assert.Equal(t, atlas.ObjectSmallRock, o, "Failed to get correct object")
world.Atlas.SetObject(vector.Vector{X: 0.0, Y: 1.0}, objects.Object{Type: objects.LargeRock}) world.Atlas.SetObject(maths.Vector{X: 0.0, Y: 1.0}, atlas.Object{Type: atlas.ObjectLargeRock})
// Try and bump into the rock // Try and bump into the rock
vec, err := world.MoveRover(a, bearing.North) vec, err := world.MoveRover(a, maths.North)
assert.NoError(t, err, "Failed to move rover") assert.NoError(t, err, "Failed to move rover")
assert.Equal(t, pos, vec, "Rover managed to move into large rock") assert.Equal(t, pos, vec, "Rover managed to move into large rock")
@ -273,7 +272,7 @@ func TestWorld_RoverRepair(t *testing.T) {
assert.NoError(t, err, "couldn't get rover info") assert.NoError(t, err, "couldn't get rover info")
assert.Equal(t, originalInfo.Integrity-1, newinfo.Integrity, "rover should have lost integrity") assert.Equal(t, originalInfo.Integrity-1, newinfo.Integrity, "rover should have lost integrity")
err = world.ExecuteCommand(&Command{Command: rove.CommandType_repair}, a) err = world.ExecuteCommand(&Command{Command: roveapi.CommandType_repair}, a)
assert.NoError(t, err, "Failed to repair rover") assert.NoError(t, err, "Failed to repair rover")
newinfo, err = world.GetRover(a) newinfo, err = world.GetRover(a)
@ -282,12 +281,12 @@ func TestWorld_RoverRepair(t *testing.T) {
assert.Contains(t, newinfo.Logs[len(newinfo.Logs)-1].Text, "repair", "Rover logs should contain the repair") 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 // Check again that it can't repair past the max
world.Atlas.SetObject(pos, objects.Object{Type: objects.SmallRock}) world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectSmallRock})
o, err = world.RoverStash(a) o, err = world.RoverStash(a)
assert.NoError(t, err, "Failed to stash") assert.NoError(t, err, "Failed to stash")
assert.Equal(t, objects.SmallRock, o, "Failed to get correct object") assert.Equal(t, atlas.ObjectSmallRock, o, "Failed to get correct object")
err = world.ExecuteCommand(&Command{Command: rove.CommandType_repair}, a) err = world.ExecuteCommand(&Command{Command: roveapi.CommandType_repair}, a)
assert.NoError(t, err, "Failed to repair rover") assert.NoError(t, err, "Failed to repair rover")
newinfo, err = world.GetRover(a) newinfo, err = world.GetRover(a)
@ -312,13 +311,13 @@ func TestWorld_Charge(t *testing.T) {
assert.NoError(t, err, "Failed to get position for rover") assert.NoError(t, err, "Failed to get position for rover")
// Ensure the path ahead is empty // Ensure the path ahead is empty
world.Atlas.SetTile(initialPos.Added(bearing.North.Vector()), atlas.TileRock) world.Atlas.SetTile(initialPos.Added(maths.North.Vector()), atlas.TileRock)
world.Atlas.SetObject(initialPos.Added(bearing.North.Vector()), objects.Object{Type: objects.None}) world.Atlas.SetObject(initialPos.Added(maths.North.Vector()), atlas.Object{Type: atlas.ObjectNone})
// Try and move north (along unblocked path) // Try and move north (along unblocked path)
newPos, err := world.MoveRover(a, bearing.North) newPos, err := world.MoveRover(a, maths.North)
assert.NoError(t, err, "Failed to set position for rover") assert.NoError(t, err, "Failed to set position for rover")
assert.Equal(t, initialPos.Added(bearing.North.Vector()), newPos, "Failed to correctly move position for rover") assert.Equal(t, initialPos.Added(maths.North.Vector()), newPos, "Failed to correctly move position for rover")
// Ensure rover lost charge // Ensure rover lost charge
rover, err := world.GetRover(a) rover, err := world.GetRover(a)
@ -377,8 +376,8 @@ func TestWorld_Broadcast(t *testing.T) {
assert.NoError(t, err) assert.NoError(t, err)
// Warp rovers near to eachother // Warp rovers near to eachother
assert.NoError(t, world.WarpRover(a, vector.Vector{X: 0, Y: 0})) assert.NoError(t, world.WarpRover(a, maths.Vector{X: 0, Y: 0}))
assert.NoError(t, world.WarpRover(b, vector.Vector{X: 1, Y: 0})) assert.NoError(t, world.WarpRover(b, maths.Vector{X: 1, Y: 0}))
// Broadcast from a // Broadcast from a
assert.NoError(t, world.RoverBroadcast(a, []byte{'A', 'B', 'C'})) assert.NoError(t, world.RoverBroadcast(a, []byte{'A', 'B', 'C'}))
@ -395,7 +394,8 @@ func TestWorld_Broadcast(t *testing.T) {
assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "ABC", "Rover A should have logged it's broadcast") assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "ABC", "Rover A should have logged it's broadcast")
// Warp B outside of the range of A // Warp B outside of the range of A
assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range, Y: 0})) world.Atlas.SetObject(maths.Vector{X: ra.Range, Y: 0}, atlas.Object{Type: atlas.ObjectNone})
assert.NoError(t, world.WarpRover(b, maths.Vector{X: ra.Range, Y: 0}))
// Broadcast from a again // Broadcast from a again
assert.NoError(t, world.RoverBroadcast(a, []byte{'X', 'Y', 'Z'})) assert.NoError(t, world.RoverBroadcast(a, []byte{'X', 'Y', 'Z'}))
@ -411,7 +411,8 @@ func TestWorld_Broadcast(t *testing.T) {
assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "XYZ", "Rover A should have logged it's broadcast") assert.Contains(t, rb.Logs[len(rb.Logs)-1].Text, "XYZ", "Rover A should have logged it's broadcast")
// Warp B outside of the range of A // Warp B outside of the range of A
assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range + 1, Y: 0})) world.Atlas.SetObject(maths.Vector{X: ra.Range + 1, Y: 0}, atlas.Object{Type: atlas.ObjectNone})
assert.NoError(t, world.WarpRover(b, maths.Vector{X: ra.Range + 1, Y: 0}))
// Broadcast from a again // Broadcast from a again
assert.NoError(t, world.RoverBroadcast(a, []byte{'H', 'J', 'K'})) assert.NoError(t, world.RoverBroadcast(a, []byte{'H', 'J', 'K'}))

View file

@ -1,23 +0,0 @@
Google APIs
============
Project: Google APIs
URL: https://github.com/google/googleapis
Revision: 3544ab16c3342d790b00764251e348705991ea4b
License: Apache License 2.0
Imported Files
---------------
- google/api/annotations.proto
- google/api/http.proto
- google/api/httpbody.proto
Generated Files
----------------
They are generated from the .proto files by protoc-gen-go.
- google/api/annotations.pb.go
- google/api/http.pb.go

View file

@ -1,31 +0,0 @@
// Copyright (c) 2015, Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.api;
import "google/api/http.proto";
import "google/protobuf/descriptor.proto";
option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
option java_multiple_files = true;
option java_outer_classname = "AnnotationsProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";
extend google.protobuf.MethodOptions {
// See `HttpRule`.
HttpRule http = 72295728;
}

View file

@ -1,318 +0,0 @@
// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.api;
option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/api/annotations;annotations";
option java_multiple_files = true;
option java_outer_classname = "HttpProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";
// Defines the HTTP configuration for an API service. It contains a list of
// [HttpRule][google.api.HttpRule], each specifying the mapping of an RPC method
// to one or more HTTP REST API methods.
message Http {
// A list of HTTP configuration rules that apply to individual API methods.
//
// **NOTE:** All service configuration rules follow "last one wins" order.
repeated HttpRule rules = 1;
// When set to true, URL path parmeters will be fully URI-decoded except in
// cases of single segment matches in reserved expansion, where "%2F" will be
// left encoded.
//
// The default behavior is to not decode RFC 6570 reserved characters in multi
// segment matches.
bool fully_decode_reserved_expansion = 2;
}
// `HttpRule` defines the mapping of an RPC method to one or more HTTP
// REST API methods. The mapping specifies how different portions of the RPC
// request message are mapped to URL path, URL query parameters, and
// HTTP request body. The mapping is typically specified as an
// `google.api.http` annotation on the RPC method,
// see "google/api/annotations.proto" for details.
//
// The mapping consists of a field specifying the path template and
// method kind. The path template can refer to fields in the request
// message, as in the example below which describes a REST GET
// operation on a resource collection of messages:
//
//
// service Messaging {
// rpc GetMessage(GetMessageRequest) returns (Message) {
// option (google.api.http).get = "/v1/messages/{message_id}/{sub.subfield}";
// }
// }
// message GetMessageRequest {
// message SubMessage {
// string subfield = 1;
// }
// string message_id = 1; // mapped to the URL
// SubMessage sub = 2; // `sub.subfield` is url-mapped
// }
// message Message {
// string text = 1; // content of the resource
// }
//
// The same http annotation can alternatively be expressed inside the
// `GRPC API Configuration` YAML file.
//
// http:
// rules:
// - selector: <proto_package_name>.Messaging.GetMessage
// get: /v1/messages/{message_id}/{sub.subfield}
//
// This definition enables an automatic, bidrectional mapping of HTTP
// JSON to RPC. Example:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456/foo` | `GetMessage(message_id: "123456" sub: SubMessage(subfield: "foo"))`
//
// In general, not only fields but also field paths can be referenced
// from a path pattern. Fields mapped to the path pattern cannot be
// repeated and must have a primitive (non-message) type.
//
// Any fields in the request message which are not bound by the path
// pattern automatically become (optional) HTTP query
// parameters. Assume the following definition of the request message:
//
//
// service Messaging {
// rpc GetMessage(GetMessageRequest) returns (Message) {
// option (google.api.http).get = "/v1/messages/{message_id}";
// }
// }
// message GetMessageRequest {
// message SubMessage {
// string subfield = 1;
// }
// string message_id = 1; // mapped to the URL
// int64 revision = 2; // becomes a parameter
// SubMessage sub = 3; // `sub.subfield` becomes a parameter
// }
//
//
// This enables a HTTP JSON to RPC mapping as below:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456?revision=2&sub.subfield=foo` | `GetMessage(message_id: "123456" revision: 2 sub: SubMessage(subfield: "foo"))`
//
// Note that fields which are mapped to HTTP parameters must have a
// primitive type or a repeated primitive type. Message types are not
// allowed. In the case of a repeated type, the parameter can be
// repeated in the URL, as in `...?param=A&param=B`.
//
// For HTTP method kinds which allow a request body, the `body` field
// specifies the mapping. Consider a REST update method on the
// message resource collection:
//
//
// service Messaging {
// rpc UpdateMessage(UpdateMessageRequest) returns (Message) {
// option (google.api.http) = {
// put: "/v1/messages/{message_id}"
// body: "message"
// };
// }
// }
// message UpdateMessageRequest {
// string message_id = 1; // mapped to the URL
// Message message = 2; // mapped to the body
// }
//
//
// The following HTTP JSON to RPC mapping is enabled, where the
// representation of the JSON in the request body is determined by
// protos JSON encoding:
//
// HTTP | RPC
// -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" message { text: "Hi!" })`
//
// The special name `*` can be used in the body mapping to define that
// every field not bound by the path template should be mapped to the
// request body. This enables the following alternative definition of
// the update method:
//
// service Messaging {
// rpc UpdateMessage(Message) returns (Message) {
// option (google.api.http) = {
// put: "/v1/messages/{message_id}"
// body: "*"
// };
// }
// }
// message Message {
// string message_id = 1;
// string text = 2;
// }
//
//
// The following HTTP JSON to RPC mapping is enabled:
//
// HTTP | RPC
// -----|-----
// `PUT /v1/messages/123456 { "text": "Hi!" }` | `UpdateMessage(message_id: "123456" text: "Hi!")`
//
// Note that when using `*` in the body mapping, it is not possible to
// have HTTP parameters, as all fields not bound by the path end in
// the body. This makes this option more rarely used in practice of
// defining REST APIs. The common usage of `*` is in custom methods
// which don't use the URL at all for transferring data.
//
// It is possible to define multiple HTTP methods for one RPC by using
// the `additional_bindings` option. Example:
//
// service Messaging {
// rpc GetMessage(GetMessageRequest) returns (Message) {
// option (google.api.http) = {
// get: "/v1/messages/{message_id}"
// additional_bindings {
// get: "/v1/users/{user_id}/messages/{message_id}"
// }
// };
// }
// }
// message GetMessageRequest {
// string message_id = 1;
// string user_id = 2;
// }
//
//
// This enables the following two alternative HTTP JSON to RPC
// mappings:
//
// HTTP | RPC
// -----|-----
// `GET /v1/messages/123456` | `GetMessage(message_id: "123456")`
// `GET /v1/users/me/messages/123456` | `GetMessage(user_id: "me" message_id: "123456")`
//
// # Rules for HTTP mapping
//
// The rules for mapping HTTP path, query parameters, and body fields
// to the request message are as follows:
//
// 1. The `body` field specifies either `*` or a field path, or is
// omitted. If omitted, it indicates there is no HTTP request body.
// 2. Leaf fields (recursive expansion of nested messages in the
// request) can be classified into three types:
// (a) Matched in the URL template.
// (b) Covered by body (if body is `*`, everything except (a) fields;
// else everything under the body field)
// (c) All other fields.
// 3. URL query parameters found in the HTTP request are mapped to (c) fields.
// 4. Any body sent with an HTTP request can contain only (b) fields.
//
// The syntax of the path template is as follows:
//
// Template = "/" Segments [ Verb ] ;
// Segments = Segment { "/" Segment } ;
// Segment = "*" | "**" | LITERAL | Variable ;
// Variable = "{" FieldPath [ "=" Segments ] "}" ;
// FieldPath = IDENT { "." IDENT } ;
// Verb = ":" LITERAL ;
//
// The syntax `*` matches a single path segment. The syntax `**` matches zero
// or more path segments, which must be the last part of the path except the
// `Verb`. The syntax `LITERAL` matches literal text in the path.
//
// The syntax `Variable` matches part of the URL path as specified by its
// template. A variable template must not contain other variables. If a variable
// matches a single path segment, its template may be omitted, e.g. `{var}`
// is equivalent to `{var=*}`.
//
// If a variable contains exactly one path segment, such as `"{var}"` or
// `"{var=*}"`, when such a variable is expanded into a URL path, all characters
// except `[-_.~0-9a-zA-Z]` are percent-encoded. Such variables show up in the
// Discovery Document as `{var}`.
//
// If a variable contains one or more path segments, such as `"{var=foo/*}"`
// or `"{var=**}"`, when such a variable is expanded into a URL path, all
// characters except `[-_.~/0-9a-zA-Z]` are percent-encoded. Such variables
// show up in the Discovery Document as `{+var}`.
//
// NOTE: While the single segment variable matches the semantics of
// [RFC 6570](https://tools.ietf.org/html/rfc6570) Section 3.2.2
// Simple String Expansion, the multi segment variable **does not** match
// RFC 6570 Reserved Expansion. The reason is that the Reserved Expansion
// does not expand special characters like `?` and `#`, which would lead
// to invalid URLs.
//
// NOTE: the field paths in variables and in the `body` must not refer to
// repeated fields or map fields.
message HttpRule {
// Selects methods to which this rule applies.
//
// Refer to [selector][google.api.DocumentationRule.selector] for syntax details.
string selector = 1;
// Determines the URL pattern is matched by this rules. This pattern can be
// used with any of the {get|put|post|delete|patch} methods. A custom method
// can be defined using the 'custom' field.
oneof pattern {
// Used for listing and getting information about resources.
string get = 2;
// Used for updating a resource.
string put = 3;
// Used for creating a resource.
string post = 4;
// Used for deleting a resource.
string delete = 5;
// Used for updating a resource.
string patch = 6;
// The custom pattern is used for specifying an HTTP method that is not
// included in the `pattern` field, such as HEAD, or "*" to leave the
// HTTP method unspecified for this rule. The wild-card rule is useful
// for services that provide content to Web (HTML) clients.
CustomHttpPattern custom = 8;
}
// The name of the request field whose value is mapped to the HTTP body, or
// `*` for mapping all fields not captured by the path pattern to the HTTP
// body. NOTE: the referred field must not be a repeated field and must be
// present at the top-level of request message type.
string body = 7;
// Optional. The name of the response field whose value is mapped to the HTTP
// body of response. Other response fields are ignored. When
// not set, the response message will be used as HTTP body of response.
string response_body = 12;
// Additional HTTP bindings for the selector. Nested bindings must
// not contain an `additional_bindings` field themselves (that is,
// the nesting may only be one level deep).
repeated HttpRule additional_bindings = 11;
}
// A custom pattern is used for defining custom HTTP verb.
message CustomHttpPattern {
// The name of this custom HTTP verb.
string kind = 1;
// The path matched by this custom verb.
string path = 2;
}

View file

@ -1,78 +0,0 @@
// Copyright 2018 Google LLC.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
syntax = "proto3";
package google.api;
import "google/protobuf/any.proto";
option cc_enable_arenas = true;
option go_package = "google.golang.org/genproto/googleapis/api/httpbody;httpbody";
option java_multiple_files = true;
option java_outer_classname = "HttpBodyProto";
option java_package = "com.google.api";
option objc_class_prefix = "GAPI";
// Message that represents an arbitrary HTTP body. It should only be used for
// payload formats that can't be represented as JSON, such as raw binary or
// an HTML page.
//
//
// This message can be used both in streaming and non-streaming API methods in
// the request as well as the response.
//
// It can be used as a top-level request field, which is convenient if one
// wants to extract parameters from either the URL or HTTP template into the
// request fields and also want access to the raw HTTP body.
//
// Example:
//
// message GetResourceRequest {
// // A unique request id.
// string request_id = 1;
//
// // The raw HTTP body is bound to this field.
// google.api.HttpBody http_body = 2;
// }
//
// service ResourceService {
// rpc GetResource(GetResourceRequest) returns (google.api.HttpBody);
// rpc UpdateResource(google.api.HttpBody) returns
// (google.protobuf.Empty);
// }
//
// Example with streaming methods:
//
// service CaldavService {
// rpc GetCalendar(stream google.api.HttpBody)
// returns (stream google.api.HttpBody);
// rpc UpdateCalendar(stream google.api.HttpBody)
// returns (stream google.api.HttpBody);
// }
//
// Use of this type only changes how the request and response bodies are
// handled, all other features will continue to work unchanged.
message HttpBody {
// The HTTP Content-Type header value specifying the content type of the body.
string content_type = 1;
// The HTTP request/response body as raw binary.
bytes data = 2;
// Application specific response metadata. Must be set in the first response
// for streaming APIs.
repeated google.protobuf.Any extensions = 3;
}

View file

@ -1,186 +0,0 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.rpc;
option go_package = "google.golang.org/genproto/googleapis/rpc/code;code";
option java_multiple_files = true;
option java_outer_classname = "CodeProto";
option java_package = "com.google.rpc";
option objc_class_prefix = "RPC";
// The canonical error codes for Google APIs.
//
//
// Sometimes multiple error codes may apply. Services should return
// the most specific error code that applies. For example, prefer
// `OUT_OF_RANGE` over `FAILED_PRECONDITION` if both codes apply.
// Similarly prefer `NOT_FOUND` or `ALREADY_EXISTS` over `FAILED_PRECONDITION`.
enum Code {
// Not an error; returned on success
//
// HTTP Mapping: 200 OK
OK = 0;
// The operation was cancelled, typically by the caller.
//
// HTTP Mapping: 499 Client Closed Request
CANCELLED = 1;
// Unknown error. For example, this error may be returned when
// a `Status` value received from another address space belongs to
// an error space that is not known in this address space. Also
// errors raised by APIs that do not return enough error information
// may be converted to this error.
//
// HTTP Mapping: 500 Internal Server Error
UNKNOWN = 2;
// The client specified an invalid argument. Note that this differs
// from `FAILED_PRECONDITION`. `INVALID_ARGUMENT` indicates arguments
// that are problematic regardless of the state of the system
// (e.g., a malformed file name).
//
// HTTP Mapping: 400 Bad Request
INVALID_ARGUMENT = 3;
// The deadline expired before the operation could complete. For operations
// that change the state of the system, this error may be returned
// even if the operation has completed successfully. For example, a
// successful response from a server could have been delayed long
// enough for the deadline to expire.
//
// HTTP Mapping: 504 Gateway Timeout
DEADLINE_EXCEEDED = 4;
// Some requested entity (e.g., file or directory) was not found.
//
// Note to server developers: if a request is denied for an entire class
// of users, such as gradual feature rollout or undocumented whitelist,
// `NOT_FOUND` may be used. If a request is denied for some users within
// a class of users, such as user-based access control, `PERMISSION_DENIED`
// must be used.
//
// HTTP Mapping: 404 Not Found
NOT_FOUND = 5;
// The entity that a client attempted to create (e.g., file or directory)
// already exists.
//
// HTTP Mapping: 409 Conflict
ALREADY_EXISTS = 6;
// The caller does not have permission to execute the specified
// operation. `PERMISSION_DENIED` must not be used for rejections
// caused by exhausting some resource (use `RESOURCE_EXHAUSTED`
// instead for those errors). `PERMISSION_DENIED` must not be
// used if the caller can not be identified (use `UNAUTHENTICATED`
// instead for those errors). This error code does not imply the
// request is valid or the requested entity exists or satisfies
// other pre-conditions.
//
// HTTP Mapping: 403 Forbidden
PERMISSION_DENIED = 7;
// The request does not have valid authentication credentials for the
// operation.
//
// HTTP Mapping: 401 Unauthorized
UNAUTHENTICATED = 16;
// Some resource has been exhausted, perhaps a per-user quota, or
// perhaps the entire file system is out of space.
//
// HTTP Mapping: 429 Too Many Requests
RESOURCE_EXHAUSTED = 8;
// The operation was rejected because the system is not in a state
// required for the operation's execution. For example, the directory
// to be deleted is non-empty, an rmdir operation is applied to
// a non-directory, etc.
//
// Service implementors can use the following guidelines to decide
// between `FAILED_PRECONDITION`, `ABORTED`, and `UNAVAILABLE`:
// (a) Use `UNAVAILABLE` if the client can retry just the failing call.
// (b) Use `ABORTED` if the client should retry at a higher level
// (e.g., when a client-specified test-and-set fails, indicating the
// client should restart a read-modify-write sequence).
// (c) Use `FAILED_PRECONDITION` if the client should not retry until
// the system state has been explicitly fixed. E.g., if an "rmdir"
// fails because the directory is non-empty, `FAILED_PRECONDITION`
// should be returned since the client should not retry unless
// the files are deleted from the directory.
//
// HTTP Mapping: 400 Bad Request
FAILED_PRECONDITION = 9;
// The operation was aborted, typically due to a concurrency issue such as
// a sequencer check failure or transaction abort.
//
// See the guidelines above for deciding between `FAILED_PRECONDITION`,
// `ABORTED`, and `UNAVAILABLE`.
//
// HTTP Mapping: 409 Conflict
ABORTED = 10;
// The operation was attempted past the valid range. E.g., seeking or
// reading past end-of-file.
//
// Unlike `INVALID_ARGUMENT`, this error indicates a problem that may
// be fixed if the system state changes. For example, a 32-bit file
// system will generate `INVALID_ARGUMENT` if asked to read at an
// offset that is not in the range [0,2^32-1], but it will generate
// `OUT_OF_RANGE` if asked to read from an offset past the current
// file size.
//
// There is a fair bit of overlap between `FAILED_PRECONDITION` and
// `OUT_OF_RANGE`. We recommend using `OUT_OF_RANGE` (the more specific
// error) when it applies so that callers who are iterating through
// a space can easily look for an `OUT_OF_RANGE` error to detect when
// they are done.
//
// HTTP Mapping: 400 Bad Request
OUT_OF_RANGE = 11;
// The operation is not implemented or is not supported/enabled in this
// service.
//
// HTTP Mapping: 501 Not Implemented
UNIMPLEMENTED = 12;
// Internal errors. This means that some invariants expected by the
// underlying system have been broken. This error code is reserved
// for serious errors.
//
// HTTP Mapping: 500 Internal Server Error
INTERNAL = 13;
// The service is currently unavailable. This is most likely a
// transient condition, which can be corrected by retrying with
// a backoff.
//
// See the guidelines above for deciding between `FAILED_PRECONDITION`,
// `ABORTED`, and `UNAVAILABLE`.
//
// HTTP Mapping: 503 Service Unavailable
UNAVAILABLE = 14;
// Unrecoverable data loss or corruption.
//
// HTTP Mapping: 500 Internal Server Error
DATA_LOSS = 15;
}

View file

@ -1,200 +0,0 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.rpc;
import "google/protobuf/duration.proto";
option go_package = "google.golang.org/genproto/googleapis/rpc/errdetails;errdetails";
option java_multiple_files = true;
option java_outer_classname = "ErrorDetailsProto";
option java_package = "com.google.rpc";
option objc_class_prefix = "RPC";
// Describes when the clients can retry a failed request. Clients could ignore
// the recommendation here or retry when this information is missing from error
// responses.
//
// It's always recommended that clients should use exponential backoff when
// retrying.
//
// Clients should wait until `retry_delay` amount of time has passed since
// receiving the error response before retrying. If retrying requests also
// fail, clients should use an exponential backoff scheme to gradually increase
// the delay between retries based on `retry_delay`, until either a maximum
// number of retires have been reached or a maximum retry delay cap has been
// reached.
message RetryInfo {
// Clients should wait at least this long between retrying the same request.
google.protobuf.Duration retry_delay = 1;
}
// Describes additional debugging info.
message DebugInfo {
// The stack trace entries indicating where the error occurred.
repeated string stack_entries = 1;
// Additional debugging information provided by the server.
string detail = 2;
}
// Describes how a quota check failed.
//
// For example if a daily limit was exceeded for the calling project,
// a service could respond with a QuotaFailure detail containing the project
// id and the description of the quota limit that was exceeded. If the
// calling project hasn't enabled the service in the developer console, then
// a service could respond with the project id and set `service_disabled`
// to true.
//
// Also see RetryDetail and Help types for other details about handling a
// quota failure.
message QuotaFailure {
// A message type used to describe a single quota violation. For example, a
// daily quota or a custom quota that was exceeded.
message Violation {
// The subject on which the quota check failed.
// For example, "clientip:<ip address of client>" or "project:<Google
// developer project id>".
string subject = 1;
// A description of how the quota check failed. Clients can use this
// description to find more about the quota configuration in the service's
// public documentation, or find the relevant quota limit to adjust through
// developer console.
//
// For example: "Service disabled" or "Daily Limit for read operations
// exceeded".
string description = 2;
}
// Describes all quota violations.
repeated Violation violations = 1;
}
// Describes what preconditions have failed.
//
// For example, if an RPC failed because it required the Terms of Service to be
// acknowledged, it could list the terms of service violation in the
// PreconditionFailure message.
message PreconditionFailure {
// A message type used to describe a single precondition failure.
message Violation {
// The type of PreconditionFailure. We recommend using a service-specific
// enum type to define the supported precondition violation types. For
// example, "TOS" for "Terms of Service violation".
string type = 1;
// The subject, relative to the type, that failed.
// For example, "google.com/cloud" relative to the "TOS" type would
// indicate which terms of service is being referenced.
string subject = 2;
// A description of how the precondition failed. Developers can use this
// description to understand how to fix the failure.
//
// For example: "Terms of service not accepted".
string description = 3;
}
// Describes all precondition violations.
repeated Violation violations = 1;
}
// Describes violations in a client request. This error type focuses on the
// syntactic aspects of the request.
message BadRequest {
// A message type used to describe a single bad request field.
message FieldViolation {
// A path leading to a field in the request body. The value will be a
// sequence of dot-separated identifiers that identify a protocol buffer
// field. E.g., "field_violations.field" would identify this field.
string field = 1;
// A description of why the request element is bad.
string description = 2;
}
// Describes all violations in a client request.
repeated FieldViolation field_violations = 1;
}
// Contains metadata about the request that clients can attach when filing a bug
// or providing other forms of feedback.
message RequestInfo {
// An opaque string that should only be interpreted by the service generating
// it. For example, it can be used to identify requests in the service's logs.
string request_id = 1;
// Any data that was used to serve this request. For example, an encrypted
// stack trace that can be sent back to the service provider for debugging.
string serving_data = 2;
}
// Describes the resource that is being accessed.
message ResourceInfo {
// A name for the type of resource being accessed, e.g. "sql table",
// "cloud storage bucket", "file", "Google calendar"; or the type URL
// of the resource: e.g. "type.googleapis.com/google.pubsub.v1.Topic".
string resource_type = 1;
// The name of the resource being accessed. For example, a shared calendar
// name: "example.com_4fghdhgsrgh@group.calendar.google.com", if the current
// error is [google.rpc.Code.PERMISSION_DENIED][google.rpc.Code.PERMISSION_DENIED].
string resource_name = 2;
// The owner of the resource (optional).
// For example, "user:<owner email>" or "project:<Google developer project
// id>".
string owner = 3;
// Describes what error is encountered when accessing this resource.
// For example, updating a cloud project may require the `writer` permission
// on the developer console project.
string description = 4;
}
// Provides links to documentation or for performing an out of band action.
//
// For example, if a quota check failed with an error indicating the calling
// project hasn't enabled the accessed service, this can contain a URL pointing
// directly to the right place in the developer console to flip the bit.
message Help {
// Describes a URL link.
message Link {
// Describes what the link offers.
string description = 1;
// The URL of the link.
string url = 2;
}
// URL(s) pointing to additional information on handling the current error.
repeated Link links = 1;
}
// Provides a localized error message that is safe to return to the user
// which can be attached to an RPC error.
message LocalizedMessage {
// The locale used following the specification defined at
// http://www.rfc-editor.org/rfc/bcp/bcp47.txt.
// Examples are: "en-US", "fr-CH", "es-MX"
string locale = 1;
// The localized error message in the above locale.
string message = 2;
}

View file

@ -1,92 +0,0 @@
// Copyright 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
syntax = "proto3";
package google.rpc;
import "google/protobuf/any.proto";
option go_package = "google.golang.org/genproto/googleapis/rpc/status;status";
option java_multiple_files = true;
option java_outer_classname = "StatusProto";
option java_package = "com.google.rpc";
option objc_class_prefix = "RPC";
// The `Status` type defines a logical error model that is suitable for different
// programming environments, including REST APIs and RPC APIs. It is used by
// [gRPC](https://github.com/grpc). The error model is designed to be:
//
// - Simple to use and understand for most users
// - Flexible enough to meet unexpected needs
//
// # Overview
//
// The `Status` message contains three pieces of data: error code, error message,
// and error details. The error code should be an enum value of
// [google.rpc.Code][google.rpc.Code], but it may accept additional error codes if needed. The
// error message should be a developer-facing English message that helps
// developers *understand* and *resolve* the error. If a localized user-facing
// error message is needed, put the localized message in the error details or
// localize it in the client. The optional error details may contain arbitrary
// information about the error. There is a predefined set of error detail types
// in the package `google.rpc` that can be used for common error conditions.
//
// # Language mapping
//
// The `Status` message is the logical representation of the error model, but it
// is not necessarily the actual wire format. When the `Status` message is
// exposed in different client libraries and different wire protocols, it can be
// mapped differently. For example, it will likely be mapped to some exceptions
// in Java, but more likely mapped to some error codes in C.
//
// # Other uses
//
// The error model and the `Status` message can be used in a variety of
// environments, either with or without APIs, to provide a
// consistent developer experience across different environments.
//
// Example uses of this error model include:
//
// - Partial errors. If a service needs to return partial errors to the client,
// it may embed the `Status` in the normal response to indicate the partial
// errors.
//
// - Workflow errors. A typical workflow has multiple steps. Each step may
// have a `Status` message for error reporting.
//
// - Batch operations. If a client uses batch request and batch response, the
// `Status` message should be used directly inside batch response, one for
// each error sub-response.
//
// - Asynchronous operations. If an API call embeds asynchronous operation
// results in its response, the status of those operations should be
// represented directly using the `Status` message.
//
// - Logging. If some API errors are stored in logs, the message `Status` could
// be used directly after any stripping needed for security/privacy reasons.
message Status {
// The status code, which should be an enum value of [google.rpc.Code][google.rpc.Code].
int32 code = 1;
// A developer-facing error message, which should be in English. Any
// user-facing error message should be localized and sent in the
// [google.rpc.Status.details][google.rpc.Status.details] field, or localized by the client.
string message = 2;
// A list of messages that carry the error details. There is a common set of
// message types for APIs to use.
repeated google.protobuf.Any details = 3;
}

View file

@ -2,14 +2,14 @@
// versions: // versions:
// protoc-gen-go v1.25.0 // protoc-gen-go v1.25.0
// protoc v3.6.1 // protoc v3.6.1
// source: rove/rove.proto // source: roveapi/roveapi.proto
// Rove // Rove
// //
// Rove is an asychronous nomadic game about exploring a planet as part of a // Rove is an asychronous nomadic game about exploring a planet as part of a
// loose community // loose community
package rove package roveapi
import ( import (
context "context" context "context"
@ -82,11 +82,11 @@ func (x CommandType) String() string {
} }
func (CommandType) Descriptor() protoreflect.EnumDescriptor { func (CommandType) Descriptor() protoreflect.EnumDescriptor {
return file_rove_rove_proto_enumTypes[0].Descriptor() return file_roveapi_roveapi_proto_enumTypes[0].Descriptor()
} }
func (CommandType) Type() protoreflect.EnumType { func (CommandType) Type() protoreflect.EnumType {
return &file_rove_rove_proto_enumTypes[0] return &file_roveapi_roveapi_proto_enumTypes[0]
} }
func (x CommandType) Number() protoreflect.EnumNumber { func (x CommandType) Number() protoreflect.EnumNumber {
@ -95,7 +95,7 @@ func (x CommandType) Number() protoreflect.EnumNumber {
// Deprecated: Use CommandType.Descriptor instead. // Deprecated: Use CommandType.Descriptor instead.
func (CommandType) EnumDescriptor() ([]byte, []int) { func (CommandType) EnumDescriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{0} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{0}
} }
// ServerStatusRequest is an empty placeholder // ServerStatusRequest is an empty placeholder
@ -108,7 +108,7 @@ type ServerStatusRequest struct {
func (x *ServerStatusRequest) Reset() { func (x *ServerStatusRequest) Reset() {
*x = ServerStatusRequest{} *x = ServerStatusRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[0] mi := &file_roveapi_roveapi_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -121,7 +121,7 @@ func (x *ServerStatusRequest) String() string {
func (*ServerStatusRequest) ProtoMessage() {} func (*ServerStatusRequest) ProtoMessage() {}
func (x *ServerStatusRequest) ProtoReflect() protoreflect.Message { func (x *ServerStatusRequest) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[0] mi := &file_roveapi_roveapi_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -134,7 +134,7 @@ func (x *ServerStatusRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServerStatusRequest.ProtoReflect.Descriptor instead. // Deprecated: Use ServerStatusRequest.ProtoReflect.Descriptor instead.
func (*ServerStatusRequest) Descriptor() ([]byte, []int) { func (*ServerStatusRequest) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{0} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{0}
} }
// ServerStatusResponse is a response with useful server information // ServerStatusResponse is a response with useful server information
@ -158,7 +158,7 @@ type ServerStatusResponse struct {
func (x *ServerStatusResponse) Reset() { func (x *ServerStatusResponse) Reset() {
*x = ServerStatusResponse{} *x = ServerStatusResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[1] mi := &file_roveapi_roveapi_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -171,7 +171,7 @@ func (x *ServerStatusResponse) String() string {
func (*ServerStatusResponse) ProtoMessage() {} func (*ServerStatusResponse) ProtoMessage() {}
func (x *ServerStatusResponse) ProtoReflect() protoreflect.Message { func (x *ServerStatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[1] mi := &file_roveapi_roveapi_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -184,7 +184,7 @@ func (x *ServerStatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use ServerStatusResponse.ProtoReflect.Descriptor instead. // Deprecated: Use ServerStatusResponse.ProtoReflect.Descriptor instead.
func (*ServerStatusResponse) Descriptor() ([]byte, []int) { func (*ServerStatusResponse) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{1} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{1}
} }
func (x *ServerStatusResponse) GetVersion() string { func (x *ServerStatusResponse) GetVersion() string {
@ -235,7 +235,7 @@ type RegisterRequest struct {
func (x *RegisterRequest) Reset() { func (x *RegisterRequest) Reset() {
*x = RegisterRequest{} *x = RegisterRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[2] mi := &file_roveapi_roveapi_proto_msgTypes[2]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -248,7 +248,7 @@ func (x *RegisterRequest) String() string {
func (*RegisterRequest) ProtoMessage() {} func (*RegisterRequest) ProtoMessage() {}
func (x *RegisterRequest) ProtoReflect() protoreflect.Message { func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[2] mi := &file_roveapi_roveapi_proto_msgTypes[2]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -261,7 +261,7 @@ func (x *RegisterRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. // Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead.
func (*RegisterRequest) Descriptor() ([]byte, []int) { func (*RegisterRequest) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{2} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{2}
} }
func (x *RegisterRequest) GetName() string { func (x *RegisterRequest) GetName() string {
@ -286,7 +286,7 @@ type Account struct {
func (x *Account) Reset() { func (x *Account) Reset() {
*x = Account{} *x = Account{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[3] mi := &file_roveapi_roveapi_proto_msgTypes[3]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -299,7 +299,7 @@ func (x *Account) String() string {
func (*Account) ProtoMessage() {} func (*Account) ProtoMessage() {}
func (x *Account) ProtoReflect() protoreflect.Message { func (x *Account) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[3] mi := &file_roveapi_roveapi_proto_msgTypes[3]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -312,7 +312,7 @@ func (x *Account) ProtoReflect() protoreflect.Message {
// Deprecated: Use Account.ProtoReflect.Descriptor instead. // Deprecated: Use Account.ProtoReflect.Descriptor instead.
func (*Account) Descriptor() ([]byte, []int) { func (*Account) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{3} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{3}
} }
func (x *Account) GetName() string { func (x *Account) GetName() string {
@ -342,7 +342,7 @@ type RegisterResponse struct {
func (x *RegisterResponse) Reset() { func (x *RegisterResponse) Reset() {
*x = RegisterResponse{} *x = RegisterResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[4] mi := &file_roveapi_roveapi_proto_msgTypes[4]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -355,7 +355,7 @@ func (x *RegisterResponse) String() string {
func (*RegisterResponse) ProtoMessage() {} func (*RegisterResponse) ProtoMessage() {}
func (x *RegisterResponse) ProtoReflect() protoreflect.Message { func (x *RegisterResponse) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[4] mi := &file_roveapi_roveapi_proto_msgTypes[4]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -368,7 +368,7 @@ func (x *RegisterResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead. // Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead.
func (*RegisterResponse) Descriptor() ([]byte, []int) { func (*RegisterResponse) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{4} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{4}
} }
func (x *RegisterResponse) GetAccount() *Account { func (x *RegisterResponse) GetAccount() *Account {
@ -385,7 +385,7 @@ type Command struct {
unknownFields protoimpl.UnknownFields unknownFields protoimpl.UnknownFields
// The command type // The command type
Command CommandType `protobuf:"varint,1,opt,name=command,proto3,enum=rove.CommandType" json:"command,omitempty"` Command CommandType `protobuf:"varint,1,opt,name=command,proto3,enum=roveapi.CommandType" json:"command,omitempty"`
// Types that are assignable to Data: // Types that are assignable to Data:
// *Command_Bearing // *Command_Bearing
// *Command_Message // *Command_Message
@ -395,7 +395,7 @@ type Command struct {
func (x *Command) Reset() { func (x *Command) Reset() {
*x = Command{} *x = Command{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[5] mi := &file_roveapi_roveapi_proto_msgTypes[5]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -408,7 +408,7 @@ func (x *Command) String() string {
func (*Command) ProtoMessage() {} func (*Command) ProtoMessage() {}
func (x *Command) ProtoReflect() protoreflect.Message { func (x *Command) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[5] mi := &file_roveapi_roveapi_proto_msgTypes[5]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -421,7 +421,7 @@ func (x *Command) ProtoReflect() protoreflect.Message {
// Deprecated: Use Command.ProtoReflect.Descriptor instead. // Deprecated: Use Command.ProtoReflect.Descriptor instead.
func (*Command) Descriptor() ([]byte, []int) { func (*Command) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{5} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{5}
} }
func (x *Command) GetCommand() CommandType { func (x *Command) GetCommand() CommandType {
@ -488,7 +488,7 @@ type CommandRequest struct {
func (x *CommandRequest) Reset() { func (x *CommandRequest) Reset() {
*x = CommandRequest{} *x = CommandRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[6] mi := &file_roveapi_roveapi_proto_msgTypes[6]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -501,7 +501,7 @@ func (x *CommandRequest) String() string {
func (*CommandRequest) ProtoMessage() {} func (*CommandRequest) ProtoMessage() {}
func (x *CommandRequest) ProtoReflect() protoreflect.Message { func (x *CommandRequest) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[6] mi := &file_roveapi_roveapi_proto_msgTypes[6]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -514,7 +514,7 @@ func (x *CommandRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use CommandRequest.ProtoReflect.Descriptor instead. // Deprecated: Use CommandRequest.ProtoReflect.Descriptor instead.
func (*CommandRequest) Descriptor() ([]byte, []int) { func (*CommandRequest) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{6} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{6}
} }
func (x *CommandRequest) GetAccount() *Account { func (x *CommandRequest) GetAccount() *Account {
@ -541,7 +541,7 @@ type CommandResponse struct {
func (x *CommandResponse) Reset() { func (x *CommandResponse) Reset() {
*x = CommandResponse{} *x = CommandResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[7] mi := &file_roveapi_roveapi_proto_msgTypes[7]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -554,7 +554,7 @@ func (x *CommandResponse) String() string {
func (*CommandResponse) ProtoMessage() {} func (*CommandResponse) ProtoMessage() {}
func (x *CommandResponse) ProtoReflect() protoreflect.Message { func (x *CommandResponse) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[7] mi := &file_roveapi_roveapi_proto_msgTypes[7]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -567,7 +567,7 @@ func (x *CommandResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use CommandResponse.ProtoReflect.Descriptor instead. // Deprecated: Use CommandResponse.ProtoReflect.Descriptor instead.
func (*CommandResponse) Descriptor() ([]byte, []int) { func (*CommandResponse) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{7} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{7}
} }
// RadarRequest is the data needed to request the radar for a rover // RadarRequest is the data needed to request the radar for a rover
@ -583,7 +583,7 @@ type RadarRequest struct {
func (x *RadarRequest) Reset() { func (x *RadarRequest) Reset() {
*x = RadarRequest{} *x = RadarRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[8] mi := &file_roveapi_roveapi_proto_msgTypes[8]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -596,7 +596,7 @@ func (x *RadarRequest) String() string {
func (*RadarRequest) ProtoMessage() {} func (*RadarRequest) ProtoMessage() {}
func (x *RadarRequest) ProtoReflect() protoreflect.Message { func (x *RadarRequest) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[8] mi := &file_roveapi_roveapi_proto_msgTypes[8]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -609,7 +609,7 @@ func (x *RadarRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use RadarRequest.ProtoReflect.Descriptor instead. // Deprecated: Use RadarRequest.ProtoReflect.Descriptor instead.
func (*RadarRequest) Descriptor() ([]byte, []int) { func (*RadarRequest) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{8} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{8}
} }
func (x *RadarRequest) GetAccount() *Account { func (x *RadarRequest) GetAccount() *Account {
@ -637,7 +637,7 @@ type RadarResponse struct {
func (x *RadarResponse) Reset() { func (x *RadarResponse) Reset() {
*x = RadarResponse{} *x = RadarResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[9] mi := &file_roveapi_roveapi_proto_msgTypes[9]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -650,7 +650,7 @@ func (x *RadarResponse) String() string {
func (*RadarResponse) ProtoMessage() {} func (*RadarResponse) ProtoMessage() {}
func (x *RadarResponse) ProtoReflect() protoreflect.Message { func (x *RadarResponse) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[9] mi := &file_roveapi_roveapi_proto_msgTypes[9]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -663,7 +663,7 @@ func (x *RadarResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use RadarResponse.ProtoReflect.Descriptor instead. // Deprecated: Use RadarResponse.ProtoReflect.Descriptor instead.
func (*RadarResponse) Descriptor() ([]byte, []int) { func (*RadarResponse) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{9} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{9}
} }
func (x *RadarResponse) GetRange() int32 { func (x *RadarResponse) GetRange() int32 {
@ -700,7 +700,7 @@ type StatusRequest struct {
func (x *StatusRequest) Reset() { func (x *StatusRequest) Reset() {
*x = StatusRequest{} *x = StatusRequest{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[10] mi := &file_roveapi_roveapi_proto_msgTypes[10]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -713,7 +713,7 @@ func (x *StatusRequest) String() string {
func (*StatusRequest) ProtoMessage() {} func (*StatusRequest) ProtoMessage() {}
func (x *StatusRequest) ProtoReflect() protoreflect.Message { func (x *StatusRequest) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[10] mi := &file_roveapi_roveapi_proto_msgTypes[10]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -726,7 +726,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message {
// Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. // Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead.
func (*StatusRequest) Descriptor() ([]byte, []int) { func (*StatusRequest) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{10} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{10}
} }
func (x *StatusRequest) GetAccount() *Account { func (x *StatusRequest) GetAccount() *Account {
@ -751,7 +751,7 @@ type Log struct {
func (x *Log) Reset() { func (x *Log) Reset() {
*x = Log{} *x = Log{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[11] mi := &file_roveapi_roveapi_proto_msgTypes[11]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -764,7 +764,7 @@ func (x *Log) String() string {
func (*Log) ProtoMessage() {} func (*Log) ProtoMessage() {}
func (x *Log) ProtoReflect() protoreflect.Message { func (x *Log) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[11] mi := &file_roveapi_roveapi_proto_msgTypes[11]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -777,7 +777,7 @@ func (x *Log) ProtoReflect() protoreflect.Message {
// Deprecated: Use Log.ProtoReflect.Descriptor instead. // Deprecated: Use Log.ProtoReflect.Descriptor instead.
func (*Log) Descriptor() ([]byte, []int) { func (*Log) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{11} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{11}
} }
func (x *Log) GetTime() string { func (x *Log) GetTime() string {
@ -807,7 +807,7 @@ type Vector struct {
func (x *Vector) Reset() { func (x *Vector) Reset() {
*x = Vector{} *x = Vector{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[12] mi := &file_roveapi_roveapi_proto_msgTypes[12]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -820,7 +820,7 @@ func (x *Vector) String() string {
func (*Vector) ProtoMessage() {} func (*Vector) ProtoMessage() {}
func (x *Vector) ProtoReflect() protoreflect.Message { func (x *Vector) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[12] mi := &file_roveapi_roveapi_proto_msgTypes[12]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -833,7 +833,7 @@ func (x *Vector) ProtoReflect() protoreflect.Message {
// Deprecated: Use Vector.ProtoReflect.Descriptor instead. // Deprecated: Use Vector.ProtoReflect.Descriptor instead.
func (*Vector) Descriptor() ([]byte, []int) { func (*Vector) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{12} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{12}
} }
func (x *Vector) GetX() int32 { func (x *Vector) GetX() int32 {
@ -885,7 +885,7 @@ type StatusResponse struct {
func (x *StatusResponse) Reset() { func (x *StatusResponse) Reset() {
*x = StatusResponse{} *x = StatusResponse{}
if protoimpl.UnsafeEnabled { if protoimpl.UnsafeEnabled {
mi := &file_rove_rove_proto_msgTypes[13] mi := &file_roveapi_roveapi_proto_msgTypes[13]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi) ms.StoreMessageInfo(mi)
} }
@ -898,7 +898,7 @@ func (x *StatusResponse) String() string {
func (*StatusResponse) ProtoMessage() {} func (*StatusResponse) ProtoMessage() {}
func (x *StatusResponse) ProtoReflect() protoreflect.Message { func (x *StatusResponse) ProtoReflect() protoreflect.Message {
mi := &file_rove_rove_proto_msgTypes[13] mi := &file_roveapi_roveapi_proto_msgTypes[13]
if protoimpl.UnsafeEnabled && x != nil { if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil { if ms.LoadMessageInfo() == nil {
@ -911,7 +911,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message {
// Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead.
func (*StatusResponse) Descriptor() ([]byte, []int) { func (*StatusResponse) Descriptor() ([]byte, []int) {
return file_rove_rove_proto_rawDescGZIP(), []int{13} return file_roveapi_roveapi_proto_rawDescGZIP(), []int{13}
} }
func (x *StatusResponse) GetName() string { func (x *StatusResponse) GetName() string {
@ -998,174 +998,179 @@ func (x *StatusResponse) GetLogs() []*Log {
return nil return nil
} }
var File_rove_rove_proto protoreflect.FileDescriptor var File_roveapi_roveapi_proto protoreflect.FileDescriptor
var file_rove_rove_proto_rawDesc = []byte{ var file_roveapi_roveapi_proto_rawDesc = []byte{
0x0a, 0x0f, 0x72, 0x6f, 0x76, 0x65, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x0a, 0x15, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70,
0x6f, 0x12, 0x04, 0x72, 0x6f, 0x76, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69,
0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x01, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76,
0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28,
0x6e, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65,
0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79,
0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01,
0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x28, 0x05, 0x52, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b,
0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28,
0x74, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x69, 0x05, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x1b,
0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x69, 0x0a, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28,
0x63, 0x6b, 0x22, 0x25, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x22, 0x25, 0x0a, 0x0f, 0x52,
0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12,
0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61,
0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a,
0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d,
0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28,
0x22, 0x3b, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x3e, 0x0a, 0x10, 0x52, 0x65, 0x67,
0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a,
0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10,
0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x76, 0x0a, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74,
0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x79, 0x0a, 0x07, 0x43, 0x6f, 0x6d,
0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18,
0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e,
0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6d,
0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18,
0x67, 0x12, 0x1a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67,
0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x12, 0x1a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28,
0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x64, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x04,
0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x64, 0x61, 0x74, 0x61, 0x22, 0x6a, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52,
0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e,
0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70,
0x12, 0x29, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02,
0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 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, 0x37, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73,
0x0a, 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f,
0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75,
0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01,
0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x55, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x61, 0x72, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41,
0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22,
0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x55, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65,
0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52,
0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18,
0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x38, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07,
0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f,
0x27, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73,
0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75,
0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61,
0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f,
0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69,
0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12,
0x72, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65,
0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0xb7, 0x03, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0c, 0x0a, 0x01,
0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18,
0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0xc3, 0x03, 0x0a, 0x0e, 0x53, 0x74, 0x61,
0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e,
0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x56, 0x65, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12,
0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x2b, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28,
0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x63, 0x74,
0x61, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05,
0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e,
0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x05, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x18,
0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79,
0x0a, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01,
0x05, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x09,
0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52,
0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x61,
0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07,
0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74,
0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65,
0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x24,
0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18,
0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68,
0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x61, 0x72, 0x67, 0x65, 0x12, 0x3c, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67,
0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10,
0x73, 0x12, 0x35, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64,
0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e,
0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x64, 0x73, 0x12, 0x38, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76,
0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x4c, 0x6f, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75,
0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x2a, 0x55, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x04,
0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76,
0x12, 0x08, 0x0a, 0x04, 0x6d, 0x6f, 0x76, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x2a, 0x55,
0x61, 0x73, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x10, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a,
0x03, 0x12, 0x0c, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x6d, 0x6f, 0x76, 0x65, 0x10,
0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x10, 0x05, 0x32, 0xb1, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x73, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06,
0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x68,
0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x53, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63,
0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x61, 0x73, 0x74, 0x10, 0x05, 0x32, 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x4d,
0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c,
0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53,
0x12, 0x3b, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x72, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72,
0x6f, 0x76, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61,
0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a,
0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65,
0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75,
0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65,
0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x05, 0x52, 0x61, 0x64, 0x61, 0x72, 0x12, 0x3e, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x72, 0x6f,
0x12, 0x12, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71,
0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43,
0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x06, 0x53, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00,
0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x13, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x53, 0x74, 0x61, 0x12, 0x38, 0x0a, 0x05, 0x52, 0x61, 0x64, 0x61, 0x72, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65,
0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74,
0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x1a, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72,
0x22, 0x00, 0x42, 0x21, 0x5a, 0x1f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x06, 0x53, 0x74,
0x2f, 0x6d, 0x64, 0x69, 0x6c, 0x75, 0x7a, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53,
0x2f, 0x72, 0x6f, 0x76, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 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 (
file_rove_rove_proto_rawDescOnce sync.Once file_roveapi_roveapi_proto_rawDescOnce sync.Once
file_rove_rove_proto_rawDescData = file_rove_rove_proto_rawDesc file_roveapi_roveapi_proto_rawDescData = file_roveapi_roveapi_proto_rawDesc
) )
func file_rove_rove_proto_rawDescGZIP() []byte { func file_roveapi_roveapi_proto_rawDescGZIP() []byte {
file_rove_rove_proto_rawDescOnce.Do(func() { file_roveapi_roveapi_proto_rawDescOnce.Do(func() {
file_rove_rove_proto_rawDescData = protoimpl.X.CompressGZIP(file_rove_rove_proto_rawDescData) file_roveapi_roveapi_proto_rawDescData = protoimpl.X.CompressGZIP(file_roveapi_roveapi_proto_rawDescData)
}) })
return file_rove_rove_proto_rawDescData return file_roveapi_roveapi_proto_rawDescData
} }
var file_rove_rove_proto_enumTypes = make([]protoimpl.EnumInfo, 1) var file_roveapi_roveapi_proto_enumTypes = make([]protoimpl.EnumInfo, 1)
var file_rove_rove_proto_msgTypes = make([]protoimpl.MessageInfo, 14) var file_roveapi_roveapi_proto_msgTypes = make([]protoimpl.MessageInfo, 14)
var file_rove_rove_proto_goTypes = []interface{}{ var file_roveapi_roveapi_proto_goTypes = []interface{}{
(CommandType)(0), // 0: rove.CommandType (CommandType)(0), // 0: roveapi.CommandType
(*ServerStatusRequest)(nil), // 1: rove.ServerStatusRequest (*ServerStatusRequest)(nil), // 1: roveapi.ServerStatusRequest
(*ServerStatusResponse)(nil), // 2: rove.ServerStatusResponse (*ServerStatusResponse)(nil), // 2: roveapi.ServerStatusResponse
(*RegisterRequest)(nil), // 3: rove.RegisterRequest (*RegisterRequest)(nil), // 3: roveapi.RegisterRequest
(*Account)(nil), // 4: rove.Account (*Account)(nil), // 4: roveapi.Account
(*RegisterResponse)(nil), // 5: rove.RegisterResponse (*RegisterResponse)(nil), // 5: roveapi.RegisterResponse
(*Command)(nil), // 6: rove.Command (*Command)(nil), // 6: roveapi.Command
(*CommandRequest)(nil), // 7: rove.CommandRequest (*CommandRequest)(nil), // 7: roveapi.CommandRequest
(*CommandResponse)(nil), // 8: rove.CommandResponse (*CommandResponse)(nil), // 8: roveapi.CommandResponse
(*RadarRequest)(nil), // 9: rove.RadarRequest (*RadarRequest)(nil), // 9: roveapi.RadarRequest
(*RadarResponse)(nil), // 10: rove.RadarResponse (*RadarResponse)(nil), // 10: roveapi.RadarResponse
(*StatusRequest)(nil), // 11: rove.StatusRequest (*StatusRequest)(nil), // 11: roveapi.StatusRequest
(*Log)(nil), // 12: rove.Log (*Log)(nil), // 12: roveapi.Log
(*Vector)(nil), // 13: rove.Vector (*Vector)(nil), // 13: roveapi.Vector
(*StatusResponse)(nil), // 14: rove.StatusResponse (*StatusResponse)(nil), // 14: roveapi.StatusResponse
} }
var file_rove_rove_proto_depIdxs = []int32{ var file_roveapi_roveapi_proto_depIdxs = []int32{
4, // 0: rove.RegisterResponse.account:type_name -> rove.Account 4, // 0: roveapi.RegisterResponse.account:type_name -> roveapi.Account
0, // 1: rove.Command.command:type_name -> rove.CommandType 0, // 1: roveapi.Command.command:type_name -> roveapi.CommandType
4, // 2: rove.CommandRequest.account:type_name -> rove.Account 4, // 2: roveapi.CommandRequest.account:type_name -> roveapi.Account
6, // 3: rove.CommandRequest.commands:type_name -> rove.Command 6, // 3: roveapi.CommandRequest.commands:type_name -> roveapi.Command
4, // 4: rove.RadarRequest.account:type_name -> rove.Account 4, // 4: roveapi.RadarRequest.account:type_name -> roveapi.Account
4, // 5: rove.StatusRequest.account:type_name -> rove.Account 4, // 5: roveapi.StatusRequest.account:type_name -> roveapi.Account
13, // 6: rove.StatusResponse.position:type_name -> rove.Vector 13, // 6: roveapi.StatusResponse.position:type_name -> roveapi.Vector
6, // 7: rove.StatusResponse.incomingCommands:type_name -> rove.Command 6, // 7: roveapi.StatusResponse.incomingCommands:type_name -> roveapi.Command
6, // 8: rove.StatusResponse.queuedCommands:type_name -> rove.Command 6, // 8: roveapi.StatusResponse.queuedCommands:type_name -> roveapi.Command
12, // 9: rove.StatusResponse.logs:type_name -> rove.Log 12, // 9: roveapi.StatusResponse.logs:type_name -> roveapi.Log
1, // 10: rove.Rove.ServerStatus:input_type -> rove.ServerStatusRequest 1, // 10: roveapi.Rove.ServerStatus:input_type -> roveapi.ServerStatusRequest
3, // 11: rove.Rove.Register:input_type -> rove.RegisterRequest 3, // 11: roveapi.Rove.Register:input_type -> roveapi.RegisterRequest
7, // 12: rove.Rove.Command:input_type -> rove.CommandRequest 7, // 12: roveapi.Rove.Command:input_type -> roveapi.CommandRequest
9, // 13: rove.Rove.Radar:input_type -> rove.RadarRequest 9, // 13: roveapi.Rove.Radar:input_type -> roveapi.RadarRequest
11, // 14: rove.Rove.Status:input_type -> rove.StatusRequest 11, // 14: roveapi.Rove.Status:input_type -> roveapi.StatusRequest
2, // 15: rove.Rove.ServerStatus:output_type -> rove.ServerStatusResponse 2, // 15: roveapi.Rove.ServerStatus:output_type -> roveapi.ServerStatusResponse
5, // 16: rove.Rove.Register:output_type -> rove.RegisterResponse 5, // 16: roveapi.Rove.Register:output_type -> roveapi.RegisterResponse
8, // 17: rove.Rove.Command:output_type -> rove.CommandResponse 8, // 17: roveapi.Rove.Command:output_type -> roveapi.CommandResponse
10, // 18: rove.Rove.Radar:output_type -> rove.RadarResponse 10, // 18: roveapi.Rove.Radar:output_type -> roveapi.RadarResponse
14, // 19: rove.Rove.Status:output_type -> rove.StatusResponse 14, // 19: roveapi.Rove.Status:output_type -> roveapi.StatusResponse
15, // [15:20] is the sub-list for method output_type 15, // [15:20] is the sub-list for method output_type
10, // [10:15] is the sub-list for method input_type 10, // [10:15] is the sub-list for method input_type
10, // [10:10] is the sub-list for extension type_name 10, // [10:10] is the sub-list for extension type_name
@ -1173,13 +1178,13 @@ var file_rove_rove_proto_depIdxs = []int32{
0, // [0:10] is the sub-list for field type_name 0, // [0:10] is the sub-list for field type_name
} }
func init() { file_rove_rove_proto_init() } func init() { file_roveapi_roveapi_proto_init() }
func file_rove_rove_proto_init() { func file_roveapi_roveapi_proto_init() {
if File_rove_rove_proto != nil { if File_roveapi_roveapi_proto != nil {
return return
} }
if !protoimpl.UnsafeEnabled { if !protoimpl.UnsafeEnabled {
file_rove_rove_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ServerStatusRequest); i { switch v := v.(*ServerStatusRequest); i {
case 0: case 0:
return &v.state return &v.state
@ -1191,7 +1196,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*ServerStatusResponse); i { switch v := v.(*ServerStatusResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -1203,7 +1208,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[2].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterRequest); i { switch v := v.(*RegisterRequest); i {
case 0: case 0:
return &v.state return &v.state
@ -1215,7 +1220,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[3].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Account); i { switch v := v.(*Account); i {
case 0: case 0:
return &v.state return &v.state
@ -1227,7 +1232,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[4].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RegisterResponse); i { switch v := v.(*RegisterResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -1239,7 +1244,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[5].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Command); i { switch v := v.(*Command); i {
case 0: case 0:
return &v.state return &v.state
@ -1251,7 +1256,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[6].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CommandRequest); i { switch v := v.(*CommandRequest); i {
case 0: case 0:
return &v.state return &v.state
@ -1263,7 +1268,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[7].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*CommandResponse); i { switch v := v.(*CommandResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -1275,7 +1280,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[8].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RadarRequest); i { switch v := v.(*RadarRequest); i {
case 0: case 0:
return &v.state return &v.state
@ -1287,7 +1292,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[9].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*RadarResponse); i { switch v := v.(*RadarResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -1299,7 +1304,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[10].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StatusRequest); i { switch v := v.(*StatusRequest); i {
case 0: case 0:
return &v.state return &v.state
@ -1311,7 +1316,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[11].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Log); i { switch v := v.(*Log); i {
case 0: case 0:
return &v.state return &v.state
@ -1323,7 +1328,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[12].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*Vector); i { switch v := v.(*Vector); i {
case 0: case 0:
return &v.state return &v.state
@ -1335,7 +1340,7 @@ func file_rove_rove_proto_init() {
return nil return nil
} }
} }
file_rove_rove_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} { file_roveapi_roveapi_proto_msgTypes[13].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*StatusResponse); i { switch v := v.(*StatusResponse); i {
case 0: case 0:
return &v.state return &v.state
@ -1348,7 +1353,7 @@ func file_rove_rove_proto_init() {
} }
} }
} }
file_rove_rove_proto_msgTypes[5].OneofWrappers = []interface{}{ file_roveapi_roveapi_proto_msgTypes[5].OneofWrappers = []interface{}{
(*Command_Bearing)(nil), (*Command_Bearing)(nil),
(*Command_Message)(nil), (*Command_Message)(nil),
} }
@ -1356,21 +1361,21 @@ func file_rove_rove_proto_init() {
out := protoimpl.TypeBuilder{ out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{ File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(), GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_rove_rove_proto_rawDesc, RawDescriptor: file_roveapi_roveapi_proto_rawDesc,
NumEnums: 1, NumEnums: 1,
NumMessages: 14, NumMessages: 14,
NumExtensions: 0, NumExtensions: 0,
NumServices: 1, NumServices: 1,
}, },
GoTypes: file_rove_rove_proto_goTypes, GoTypes: file_roveapi_roveapi_proto_goTypes,
DependencyIndexes: file_rove_rove_proto_depIdxs, DependencyIndexes: file_roveapi_roveapi_proto_depIdxs,
EnumInfos: file_rove_rove_proto_enumTypes, EnumInfos: file_roveapi_roveapi_proto_enumTypes,
MessageInfos: file_rove_rove_proto_msgTypes, MessageInfos: file_roveapi_roveapi_proto_msgTypes,
}.Build() }.Build()
File_rove_rove_proto = out.File File_roveapi_roveapi_proto = out.File
file_rove_rove_proto_rawDesc = nil file_roveapi_roveapi_proto_rawDesc = nil
file_rove_rove_proto_goTypes = nil file_roveapi_roveapi_proto_goTypes = nil
file_rove_rove_proto_depIdxs = nil file_roveapi_roveapi_proto_depIdxs = nil
} }
// Reference imports to suppress errors if they are not otherwise used. // Reference imports to suppress errors if they are not otherwise used.
@ -1414,7 +1419,7 @@ func NewRoveClient(cc grpc.ClientConnInterface) RoveClient {
func (c *roveClient) ServerStatus(ctx context.Context, in *ServerStatusRequest, opts ...grpc.CallOption) (*ServerStatusResponse, error) { func (c *roveClient) ServerStatus(ctx context.Context, in *ServerStatusRequest, opts ...grpc.CallOption) (*ServerStatusResponse, error) {
out := new(ServerStatusResponse) out := new(ServerStatusResponse)
err := c.cc.Invoke(ctx, "/rove.Rove/ServerStatus", in, out, opts...) err := c.cc.Invoke(ctx, "/roveapi.Rove/ServerStatus", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1423,7 +1428,7 @@ func (c *roveClient) ServerStatus(ctx context.Context, in *ServerStatusRequest,
func (c *roveClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) { func (c *roveClient) Register(ctx context.Context, in *RegisterRequest, opts ...grpc.CallOption) (*RegisterResponse, error) {
out := new(RegisterResponse) out := new(RegisterResponse)
err := c.cc.Invoke(ctx, "/rove.Rove/Register", in, out, opts...) err := c.cc.Invoke(ctx, "/roveapi.Rove/Register", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1432,7 +1437,7 @@ func (c *roveClient) Register(ctx context.Context, in *RegisterRequest, opts ...
func (c *roveClient) Command(ctx context.Context, in *CommandRequest, opts ...grpc.CallOption) (*CommandResponse, error) { func (c *roveClient) Command(ctx context.Context, in *CommandRequest, opts ...grpc.CallOption) (*CommandResponse, error) {
out := new(CommandResponse) out := new(CommandResponse)
err := c.cc.Invoke(ctx, "/rove.Rove/Command", in, out, opts...) err := c.cc.Invoke(ctx, "/roveapi.Rove/Command", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1441,7 +1446,7 @@ func (c *roveClient) Command(ctx context.Context, in *CommandRequest, opts ...gr
func (c *roveClient) Radar(ctx context.Context, in *RadarRequest, opts ...grpc.CallOption) (*RadarResponse, error) { func (c *roveClient) Radar(ctx context.Context, in *RadarRequest, opts ...grpc.CallOption) (*RadarResponse, error) {
out := new(RadarResponse) out := new(RadarResponse)
err := c.cc.Invoke(ctx, "/rove.Rove/Radar", in, out, opts...) err := c.cc.Invoke(ctx, "/roveapi.Rove/Radar", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1450,7 +1455,7 @@ func (c *roveClient) Radar(ctx context.Context, in *RadarRequest, opts ...grpc.C
func (c *roveClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) { func (c *roveClient) Status(ctx context.Context, in *StatusRequest, opts ...grpc.CallOption) (*StatusResponse, error) {
out := new(StatusResponse) out := new(StatusResponse)
err := c.cc.Invoke(ctx, "/rove.Rove/Status", in, out, opts...) err := c.cc.Invoke(ctx, "/roveapi.Rove/Status", in, out, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -1512,7 +1517,7 @@ func _Rove_ServerStatus_Handler(srv interface{}, ctx context.Context, dec func(i
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/rove.Rove/ServerStatus", FullMethod: "/roveapi.Rove/ServerStatus",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RoveServer).ServerStatus(ctx, req.(*ServerStatusRequest)) return srv.(RoveServer).ServerStatus(ctx, req.(*ServerStatusRequest))
@ -1530,7 +1535,7 @@ func _Rove_Register_Handler(srv interface{}, ctx context.Context, dec func(inter
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/rove.Rove/Register", FullMethod: "/roveapi.Rove/Register",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RoveServer).Register(ctx, req.(*RegisterRequest)) return srv.(RoveServer).Register(ctx, req.(*RegisterRequest))
@ -1548,7 +1553,7 @@ func _Rove_Command_Handler(srv interface{}, ctx context.Context, dec func(interf
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/rove.Rove/Command", FullMethod: "/roveapi.Rove/Command",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RoveServer).Command(ctx, req.(*CommandRequest)) return srv.(RoveServer).Command(ctx, req.(*CommandRequest))
@ -1566,7 +1571,7 @@ func _Rove_Radar_Handler(srv interface{}, ctx context.Context, dec func(interfac
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/rove.Rove/Radar", FullMethod: "/roveapi.Rove/Radar",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RoveServer).Radar(ctx, req.(*RadarRequest)) return srv.(RoveServer).Radar(ctx, req.(*RadarRequest))
@ -1584,7 +1589,7 @@ func _Rove_Status_Handler(srv interface{}, ctx context.Context, dec func(interfa
} }
info := &grpc.UnaryServerInfo{ info := &grpc.UnaryServerInfo{
Server: srv, Server: srv,
FullMethod: "/rove.Rove/Status", FullMethod: "/roveapi.Rove/Status",
} }
handler := func(ctx context.Context, req interface{}) (interface{}, error) { handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(RoveServer).Status(ctx, req.(*StatusRequest)) return srv.(RoveServer).Status(ctx, req.(*StatusRequest))
@ -1593,7 +1598,7 @@ func _Rove_Status_Handler(srv interface{}, ctx context.Context, dec func(interfa
} }
var _Rove_serviceDesc = grpc.ServiceDesc{ var _Rove_serviceDesc = grpc.ServiceDesc{
ServiceName: "rove.Rove", ServiceName: "roveapi.Rove",
HandlerType: (*RoveServer)(nil), HandlerType: (*RoveServer)(nil),
Methods: []grpc.MethodDesc{ Methods: []grpc.MethodDesc{
{ {
@ -1618,5 +1623,5 @@ var _Rove_serviceDesc = grpc.ServiceDesc{
}, },
}, },
Streams: []grpc.StreamDesc{}, Streams: []grpc.StreamDesc{},
Metadata: "rove/rove.proto", Metadata: "roveapi/roveapi.proto",
} }

View file

@ -4,8 +4,8 @@ syntax = "proto3";
// //
// Rove is an asychronous nomadic game about exploring a planet as part of a // Rove is an asychronous nomadic game about exploring a planet as part of a
// loose community // loose community
package rove; package roveapi;
option go_package = "github.com/mdiluz/rove/pkg/rove"; option go_package = "github.com/mdiluz/rove/proto/roveapi";
// The Rove server hosts a single game session and world with multiple players // The Rove server hosts a single game session and world with multiple players
service Rove { service Rove {