From 5ac44d85cbd1f71351ee9fa254da06ea56b43b2c Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 16:38:49 +0100 Subject: [PATCH 01/18] Add a warning to missing DATA_PATH env --- cmd/rove-server/main.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/cmd/rove-server/main.go b/cmd/rove-server/main.go index db09130..66621cf 100644 --- a/cmd/rove-server/main.go +++ b/cmd/rove-server/main.go @@ -52,7 +52,9 @@ func InnerMain() { log.Printf("Initialising version %s...\n", version.Version) // 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) } From fb2ffc52523faf8659790ecf6b80392948bbaa1a Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 16:52:00 +0100 Subject: [PATCH 02/18] Convert Atlas to an interface --- pkg/atlas/atlas.go | 46 ++++++++++++++++++++++++++--------------- pkg/atlas/atlas_test.go | 22 ++++++++++---------- pkg/game/world.go | 4 ++-- 3 files changed, 42 insertions(+), 30 deletions(-) diff --git a/pkg/atlas/atlas.go b/pkg/atlas/atlas.go index dd618e7..b94d923 100644 --- a/pkg/atlas/atlas.go +++ b/pkg/atlas/atlas.go @@ -27,6 +27,18 @@ const ( TileSand = Tile('~') ) +// Atlas represents a 2D world atlas of tiles and objects +type Atlas interface { + // SetTile sets a location on the Atlas to a type of tile + SetTile(v vector.Vector, tile Tile) + + // SetObject will set a location on the Atlas to contain an object + SetObject(v vector.Vector, obj objects.Object) + + // QueryPosition queries a position on the atlas + QueryPosition(v vector.Vector) (byte, objects.Object) +} + // Chunk represents a fixed square grid of tiles type Chunk struct { // Tiles represents the tiles within the chunk @@ -37,8 +49,8 @@ type Chunk struct { Objects map[int]objects.Object `json:"objects"` } -// Atlas represents a grid of Chunks -type Atlas struct { +// 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"` @@ -68,7 +80,7 @@ const ( // NewAtlas creates a new empty atlas func NewAtlas(chunkSize int) Atlas { // Start up with one chunk - a := Atlas{ + a := ChunkBasedAtlas{ ChunkSize: chunkSize, Chunks: make([]Chunk, 1), LowerBound: vector.Vector{X: 0, Y: 0}, @@ -78,25 +90,25 @@ func NewAtlas(chunkSize int) Atlas { } // Initialise the first chunk a.populate(0) - return a + return &a } // SetTile sets an individual tile's kind -func (a *Atlas) SetTile(v vector.Vector, tile Tile) { +func (a *ChunkBasedAtlas) 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) { +func (a *ChunkBasedAtlas) 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) { +func (a *ChunkBasedAtlas) QueryPosition(v vector.Vector) (byte, objects.Object) { c := a.worldSpaceToChunkWithGrow(v) local := a.worldSpaceToChunkLocal(v) a.populate(c) @@ -106,12 +118,12 @@ func (a *Atlas) QueryPosition(v vector.Vector) (byte, objects.Object) { } // chunkTileID returns the tile index within a chunk -func (a *Atlas) chunkTileIndex(local vector.Vector) int { +func (a *ChunkBasedAtlas) 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) { +func (a *ChunkBasedAtlas) populate(chunk int) { c := a.Chunks[chunk] if c.Tiles != nil { return @@ -165,7 +177,7 @@ func (a *Atlas) populate(chunk int) { } // setTile sets a tile in a specific chunk -func (a *Atlas) setTile(chunk int, local vector.Vector, tile byte) { +func (a *ChunkBasedAtlas) setTile(chunk int, local vector.Vector, tile byte) { a.populate(chunk) c := a.Chunks[chunk] c.Tiles[a.chunkTileIndex(local)] = tile @@ -173,7 +185,7 @@ func (a *Atlas) setTile(chunk int, local vector.Vector, tile byte) { } // setObject sets an object in a specific chunk -func (a *Atlas) setObject(chunk int, local vector.Vector, object objects.Object) { +func (a *ChunkBasedAtlas) setObject(chunk int, local vector.Vector, object objects.Object) { a.populate(chunk) c := a.Chunks[chunk] @@ -187,12 +199,12 @@ func (a *Atlas) setObject(chunk int, local vector.Vector, object objects.Object) } // worldSpaceToChunkLocal gets a chunk local coordinate for a tile -func (a *Atlas) worldSpaceToChunkLocal(v vector.Vector) vector.Vector { +func (a *ChunkBasedAtlas) 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 { +func (a *ChunkBasedAtlas) worldSpaceToChunkIndex(v vector.Vector) int { // Shift the vector by our current min v = v.Added(a.LowerBound.Negated()) @@ -208,7 +220,7 @@ func (a *Atlas) worldSpaceToChunkIndex(v vector.Vector) int { } // chunkOriginInWorldSpace returns the origin of the chunk in world space -func (a *Atlas) chunkOriginInWorldSpace(chunk int) vector.Vector { +func (a *ChunkBasedAtlas) chunkOriginInWorldSpace(chunk int) vector.Vector { // Calculate the width width := a.UpperBound.X - a.LowerBound.X widthInChunks := width / a.ChunkSize @@ -225,7 +237,7 @@ func (a *Atlas) chunkOriginInWorldSpace(chunk int) vector.Vector { } // 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) { +func (a *ChunkBasedAtlas) 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) @@ -241,7 +253,7 @@ func (a *Atlas) getNewBounds(v vector.Vector) (lower vector.Vector, upper vector } // worldSpaceToTrunkWithGrow will expand the current atlas for a given world space position if needed -func (a *Atlas) worldSpaceToChunkWithGrow(v vector.Vector) int { +func (a *ChunkBasedAtlas) 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) @@ -253,7 +265,7 @@ func (a *Atlas) worldSpaceToChunkWithGrow(v vector.Vector) int { size = size.Divided(a.ChunkSize) // Create the new empty atlas - newAtlas := Atlas{ + newAtlas := ChunkBasedAtlas{ ChunkSize: a.ChunkSize, LowerBound: lower, UpperBound: upper, diff --git a/pkg/atlas/atlas_test.go b/pkg/atlas/atlas_test.go index dedf4b1..1803bea 100644 --- a/pkg/atlas/atlas_test.go +++ b/pkg/atlas/atlas_test.go @@ -10,14 +10,14 @@ import ( ) func TestAtlas_NewAtlas(t *testing.T) { - a := NewAtlas(1) + a := NewAtlas(1).(*ChunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, a.ChunkSize) assert.Equal(t, 1, len(a.Chunks)) // Should start empty } func TestAtlas_toChunk(t *testing.T) { - a := NewAtlas(1) + a := NewAtlas(1).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks @@ -38,7 +38,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: 0}) assert.Equal(t, 2, chunkID) - a = NewAtlas(2) + a = NewAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks a.QueryPosition(vector.Vector{X: -2, Y: -2}) @@ -58,7 +58,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 1}) assert.Equal(t, 2, chunkID) - a = NewAtlas(2) + a = NewAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -83,7 +83,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 2}) assert.Equal(t, 13, chunkID) - a = NewAtlas(3) + a = NewAtlas(3).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -105,7 +105,7 @@ func TestAtlas_toChunk(t *testing.T) { } func TestAtlas_toWorld(t *testing.T) { - a := NewAtlas(1) + a := NewAtlas(1).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn some chunks @@ -119,7 +119,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -1, Y: -1}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: 0, Y: -1}, a.chunkOriginInWorldSpace(1)) - a = NewAtlas(2) + a = NewAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks a.QueryPosition(vector.Vector{X: -2, Y: -2}) @@ -133,7 +133,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -2, Y: -2}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: -2, Y: 0}, a.chunkOriginInWorldSpace(2)) - a = NewAtlas(2) + a = NewAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -152,7 +152,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -4, Y: -4}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: 2, Y: -2}, a.chunkOriginInWorldSpace(7)) - a = NewAtlas(3) + a = NewAtlas(3).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -198,7 +198,7 @@ func TestAtlas_GetSetObject(t *testing.T) { func TestAtlas_Grown(t *testing.T) { // Start with a small example - a := NewAtlas(2) + a := NewAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, len(a.Chunks)) @@ -233,7 +233,7 @@ func TestAtlas_GetSetCorrect(t *testing.T) { for x := -i * 2; x < i*2; x++ { for y := -i * 2; y < i*2; y++ { - a := NewAtlas(i) + a := NewAtlas(i).(*ChunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, len(a.Chunks)) diff --git a/pkg/game/world.go b/pkg/game/world.go index 19183f5..89a70e5 100644 --- a/pkg/game/world.go +++ b/pkg/game/world.go @@ -107,8 +107,8 @@ func (w *World) SpawnRover() (string, error) { // Spawn in a random place near the origin rover.Pos = vector.Vector{ - X: w.Atlas.ChunkSize/2 - rand.Intn(w.Atlas.ChunkSize), - Y: w.Atlas.ChunkSize/2 - rand.Intn(w.Atlas.ChunkSize), + X: 10 - rand.Intn(20), + Y: 10 - rand.Intn(20), } // Seach until we error (run out of world) From 655e00b41fbe33b9e63fa478baa29acb5c3957b2 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 16:52:31 +0100 Subject: [PATCH 03/18] Don't expose Chunk externally --- pkg/atlas/atlas.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/atlas/atlas.go b/pkg/atlas/atlas.go index b94d923..0793dc9 100644 --- a/pkg/atlas/atlas.go +++ b/pkg/atlas/atlas.go @@ -39,8 +39,8 @@ type Atlas interface { QueryPosition(v vector.Vector) (byte, objects.Object) } -// Chunk represents a fixed square grid of tiles -type Chunk struct { +// chunk represents a fixed square grid of tiles +type chunk struct { // Tiles represents the tiles within the chunk Tiles []byte `json:"tiles"` @@ -53,7 +53,7 @@ type Chunk struct { 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"` + 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"` @@ -82,7 +82,7 @@ func NewAtlas(chunkSize int) Atlas { // Start up with one chunk a := ChunkBasedAtlas{ ChunkSize: chunkSize, - Chunks: make([]Chunk, 1), + Chunks: make([]chunk, 1), LowerBound: vector.Vector{X: 0, Y: 0}, UpperBound: vector.Vector{X: chunkSize, Y: chunkSize}, terrainNoise: opensimplex.New(noiseSeed), @@ -269,7 +269,7 @@ func (a *ChunkBasedAtlas) worldSpaceToChunkWithGrow(v vector.Vector) int { ChunkSize: a.ChunkSize, LowerBound: lower, UpperBound: upper, - Chunks: make([]Chunk, size.X*size.Y), + Chunks: make([]chunk, size.X*size.Y), terrainNoise: a.terrainNoise, objectNoise: a.objectNoise, } From a0be8a463c72ffdfe4e52fff7823316f1bedd660 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 16:54:43 +0100 Subject: [PATCH 04/18] Pull out chunk based atlas into new file --- pkg/atlas/atlas.go | 260 --------------------------------------- pkg/atlas/atlas_test.go | 28 ++--- pkg/atlas/chunkAtlas.go | 266 ++++++++++++++++++++++++++++++++++++++++ pkg/game/world.go | 2 +- 4 files changed, 281 insertions(+), 275 deletions(-) create mode 100644 pkg/atlas/chunkAtlas.go diff --git a/pkg/atlas/atlas.go b/pkg/atlas/atlas.go index 0793dc9..d4054db 100644 --- a/pkg/atlas/atlas.go +++ b/pkg/atlas/atlas.go @@ -1,13 +1,8 @@ package atlas import ( - "log" - "math/rand" - - "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 @@ -38,258 +33,3 @@ type Atlas interface { // QueryPosition queries a position on the atlas QueryPosition(v vector.Vector) (byte, objects.Object) } - -// 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]objects.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 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 := ChunkBasedAtlas{ - 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) chunkTileIndex(local vector.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]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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 := 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) -} diff --git a/pkg/atlas/atlas_test.go b/pkg/atlas/atlas_test.go index 1803bea..1805d66 100644 --- a/pkg/atlas/atlas_test.go +++ b/pkg/atlas/atlas_test.go @@ -10,14 +10,14 @@ import ( ) func TestAtlas_NewAtlas(t *testing.T) { - a := NewAtlas(1).(*ChunkBasedAtlas) + a := NewChunkAtlas(1).(*ChunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, a.ChunkSize) assert.Equal(t, 1, len(a.Chunks)) // Should start empty } func TestAtlas_toChunk(t *testing.T) { - a := NewAtlas(1).(*ChunkBasedAtlas) + a := NewChunkAtlas(1).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks @@ -38,7 +38,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: 0}) assert.Equal(t, 2, chunkID) - a = NewAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks a.QueryPosition(vector.Vector{X: -2, Y: -2}) @@ -58,7 +58,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 1}) assert.Equal(t, 2, chunkID) - a = NewAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -83,7 +83,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 2}) assert.Equal(t, 13, chunkID) - a = NewAtlas(3).(*ChunkBasedAtlas) + a = NewChunkAtlas(3).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -105,7 +105,7 @@ func TestAtlas_toChunk(t *testing.T) { } func TestAtlas_toWorld(t *testing.T) { - a := NewAtlas(1).(*ChunkBasedAtlas) + a := NewChunkAtlas(1).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn some chunks @@ -119,7 +119,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -1, Y: -1}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: 0, Y: -1}, a.chunkOriginInWorldSpace(1)) - a = NewAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks a.QueryPosition(vector.Vector{X: -2, Y: -2}) @@ -133,7 +133,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -2, Y: -2}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: -2, Y: 0}, a.chunkOriginInWorldSpace(2)) - a = NewAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -152,7 +152,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -4, Y: -4}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: 2, Y: -2}, a.chunkOriginInWorldSpace(7)) - a = NewAtlas(3).(*ChunkBasedAtlas) + a = NewChunkAtlas(3).(*ChunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -167,7 +167,7 @@ func TestAtlas_toWorld(t *testing.T) { } func TestAtlas_GetSetTile(t *testing.T) { - a := NewAtlas(10) + a := NewChunkAtlas(10) assert.NotNil(t, a) // Set the origin tile to 1 and test it @@ -182,7 +182,7 @@ func TestAtlas_GetSetTile(t *testing.T) { } func TestAtlas_GetSetObject(t *testing.T) { - a := NewAtlas(10) + a := NewChunkAtlas(10) assert.NotNil(t, a) // Set the origin tile to 1 and test it @@ -198,7 +198,7 @@ func TestAtlas_GetSetObject(t *testing.T) { func TestAtlas_Grown(t *testing.T) { // Start with a small example - a := NewAtlas(2).(*ChunkBasedAtlas) + a := NewChunkAtlas(2).(*ChunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, len(a.Chunks)) @@ -233,7 +233,7 @@ func TestAtlas_GetSetCorrect(t *testing.T) { for x := -i * 2; x < i*2; x++ { for y := -i * 2; y < i*2; y++ { - a := NewAtlas(i).(*ChunkBasedAtlas) + a := NewChunkAtlas(i).(*ChunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, len(a.Chunks)) @@ -251,7 +251,7 @@ func TestAtlas_GetSetCorrect(t *testing.T) { } func TestAtlas_WorldGen(t *testing.T) { - a := NewAtlas(8) + a := NewChunkAtlas(8) // Spawn a large world _, _ = a.QueryPosition(vector.Vector{X: 20, Y: 20}) diff --git a/pkg/atlas/chunkAtlas.go b/pkg/atlas/chunkAtlas.go new file mode 100644 index 0000000..00231af --- /dev/null +++ b/pkg/atlas/chunkAtlas.go @@ -0,0 +1,266 @@ +package atlas + +import ( + "log" + "math/rand" + + "github.com/mdiluz/rove/pkg/maths" + "github.com/mdiluz/rove/pkg/objects" + "github.com/mdiluz/rove/pkg/vector" + "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]objects.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 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 +) + +// 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: 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) chunkTileIndex(local vector.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]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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 *ChunkBasedAtlas) 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 := 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) +} diff --git a/pkg/game/world.go b/pkg/game/world.go index 89a70e5..f7476fb 100644 --- a/pkg/game/world.go +++ b/pkg/game/world.go @@ -70,7 +70,7 @@ func NewWorld(chunkSize int) *World { Rovers: make(map[string]Rover), CommandQueue: make(map[string]CommandStream), CommandIncoming: make(map[string]CommandStream), - Atlas: atlas.NewAtlas(chunkSize), + Atlas: atlas.NewChunkAtlas(chunkSize), words: lines, TicksPerDay: 24, CurrentTicks: 0, From 9a7c48ae7828f1fc192b6e820117e2a1b66cd42f Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 16:56:17 +0100 Subject: [PATCH 05/18] Make chunkBasedAtlas private --- pkg/atlas/atlas_test.go | 22 +++++++++++----------- pkg/atlas/chunkAtlas.go | 32 ++++++++++++++++---------------- 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/pkg/atlas/atlas_test.go b/pkg/atlas/atlas_test.go index 1805d66..1b1447e 100644 --- a/pkg/atlas/atlas_test.go +++ b/pkg/atlas/atlas_test.go @@ -10,14 +10,14 @@ import ( ) func TestAtlas_NewAtlas(t *testing.T) { - a := NewChunkAtlas(1).(*ChunkBasedAtlas) + a := NewChunkAtlas(1).(*chunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, a.ChunkSize) assert.Equal(t, 1, len(a.Chunks)) // Should start empty } func TestAtlas_toChunk(t *testing.T) { - a := NewChunkAtlas(1).(*ChunkBasedAtlas) + a := NewChunkAtlas(1).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks @@ -38,7 +38,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: 0}) assert.Equal(t, 2, chunkID) - a = NewChunkAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks a.QueryPosition(vector.Vector{X: -2, Y: -2}) @@ -58,7 +58,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 1}) assert.Equal(t, 2, chunkID) - a = NewChunkAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -83,7 +83,7 @@ func TestAtlas_toChunk(t *testing.T) { chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 2}) assert.Equal(t, 13, chunkID) - a = NewChunkAtlas(3).(*ChunkBasedAtlas) + a = NewChunkAtlas(3).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -105,7 +105,7 @@ func TestAtlas_toChunk(t *testing.T) { } func TestAtlas_toWorld(t *testing.T) { - a := NewChunkAtlas(1).(*ChunkBasedAtlas) + a := NewChunkAtlas(1).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn some chunks @@ -119,7 +119,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -1, Y: -1}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: 0, Y: -1}, a.chunkOriginInWorldSpace(1)) - a = NewChunkAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn the chunks a.QueryPosition(vector.Vector{X: -2, Y: -2}) @@ -133,7 +133,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -2, Y: -2}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: -2, Y: 0}, a.chunkOriginInWorldSpace(2)) - a = NewChunkAtlas(2).(*ChunkBasedAtlas) + a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -152,7 +152,7 @@ func TestAtlas_toWorld(t *testing.T) { assert.Equal(t, vector.Vector{X: -4, Y: -4}, a.chunkOriginInWorldSpace(0)) assert.Equal(t, vector.Vector{X: 2, Y: -2}, a.chunkOriginInWorldSpace(7)) - a = NewChunkAtlas(3).(*ChunkBasedAtlas) + a = NewChunkAtlas(3).(*chunkBasedAtlas) assert.NotNil(t, a) // Get a tile to spawn a 4x4 grid of chunks a.QueryPosition(vector.Vector{X: 3, Y: 3}) @@ -198,7 +198,7 @@ func TestAtlas_GetSetObject(t *testing.T) { func TestAtlas_Grown(t *testing.T) { // Start with a small example - a := NewChunkAtlas(2).(*ChunkBasedAtlas) + a := NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, len(a.Chunks)) @@ -233,7 +233,7 @@ func TestAtlas_GetSetCorrect(t *testing.T) { for x := -i * 2; x < i*2; x++ { for y := -i * 2; y < i*2; y++ { - a := NewChunkAtlas(i).(*ChunkBasedAtlas) + a := NewChunkAtlas(i).(*chunkBasedAtlas) assert.NotNil(t, a) assert.Equal(t, 1, len(a.Chunks)) diff --git a/pkg/atlas/chunkAtlas.go b/pkg/atlas/chunkAtlas.go index 00231af..1caac1e 100644 --- a/pkg/atlas/chunkAtlas.go +++ b/pkg/atlas/chunkAtlas.go @@ -20,8 +20,8 @@ type chunk struct { Objects map[int]objects.Object `json:"objects"` } -// ChunkBasedAtlas represents a grid of Chunks -type ChunkBasedAtlas struct { +// 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"` @@ -51,7 +51,7 @@ const ( // NewChunkAtlas creates a new empty atlas func NewChunkAtlas(chunkSize int) Atlas { // Start up with one chunk - a := ChunkBasedAtlas{ + a := chunkBasedAtlas{ ChunkSize: chunkSize, Chunks: make([]chunk, 1), LowerBound: vector.Vector{X: 0, Y: 0}, @@ -65,21 +65,21 @@ func NewChunkAtlas(chunkSize int) Atlas { } // SetTile sets an individual tile's kind -func (a *ChunkBasedAtlas) SetTile(v vector.Vector, tile Tile) { +func (a *chunkBasedAtlas) 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 *ChunkBasedAtlas) SetObject(v vector.Vector, obj objects.Object) { +func (a *chunkBasedAtlas) 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 *ChunkBasedAtlas) QueryPosition(v vector.Vector) (byte, objects.Object) { +func (a *chunkBasedAtlas) QueryPosition(v vector.Vector) (byte, objects.Object) { c := a.worldSpaceToChunkWithGrow(v) local := a.worldSpaceToChunkLocal(v) a.populate(c) @@ -89,12 +89,12 @@ func (a *ChunkBasedAtlas) QueryPosition(v vector.Vector) (byte, objects.Object) } // chunkTileID returns the tile index within a chunk -func (a *ChunkBasedAtlas) chunkTileIndex(local vector.Vector) int { +func (a *chunkBasedAtlas) chunkTileIndex(local vector.Vector) int { return local.X + local.Y*a.ChunkSize } // populate will fill a chunk with data -func (a *ChunkBasedAtlas) populate(chunk int) { +func (a *chunkBasedAtlas) populate(chunk int) { c := a.Chunks[chunk] if c.Tiles != nil { return @@ -148,7 +148,7 @@ func (a *ChunkBasedAtlas) populate(chunk int) { } // setTile sets a tile in a specific chunk -func (a *ChunkBasedAtlas) setTile(chunk int, local vector.Vector, tile byte) { +func (a *chunkBasedAtlas) setTile(chunk int, local vector.Vector, tile byte) { a.populate(chunk) c := a.Chunks[chunk] c.Tiles[a.chunkTileIndex(local)] = tile @@ -156,7 +156,7 @@ func (a *ChunkBasedAtlas) setTile(chunk int, local vector.Vector, tile byte) { } // setObject sets an object in a specific chunk -func (a *ChunkBasedAtlas) setObject(chunk int, local vector.Vector, object objects.Object) { +func (a *chunkBasedAtlas) setObject(chunk int, local vector.Vector, object objects.Object) { a.populate(chunk) c := a.Chunks[chunk] @@ -170,12 +170,12 @@ func (a *ChunkBasedAtlas) setObject(chunk int, local vector.Vector, object objec } // worldSpaceToChunkLocal gets a chunk local coordinate for a tile -func (a *ChunkBasedAtlas) worldSpaceToChunkLocal(v vector.Vector) vector.Vector { +func (a *chunkBasedAtlas) 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 *ChunkBasedAtlas) worldSpaceToChunkIndex(v vector.Vector) int { +func (a *chunkBasedAtlas) worldSpaceToChunkIndex(v vector.Vector) int { // Shift the vector by our current min v = v.Added(a.LowerBound.Negated()) @@ -191,7 +191,7 @@ func (a *ChunkBasedAtlas) worldSpaceToChunkIndex(v vector.Vector) int { } // chunkOriginInWorldSpace returns the origin of the chunk in world space -func (a *ChunkBasedAtlas) chunkOriginInWorldSpace(chunk int) vector.Vector { +func (a *chunkBasedAtlas) chunkOriginInWorldSpace(chunk int) vector.Vector { // Calculate the width width := a.UpperBound.X - a.LowerBound.X widthInChunks := width / a.ChunkSize @@ -208,7 +208,7 @@ func (a *ChunkBasedAtlas) chunkOriginInWorldSpace(chunk int) vector.Vector { } // getNewBounds gets new lower and upper bounds for the world space given a vector -func (a *ChunkBasedAtlas) getNewBounds(v vector.Vector) (lower vector.Vector, upper vector.Vector) { +func (a *chunkBasedAtlas) 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) @@ -224,7 +224,7 @@ func (a *ChunkBasedAtlas) getNewBounds(v vector.Vector) (lower vector.Vector, up } // worldSpaceToTrunkWithGrow will expand the current atlas for a given world space position if needed -func (a *ChunkBasedAtlas) worldSpaceToChunkWithGrow(v vector.Vector) int { +func (a *chunkBasedAtlas) 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) @@ -236,7 +236,7 @@ func (a *ChunkBasedAtlas) worldSpaceToChunkWithGrow(v vector.Vector) int { size = size.Divided(a.ChunkSize) // Create the new empty atlas - newAtlas := ChunkBasedAtlas{ + newAtlas := chunkBasedAtlas{ ChunkSize: a.ChunkSize, LowerBound: lower, UpperBound: upper, From d6349d081eaa74e47dacee1008b9cf467f2983fb Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 16:59:55 +0100 Subject: [PATCH 06/18] Clear the tile before warping to it --- pkg/game/world_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pkg/game/world_test.go b/pkg/game/world_test.go index 35c0a22..262a7e9 100644 --- a/pkg/game/world_test.go +++ b/pkg/game/world_test.go @@ -395,6 +395,7 @@ 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") // Warp B outside of the range of A + world.Atlas.SetObject(vector.Vector{X: ra.Range, Y: 0}, objects.Object{Type: objects.None}) assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range, Y: 0})) // Broadcast from a again @@ -411,6 +412,7 @@ 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") // Warp B outside of the range of A + world.Atlas.SetObject(vector.Vector{X: ra.Range + 1, Y: 0}, objects.Object{Type: objects.None}) assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range + 1, Y: 0})) // Broadcast from a again From c1267829ac6b95834cf41a925fe7fe5ef9b29bb6 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 17:00:30 +0100 Subject: [PATCH 07/18] Clear out genproto mod require --- go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/go.mod b/go.mod index db01c84..32caba4 100644 --- a/go.mod +++ b/go.mod @@ -14,7 +14,6 @@ require ( golang.org/x/net v0.0.0-20200602114024-627f9648deb9 golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980 // 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/protobuf v1.25.0 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect From dc2800fa5461de76f35e12a12c361c9e20a18ea1 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 17:09:47 +0100 Subject: [PATCH 08/18] Move Accountant behind an interface --- cmd/rove-server/internal/server.go | 4 +- pkg/accounts/accounts.go | 93 +++++------------------------- pkg/accounts/accounts_test.go | 9 +-- pkg/accounts/simpleAccountant.go | 90 +++++++++++++++++++++++++++++ 4 files changed, 111 insertions(+), 85 deletions(-) create mode 100644 pkg/accounts/simpleAccountant.go diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go index ff98f76..a38e20d 100644 --- a/cmd/rove-server/internal/server.go +++ b/cmd/rove-server/internal/server.go @@ -29,7 +29,7 @@ type Server struct { world *game.World // Accountant - accountant *accounts.Accountant + accountant accounts.Accountant // gRPC server netListener net.Listener @@ -81,7 +81,7 @@ func NewServer(opts ...ServerOption) *Server { persistence: EphemeralData, schedule: cron.New(), world: game.NewWorld(32), - accountant: accounts.NewAccountant(), + accountant: accounts.NewSimpleAccountant(), } // Apply all options diff --git a/pkg/accounts/accounts.go b/pkg/accounts/accounts.go index 08f3ee3..69508c0 100644 --- a/pkg/accounts/accounts.go +++ b/pkg/accounts/accounts.go @@ -1,11 +1,22 @@ package accounts -import ( - "fmt" - "time" +// 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) - "github.com/google/uuid" -) + // 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 { @@ -15,75 +26,3 @@ type Account struct { // 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"` -} - -// NewAccountant creates a new accountant -func NewAccountant() *Accountant { - return &Accountant{ - Accounts: make(map[string]Account), - } -} - -// RegisterAccount adds an account to the set of internal accounts -func (a *Accountant) RegisterAccount(name string) (acc Account, err error) { - - // Set up the account info - acc.Name = name - acc.Data = make(map[string]string) - - // Verify this acount isn't already registered - for _, a := range a.Accounts { - if a.Name == acc.Name { - return Account{}, fmt.Errorf("account name already registered: %s", a.Name) - } - } - - // Set the creation time - acc.Data["created"] = time.Now().String() - - // Create a secret - acc.Data["secret"] = uuid.New().String() - - // Simply add the account to the map - a.Accounts[acc.Name] = acc - - return -} - -// VerifySecret verifies if an account secret is correct -func (a *Accountant) VerifySecret(account string, secret string) (bool, error) { - // Find the account matching the ID - if this, ok := a.Accounts[account]; ok { - return this.Data["secret"] == secret, nil - } - - return false, fmt.Errorf("no account found for id: %s", account) -} - -// AssignData assigns data to an account -func (a *Accountant) AssignData(account string, key string, value string) error { - - // Find the account matching the ID - if this, ok := a.Accounts[account]; ok { - this.Data[key] = value - a.Accounts[account] = this - } else { - return fmt.Errorf("no account found for id: %s", account) - } - - return nil -} - -// GetValue gets the rover rover for the account -func (a *Accountant) GetValue(account string, key string) (string, error) { - // Find the account matching the ID - this, ok := a.Accounts[account] - if !ok { - return "", fmt.Errorf("no account found for id: %s", account) - } - return this.Data[key], nil -} diff --git a/pkg/accounts/accounts_test.go b/pkg/accounts/accounts_test.go index 893c57d..bd2416f 100644 --- a/pkg/accounts/accounts_test.go +++ b/pkg/accounts/accounts_test.go @@ -8,7 +8,7 @@ import ( func TestNewAccountant(t *testing.T) { // Very basic verify here for now - accountant := NewAccountant() + accountant := NewSimpleAccountant() if accountant == nil { t.Error("Failed to create accountant") } @@ -16,7 +16,7 @@ func TestNewAccountant(t *testing.T) { func TestAccountant_RegisterAccount(t *testing.T) { - accountant := NewAccountant() + accountant := NewSimpleAccountant() // Start by making two accounts @@ -44,10 +44,7 @@ func TestAccountant_RegisterAccount(t *testing.T) { } func TestAccountant_AssignGetData(t *testing.T) { - accountant := NewAccountant() - if len(accountant.Accounts) != 0 { - t.Error("New accountant created with non-zero account number") - } + accountant := NewSimpleAccountant() name := uuid.New().String() a, err := accountant.RegisterAccount(name) diff --git a/pkg/accounts/simpleAccountant.go b/pkg/accounts/simpleAccountant.go new file mode 100644 index 0000000..023fe2f --- /dev/null +++ b/pkg/accounts/simpleAccountant.go @@ -0,0 +1,90 @@ +package accounts + +import ( + "fmt" + "time" + + "github.com/google/uuid" +) + +// SimpleAccountant manages a set of accounts +type SimpleAccountant struct { + Accounts map[string]Account `json:"accounts"` +} + +// NewSimpleAccountant creates a new accountant +func NewSimpleAccountant() Accountant { + return &SimpleAccountant{ + Accounts: make(map[string]Account), + } +} + +// RegisterAccount adds an account to the set of internal accounts +func (a *SimpleAccountant) RegisterAccount(name string) (acc Account, err error) { + + // Set up the account info + acc.Name = name + acc.Data = make(map[string]string) + + // Verify this acount isn't already registered + for _, a := range a.Accounts { + if a.Name == acc.Name { + return Account{}, fmt.Errorf("account name already registered: %s", a.Name) + } + } + + // Set the creation time + acc.Data["created"] = time.Now().String() + + // Create a secret + acc.Data["secret"] = uuid.New().String() + + // Simply add the account to the map + a.Accounts[acc.Name] = acc + + return +} + +// VerifySecret verifies if an account secret is correct +func (a *SimpleAccountant) VerifySecret(account string, secret string) (bool, error) { + // Find the account matching the ID + if this, ok := a.Accounts[account]; ok { + return this.Data["secret"] == secret, nil + } + + 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 +func (a *SimpleAccountant) AssignData(account string, key string, value string) error { + + // Find the account matching the ID + if this, ok := a.Accounts[account]; ok { + this.Data[key] = value + a.Accounts[account] = this + } else { + return fmt.Errorf("no account found for id: %s", account) + } + + return nil +} + +// GetValue gets the rover rover for the account +func (a *SimpleAccountant) GetValue(account string, key string) (string, error) { + // Find the account matching the ID + this, ok := a.Accounts[account] + if !ok { + return "", fmt.Errorf("no account found for id: %s", account) + } + return this.Data[key], nil +} From b451ea519deb0c05668b3b47d3f0e1de57e18d67 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 17:21:59 +0100 Subject: [PATCH 09/18] Make sure the accounts are saved as well --- cmd/rove-server/internal/server.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go index a38e20d..5ccd004 100644 --- a/cmd/rove-server/internal/server.go +++ b/cmd/rove-server/internal/server.go @@ -189,7 +189,7 @@ func (s *Server) SaveWorld() error { if s.persistence == PersistentData { s.world.RLock() defer s.world.RUnlock() - if err := persistence.SaveAll("world", s.world); err != nil { + if err := persistence.SaveAll("world", s.world, "accounts", s.accountant); err != nil { return fmt.Errorf("failed to save out persistent data: %s", err) } } @@ -201,7 +201,7 @@ func (s *Server) LoadWorld() error { if s.persistence == PersistentData { s.world.Lock() defer s.world.Unlock() - if err := persistence.LoadAll("world", &s.world); err != nil { + if err := persistence.LoadAll("world", &s.world, "accounts", &s.accountant); err != nil { return err } } From b534ac0516947030772da2f3197288d38df10e15 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:01:35 +0100 Subject: [PATCH 10/18] Rename generated rove package to roveapi and the game package to rove --- Makefile | 4 +- README.md | 2 +- cmd/rove-server/internal/routes.go | 60 +-- cmd/rove-server/internal/server.go | 8 +- cmd/rove/main.go | 40 +- pkg/{game => rove}/command.go | 6 +- pkg/{game => rove}/command_test.go | 10 +- pkg/{game => rove}/rover.go | 2 +- pkg/{game => rove}/world.go | 24 +- pkg/{game => rove}/world_test.go | 8 +- .../rove.pb.go => roveapi/roveapi.pb.go} | 495 +++++++++--------- .../rove.proto => roveapi/roveapi.proto} | 4 +- 12 files changed, 334 insertions(+), 329 deletions(-) rename pkg/{game => rove}/command.go (75%) rename pkg/{game => rove}/command_test.go (85%) rename pkg/{game => rove}/rover.go (99%) rename pkg/{game => rove}/world.go (97%) rename pkg/{game => rove}/world_test.go (98%) rename pkg/{rove/rove.pb.go => roveapi/roveapi.pb.go} (65%) rename proto/{rove/rove.proto => roveapi/roveapi.proto} (98%) diff --git a/Makefile b/Makefile index 0ef8cd7..b28ac4f 100644 --- a/Makefile +++ b/Makefile @@ -18,8 +18,8 @@ gen: github.com/golang/protobuf/protoc-gen-go go mod download @echo Generating rove server gRPC and gateway - protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:pkg/ proto/rove/rove.proto - protoc --proto_path proto --grpc-gateway_out=paths=source_relative:pkg/ proto/rove/rove.proto + protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:pkg/ proto/roveapi/roveapi.proto + protoc --proto_path proto --grpc-gateway_out=paths=source_relative:pkg/ proto/roveapi/roveapi.proto test: @echo Unit tests diff --git a/README.md b/README.md index 8846cc3..445ecac 100644 --- a/README.md +++ b/README.md @@ -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. -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. diff --git a/cmd/rove-server/internal/routes.go b/cmd/rove-server/internal/routes.go index e533cbf..8e8706c 100644 --- a/cmd/rove-server/internal/routes.go +++ b/cmd/rove-server/internal/routes.go @@ -5,14 +5,14 @@ import ( "fmt" "log" - "github.com/mdiluz/rove/pkg/game" "github.com/mdiluz/rove/pkg/rove" + "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/version" ) // ServerStatus returns the status of the current server to a gRPC request -func (s *Server) ServerStatus(context.Context, *rove.ServerStatusRequest) (*rove.ServerStatusResponse, error) { - response := &rove.ServerStatusResponse{ +func (s *Server) ServerStatus(context.Context, *roveapi.ServerStatusRequest) (*roveapi.ServerStatusResponse, error) { + response := &roveapi.ServerStatusResponse{ Ready: true, Version: version.Version, 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 -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) 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) } else { - return &rove.RegisterResponse{ - Account: &rove.Account{ + return &roveapi.RegisterResponse{ + Account: &roveapi.Account{ Name: acc.Name, 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 -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) 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) - var incoming, queued []*rove.Command + var incoming, queued []*roveapi.Command for _, i := range i { - c := &rove.Command{ + c := &roveapi.Command{ Command: i.Command, } switch i.Command { - case rove.CommandType_move: - c.Data = &rove.Command_Bearing{ + case roveapi.CommandType_move: + c.Data = &roveapi.Command_Bearing{ Bearing: i.Bearing, } - case rove.CommandType_broadcast: - c.Data = &rove.Command_Message{ + case roveapi.CommandType_broadcast: + c.Data = &roveapi.Command_Message{ Message: i.Message, } } incoming = append(incoming, c) } for _, q := range q { - c := &rove.Command{ + c := &roveapi.Command{ Command: q.Command, } switch q.Command { - case rove.CommandType_move: - c.Data = &rove.Command_Bearing{ + case roveapi.CommandType_move: + c.Data = &roveapi.Command_Bearing{ Bearing: q.Bearing, } - case rove.CommandType_broadcast: - c.Data = &rove.Command_Message{ + case roveapi.CommandType_broadcast: + c.Data = &roveapi.Command_Message{ Message: q.Message, } } queued = append(queued, c) } - var logs []*rove.Log + var logs []*roveapi.Log for _, log := range rover.Logs { - logs = append(logs, &rove.Log{ + logs = append(logs, &roveapi.Log{ Text: log.Text, 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, - Position: &rove.Vector{ + Position: &roveapi.Vector{ X: int32(rover.Pos.X), 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 -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) 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) } - response := &rove.RadarResponse{} + response := &roveapi.RadarResponse{} resp, err := s.accountant.GetValue(req.Account.Name, "rover") 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 -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) 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 } - var cmds []game.Command + var cmds []rove.Command for _, c := range req.Commands { - n := game.Command{ + n := rove.Command{ Command: c.Command, } switch c.Command { - case rove.CommandType_move: + case roveapi.CommandType_move: n.Bearing = c.GetBearing() - case rove.CommandType_broadcast: + case roveapi.CommandType_broadcast: n.Message = c.GetMessage() } cmds = append(cmds, n) @@ -205,5 +205,5 @@ func (s *Server) Command(ctx context.Context, req *rove.CommandRequest) (*rove.C return nil, err } - return &rove.CommandResponse{}, nil + return &roveapi.CommandResponse{}, nil } diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go index 5ccd004..f633601 100644 --- a/cmd/rove-server/internal/server.go +++ b/cmd/rove-server/internal/server.go @@ -7,9 +7,9 @@ import ( "sync" "github.com/mdiluz/rove/pkg/accounts" - "github.com/mdiluz/rove/pkg/game" "github.com/mdiluz/rove/pkg/persistence" "github.com/mdiluz/rove/pkg/rove" + "github.com/mdiluz/rove/pkg/roveapi" "github.com/robfig/cron" "google.golang.org/grpc" ) @@ -26,7 +26,7 @@ const ( type Server struct { // Internal state - world *game.World + world *rove.World // Accountant accountant accounts.Accountant @@ -80,7 +80,7 @@ func NewServer(opts ...ServerOption) *Server { address: "", persistence: EphemeralData, schedule: cron.New(), - world: game.NewWorld(32), + world: rove.NewWorld(32), accountant: accounts.NewSimpleAccountant(), } @@ -109,7 +109,7 @@ func (s *Server) Initialise(fillWorld bool) (err error) { log.Fatalf("failed to listen: %v", err) } s.grpcServ = grpc.NewServer() - rove.RegisterRoveServer(s.grpcServ, s) + roveapi.RegisterRoveServer(s.grpcServ, s) return nil } diff --git a/cmd/rove/main.go b/cmd/rove/main.go index 5f51e32..af48a61 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -13,7 +13,7 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/rove" + "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/version" "golang.org/x/net/context" "google.golang.org/grpc" @@ -66,7 +66,7 @@ func ConfigPath() string { if len(override) > 0 { datapath = override } - datapath = path.Join(datapath, "rove.json") + datapath = path.Join(datapath, "roveapi.json") return datapath } @@ -163,14 +163,14 @@ func InnerMain(command string, args ...string) error { if err != nil { return err } - var client = rove.NewRoveClient(clientConn) + var client = roveapi.NewRoveClient(clientConn) ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() // Handle all the commands switch command { case "server-status": - response, err := client.ServerStatus(ctx, &rove.ServerStatusRequest{}) + response, err := client.ServerStatus(ctx, &roveapi.ServerStatusRequest{}) switch { case err != nil: return err @@ -188,7 +188,7 @@ func InnerMain(command string, args ...string) error { 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], }) switch { @@ -209,7 +209,7 @@ func InnerMain(command string, args ...string) error { } // Iterate through each command - var commands []*rove.Command + var commands []*roveapi.Command for i := 0; i < len(args); i++ { switch args[i] { case "move": @@ -220,9 +220,9 @@ func InnerMain(command string, args ...string) error { return err } commands = append(commands, - &rove.Command{ - Command: rove.CommandType_move, - Data: &rove.Command_Bearing{Bearing: args[i]}, + &roveapi.Command{ + Command: roveapi.CommandType_move, + Data: &roveapi.Command_Bearing{Bearing: args[i]}, }, ) case "broadcast": @@ -233,23 +233,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]) } commands = append(commands, - &rove.Command{ - Command: rove.CommandType_broadcast, - Data: &rove.Command_Message{Message: []byte(args[i])}, + &roveapi.Command{ + Command: roveapi.CommandType_broadcast, + Data: &roveapi.Command_Message{Message: []byte(args[i])}, }, ) default: // By default just use the command literally commands = append(commands, - &rove.Command{ - Command: rove.CommandType(rove.CommandType_value[args[i]]), + &roveapi.Command{ + Command: roveapi.CommandType(roveapi.CommandType_value[args[i]]), }, ) } } - _, err := client.Command(ctx, &rove.CommandRequest{ - Account: &rove.Account{ + _, err := client.Command(ctx, &roveapi.CommandRequest{ + Account: &roveapi.Account{ Name: config.Account.Name, Secret: config.Account.Secret, }, @@ -269,8 +269,8 @@ func InnerMain(command string, args ...string) error { return err } - response, err := client.Radar(ctx, &rove.RadarRequest{ - Account: &rove.Account{ + response, err := client.Radar(ctx, &roveapi.RadarRequest{ + Account: &roveapi.Account{ Name: config.Account.Name, Secret: config.Account.Secret, }, @@ -306,8 +306,8 @@ func InnerMain(command string, args ...string) error { return err } - response, err := client.Status(ctx, &rove.StatusRequest{ - Account: &rove.Account{ + response, err := client.Status(ctx, &roveapi.StatusRequest{ + Account: &roveapi.Account{ Name: config.Account.Name, Secret: config.Account.Secret, }, diff --git a/pkg/game/command.go b/pkg/rove/command.go similarity index 75% rename from pkg/game/command.go rename to pkg/rove/command.go index b57f678..6016555 100644 --- a/pkg/game/command.go +++ b/pkg/rove/command.go @@ -1,10 +1,10 @@ -package game +package rove -import "github.com/mdiluz/rove/pkg/rove" +import "github.com/mdiluz/rove/pkg/roveapi" // Command represends a single command to execute type Command struct { - Command rove.CommandType `json:"command"` + Command roveapi.CommandType `json:"command"` // Used in the move command Bearing string `json:"bearing,omitempty"` diff --git a/pkg/game/command_test.go b/pkg/rove/command_test.go similarity index 85% rename from pkg/game/command_test.go rename to pkg/rove/command_test.go index 10ccbe5..f4f6bd9 100644 --- a/pkg/game/command_test.go +++ b/pkg/rove/command_test.go @@ -1,9 +1,9 @@ -package game +package rove import ( "testing" - "github.com/mdiluz/rove/pkg/rove" + "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/vector" "github.com/stretchr/testify/assert" ) @@ -21,7 +21,7 @@ func TestCommand_Move(t *testing.T) { assert.NoError(t, err, "Failed to set position for rover") // 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") // Tick the world @@ -47,7 +47,7 @@ func TestCommand_Recharge(t *testing.T) { assert.NoError(t, err, "Failed to set position for rover") // 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") // Tick the world @@ -57,7 +57,7 @@ func TestCommand_Recharge(t *testing.T) { rover, _ := world.GetRover(a) 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") // Tick the world diff --git a/pkg/game/rover.go b/pkg/rove/rover.go similarity index 99% rename from pkg/game/rover.go rename to pkg/rove/rover.go index 693ba9a..9ab0401 100644 --- a/pkg/game/rover.go +++ b/pkg/rove/rover.go @@ -1,4 +1,4 @@ -package game +package rove import ( "fmt" diff --git a/pkg/game/world.go b/pkg/rove/world.go similarity index 97% rename from pkg/game/world.go rename to pkg/rove/world.go index f7476fb..490747b 100644 --- a/pkg/game/world.go +++ b/pkg/rove/world.go @@ -1,4 +1,4 @@ -package game +package rove import ( "bufio" @@ -12,7 +12,7 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/rove" + "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/vector" ) @@ -430,11 +430,11 @@ func (w *World) Enqueue(rover string, commands ...Command) error { // First validate the commands for _, c := range commands { switch c.Command { - case rove.CommandType_move: + case roveapi.CommandType_move: if _, err := bearing.FromString(c.Bearing); err != nil { return fmt.Errorf("unknown bearing: %s", c.Bearing) } - case rove.CommandType_broadcast: + case roveapi.CommandType_broadcast: if len(c.Message) > 3 { return fmt.Errorf("too many characters in message (limit 3): %d", len(c.Message)) } @@ -443,9 +443,9 @@ func (w *World) Enqueue(rover string, commands ...Command) error { return fmt.Errorf("invalid message character: %c", b) } } - case rove.CommandType_stash: - case rove.CommandType_repair: - case rove.CommandType_recharge: + case roveapi.CommandType_stash: + case roveapi.CommandType_repair: + case roveapi.CommandType_recharge: // Nothing to verify default: return fmt.Errorf("unknown command: %s", c.Command) @@ -509,19 +509,19 @@ func (w *World) ExecuteCommand(c *Command, rover string) (err error) { log.Printf("Executing command: %+v for %s\n", *c, rover) switch c.Command { - case rove.CommandType_move: + case roveapi.CommandType_move: if dir, err := bearing.FromString(c.Bearing); err != nil { return err } else if _, err := w.MoveRover(rover, dir); err != nil { return err } - case rove.CommandType_stash: + case roveapi.CommandType_stash: if _, err := w.RoverStash(rover); err != nil { return err } - case rove.CommandType_repair: + case roveapi.CommandType_repair: r, err := w.GetRover(rover) if err != nil { return err @@ -533,12 +533,12 @@ func (w *World) ExecuteCommand(c *Command, rover string) (err error) { r.AddLogEntryf("repaired self to %d", r.Integrity) w.Rovers[rover] = r } - case rove.CommandType_recharge: + case roveapi.CommandType_recharge: _, err := w.RoverRecharge(rover) if err != nil { return err } - case rove.CommandType_broadcast: + case roveapi.CommandType_broadcast: if err := w.RoverBroadcast(rover, c.Message); err != nil { return err } diff --git a/pkg/game/world_test.go b/pkg/rove/world_test.go similarity index 98% rename from pkg/game/world_test.go rename to pkg/rove/world_test.go index 262a7e9..33ae973 100644 --- a/pkg/game/world_test.go +++ b/pkg/rove/world_test.go @@ -1,4 +1,4 @@ -package game +package rove import ( "testing" @@ -6,7 +6,7 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/bearing" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/rove" + "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/vector" "github.com/stretchr/testify/assert" ) @@ -273,7 +273,7 @@ func TestWorld_RoverRepair(t *testing.T) { assert.NoError(t, err, "couldn't get rover info") assert.Equal(t, originalInfo.Integrity-1, newinfo.Integrity, "rover should have lost integrity") - err = world.ExecuteCommand(&Command{Command: rove.CommandType_repair}, a) + err = world.ExecuteCommand(&Command{Command: roveapi.CommandType_repair}, a) assert.NoError(t, err, "Failed to repair rover") newinfo, err = world.GetRover(a) @@ -287,7 +287,7 @@ func TestWorld_RoverRepair(t *testing.T) { assert.NoError(t, err, "Failed to stash") assert.Equal(t, objects.SmallRock, 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") newinfo, err = world.GetRover(a) diff --git a/pkg/rove/rove.pb.go b/pkg/roveapi/roveapi.pb.go similarity index 65% rename from pkg/rove/rove.pb.go rename to pkg/roveapi/roveapi.pb.go index 2186fd9..491231d 100644 --- a/pkg/rove/rove.pb.go +++ b/pkg/roveapi/roveapi.pb.go @@ -2,14 +2,14 @@ // versions: // protoc-gen-go v1.25.0 // protoc v3.6.1 -// source: rove/rove.proto +// source: roveapi/roveapi.proto // Rove // // Rove is an asychronous nomadic game about exploring a planet as part of a // loose community -package rove +package roveapi import ( context "context" @@ -82,11 +82,11 @@ func (x CommandType) String() string { } 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 { - return &file_rove_rove_proto_enumTypes[0] + return &file_roveapi_roveapi_proto_enumTypes[0] } func (x CommandType) Number() protoreflect.EnumNumber { @@ -95,7 +95,7 @@ func (x CommandType) Number() protoreflect.EnumNumber { // Deprecated: Use CommandType.Descriptor instead. 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 @@ -108,7 +108,7 @@ type ServerStatusRequest struct { func (x *ServerStatusRequest) Reset() { *x = ServerStatusRequest{} 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.StoreMessageInfo(mi) } @@ -121,7 +121,7 @@ func (x *ServerStatusRequest) String() string { func (*ServerStatusRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -134,7 +134,7 @@ func (x *ServerStatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use ServerStatusRequest.ProtoReflect.Descriptor instead. 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 @@ -158,7 +158,7 @@ type ServerStatusResponse struct { func (x *ServerStatusResponse) Reset() { *x = ServerStatusResponse{} 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.StoreMessageInfo(mi) } @@ -171,7 +171,7 @@ func (x *ServerStatusResponse) String() string { func (*ServerStatusResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -184,7 +184,7 @@ func (x *ServerStatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use ServerStatusResponse.ProtoReflect.Descriptor instead. 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 { @@ -235,7 +235,7 @@ type RegisterRequest struct { func (x *RegisterRequest) Reset() { *x = RegisterRequest{} 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.StoreMessageInfo(mi) } @@ -248,7 +248,7 @@ func (x *RegisterRequest) String() string { func (*RegisterRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -261,7 +261,7 @@ func (x *RegisterRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterRequest.ProtoReflect.Descriptor instead. 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 { @@ -286,7 +286,7 @@ type Account struct { func (x *Account) Reset() { *x = Account{} 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.StoreMessageInfo(mi) } @@ -299,7 +299,7 @@ func (x *Account) String() string { func (*Account) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -312,7 +312,7 @@ func (x *Account) ProtoReflect() protoreflect.Message { // Deprecated: Use Account.ProtoReflect.Descriptor instead. 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 { @@ -342,7 +342,7 @@ type RegisterResponse struct { func (x *RegisterResponse) Reset() { *x = RegisterResponse{} 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.StoreMessageInfo(mi) } @@ -355,7 +355,7 @@ func (x *RegisterResponse) String() string { func (*RegisterResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -368,7 +368,7 @@ func (x *RegisterResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RegisterResponse.ProtoReflect.Descriptor instead. 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 { @@ -385,7 +385,7 @@ type Command struct { unknownFields protoimpl.UnknownFields // 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: // *Command_Bearing // *Command_Message @@ -395,7 +395,7 @@ type Command struct { func (x *Command) Reset() { *x = Command{} 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.StoreMessageInfo(mi) } @@ -408,7 +408,7 @@ func (x *Command) String() string { func (*Command) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -421,7 +421,7 @@ func (x *Command) ProtoReflect() protoreflect.Message { // Deprecated: Use Command.ProtoReflect.Descriptor instead. 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 { @@ -488,7 +488,7 @@ type CommandRequest struct { func (x *CommandRequest) Reset() { *x = CommandRequest{} 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.StoreMessageInfo(mi) } @@ -501,7 +501,7 @@ func (x *CommandRequest) String() string { func (*CommandRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -514,7 +514,7 @@ func (x *CommandRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandRequest.ProtoReflect.Descriptor instead. 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 { @@ -541,7 +541,7 @@ type CommandResponse struct { func (x *CommandResponse) Reset() { *x = CommandResponse{} 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.StoreMessageInfo(mi) } @@ -554,7 +554,7 @@ func (x *CommandResponse) String() string { func (*CommandResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -567,7 +567,7 @@ func (x *CommandResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use CommandResponse.ProtoReflect.Descriptor instead. 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 @@ -583,7 +583,7 @@ type RadarRequest struct { func (x *RadarRequest) Reset() { *x = RadarRequest{} 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.StoreMessageInfo(mi) } @@ -596,7 +596,7 @@ func (x *RadarRequest) String() string { func (*RadarRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -609,7 +609,7 @@ func (x *RadarRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use RadarRequest.ProtoReflect.Descriptor instead. 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 { @@ -637,7 +637,7 @@ type RadarResponse struct { func (x *RadarResponse) Reset() { *x = RadarResponse{} 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.StoreMessageInfo(mi) } @@ -650,7 +650,7 @@ func (x *RadarResponse) String() string { func (*RadarResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -663,7 +663,7 @@ func (x *RadarResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use RadarResponse.ProtoReflect.Descriptor instead. 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 { @@ -700,7 +700,7 @@ type StatusRequest struct { func (x *StatusRequest) Reset() { *x = StatusRequest{} 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.StoreMessageInfo(mi) } @@ -713,7 +713,7 @@ func (x *StatusRequest) String() string { func (*StatusRequest) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -726,7 +726,7 @@ func (x *StatusRequest) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusRequest.ProtoReflect.Descriptor instead. 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 { @@ -751,7 +751,7 @@ type Log struct { func (x *Log) Reset() { *x = Log{} 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.StoreMessageInfo(mi) } @@ -764,7 +764,7 @@ func (x *Log) String() string { func (*Log) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -777,7 +777,7 @@ func (x *Log) ProtoReflect() protoreflect.Message { // Deprecated: Use Log.ProtoReflect.Descriptor instead. 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 { @@ -807,7 +807,7 @@ type Vector struct { func (x *Vector) Reset() { *x = Vector{} 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.StoreMessageInfo(mi) } @@ -820,7 +820,7 @@ func (x *Vector) String() string { func (*Vector) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -833,7 +833,7 @@ func (x *Vector) ProtoReflect() protoreflect.Message { // Deprecated: Use Vector.ProtoReflect.Descriptor instead. 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 { @@ -885,7 +885,7 @@ type StatusResponse struct { func (x *StatusResponse) Reset() { *x = StatusResponse{} 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.StoreMessageInfo(mi) } @@ -898,7 +898,7 @@ func (x *StatusResponse) String() string { func (*StatusResponse) ProtoMessage() {} 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 { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -911,7 +911,7 @@ func (x *StatusResponse) ProtoReflect() protoreflect.Message { // Deprecated: Use StatusResponse.ProtoReflect.Descriptor instead. 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 { @@ -998,174 +998,179 @@ func (x *StatusResponse) GetLogs() []*Log { return nil } -var File_rove_rove_proto protoreflect.FileDescriptor +var File_roveapi_roveapi_proto protoreflect.FileDescriptor -var file_rove_rove_proto_rawDesc = []byte{ - 0x0a, 0x0f, 0x72, 0x6f, 0x76, 0x65, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, - 0x6f, 0x12, 0x04, 0x72, 0x6f, 0x76, 0x65, 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, - 0x01, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, - 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, - 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, - 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, - 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, - 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, - 0x74, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x69, - 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x69, - 0x63, 0x6b, 0x22, 0x25, 0x0a, 0x0f, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, - 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, - 0x22, 0x3b, 0x0a, 0x10, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x27, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x76, 0x0a, - 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2b, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, - 0x61, 0x6e, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x11, 0x2e, 0x72, 0x6f, 0x76, 0x65, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, - 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, - 0x67, 0x12, 0x1a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, - 0x28, 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x22, 0x64, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, - 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x12, 0x29, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, - 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x22, 0x11, 0x0a, 0x0f, 0x43, - 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x37, - 0x0a, 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x27, - 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, - 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x55, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x61, 0x72, - 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, - 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, - 0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, - 0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x38, - 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, - 0x27, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, - 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, - 0x12, 0x0a, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, - 0x69, 0x6d, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x65, 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, - 0x72, 0x12, 0x0c, 0x0a, 0x01, 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, - 0x0c, 0x0a, 0x01, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0xb7, 0x03, - 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, - 0x6e, 0x61, 0x6d, 0x65, 0x12, 0x28, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x56, 0x65, - 0x63, 0x74, 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, - 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, - 0x61, 0x6e, 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, - 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, - 0x72, 0x79, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x05, - 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x1c, - 0x0a, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, - 0x05, 0x52, 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, - 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, - 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, - 0x67, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, - 0x12, 0x24, 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, - 0x65, 0x18, 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, - 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x39, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, - 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, - 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, - 0x73, 0x12, 0x35, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0d, 0x2e, 0x72, 0x6f, 0x76, 0x65, - 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x1d, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x09, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x4c, 0x6f, - 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x2a, 0x55, 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, - 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, - 0x12, 0x08, 0x0a, 0x04, 0x6d, 0x6f, 0x76, 0x65, 0x10, 0x01, 0x12, 0x09, 0x0a, 0x05, 0x73, 0x74, - 0x61, 0x73, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x10, - 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, - 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, 0x61, 0x73, 0x74, 0x10, 0x05, 0x32, 0xb1, - 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x47, 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x53, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x1a, 0x1a, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x3b, 0x0a, 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x15, 0x2e, 0x72, - 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, - 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x38, 0x0a, - 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, - 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x15, - 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x32, 0x0a, 0x05, 0x52, 0x61, 0x64, 0x61, 0x72, - 0x12, 0x12, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x1a, 0x13, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x52, 0x61, 0x64, 0x61, - 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x35, 0x0a, 0x06, 0x53, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x13, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x14, 0x2e, 0x72, 0x6f, 0x76, - 0x65, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x22, 0x00, 0x42, 0x21, 0x5a, 0x1f, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, - 0x2f, 0x6d, 0x64, 0x69, 0x6c, 0x75, 0x7a, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x2f, 0x70, 0x6b, 0x67, - 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, +var file_roveapi_roveapi_proto_rawDesc = []byte{ + 0x0a, 0x15, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, + 0x69, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, + 0x22, 0x15, 0x0a, 0x13, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0xa1, 0x01, 0x0a, 0x14, 0x53, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, 0x72, 0x65, + 0x61, 0x64, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x08, 0x52, 0x05, 0x72, 0x65, 0x61, 0x64, 0x79, + 0x12, 0x1a, 0x0a, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x74, 0x69, 0x63, 0x6b, 0x52, 0x61, 0x74, 0x65, 0x12, 0x20, 0x0a, 0x0b, + 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x0b, 0x63, 0x75, 0x72, 0x72, 0x65, 0x6e, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x12, 0x1b, + 0x0a, 0x09, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x74, 0x69, 0x63, 0x6b, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x08, 0x6e, 0x65, 0x78, 0x74, 0x54, 0x69, 0x63, 0x6b, 0x22, 0x25, 0x0a, 0x0f, 0x52, + 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, + 0x0a, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, + 0x6d, 0x65, 0x22, 0x35, 0x0a, 0x07, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x12, 0x12, 0x0a, + 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, + 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x06, 0x73, 0x65, 0x63, 0x72, 0x65, 0x74, 0x22, 0x3e, 0x0a, 0x10, 0x52, 0x65, 0x67, + 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x2a, 0x0a, + 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, + 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0x79, 0x0a, 0x07, 0x43, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x2e, 0x0a, 0x07, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x14, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x52, 0x07, 0x63, 0x6f, 0x6d, + 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x1a, 0x0a, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x07, 0x62, 0x65, 0x61, 0x72, 0x69, 0x6e, 0x67, + 0x12, 0x1a, 0x0a, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x48, 0x00, 0x52, 0x07, 0x6d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x42, 0x06, 0x0a, 0x04, + 0x64, 0x61, 0x74, 0x61, 0x22, 0x6a, 0x0a, 0x0e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, + 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, + 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x12, 0x2c, 0x0a, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x08, 0x63, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, + 0x22, 0x11, 0x0a, 0x0f, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x22, 0x3a, 0x0a, 0x0c, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x41, + 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, + 0x55, 0x0a, 0x0d, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x12, 0x14, 0x0a, 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x05, 0x72, 0x61, 0x6e, 0x67, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x74, 0x69, 0x6c, 0x65, 0x73, 0x12, 0x18, 0x0a, 0x07, + 0x6f, 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6f, + 0x62, 0x6a, 0x65, 0x63, 0x74, 0x73, 0x22, 0x3b, 0x0a, 0x0d, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x2a, 0x0a, 0x07, 0x61, 0x63, 0x63, 0x6f, 0x75, + 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, + 0x70, 0x69, 0x2e, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x52, 0x07, 0x61, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x22, 0x2d, 0x0a, 0x03, 0x4c, 0x6f, 0x67, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x69, 0x6d, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x74, 0x65, 0x78, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x65, + 0x78, 0x74, 0x22, 0x24, 0x0a, 0x06, 0x56, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x12, 0x0c, 0x0a, 0x01, + 0x78, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x78, 0x12, 0x0c, 0x0a, 0x01, 0x79, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x05, 0x52, 0x01, 0x79, 0x22, 0xc3, 0x03, 0x0a, 0x0e, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x6e, + 0x61, 0x6d, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x6e, 0x61, 0x6d, 0x65, 0x12, + 0x2b, 0x0a, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x0f, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x56, 0x65, 0x63, 0x74, + 0x6f, 0x72, 0x52, 0x08, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, 0x6e, 0x12, 0x14, 0x0a, 0x05, + 0x72, 0x61, 0x6e, 0x67, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x05, 0x72, 0x61, 0x6e, + 0x67, 0x65, 0x12, 0x1c, 0x0a, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x69, 0x6e, 0x76, 0x65, 0x6e, 0x74, 0x6f, 0x72, 0x79, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x05, 0x52, 0x08, 0x63, 0x61, 0x70, 0x61, 0x63, 0x69, 0x74, 0x79, 0x12, 0x1c, 0x0a, 0x09, + 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x06, 0x20, 0x01, 0x28, 0x05, 0x52, + 0x09, 0x69, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x10, 0x6d, 0x61, + 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x18, 0x07, + 0x20, 0x01, 0x28, 0x05, 0x52, 0x10, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x49, 0x6e, 0x74, + 0x65, 0x67, 0x72, 0x69, 0x74, 0x79, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x05, 0x52, 0x06, 0x63, 0x68, 0x61, 0x72, 0x67, 0x65, 0x12, 0x24, + 0x0a, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, 0x61, 0x72, 0x67, 0x65, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x05, 0x52, 0x0d, 0x6d, 0x61, 0x78, 0x69, 0x6d, 0x75, 0x6d, 0x43, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x12, 0x3c, 0x0a, 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, + 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0a, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, + 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, + 0x52, 0x10, 0x69, 0x6e, 0x63, 0x6f, 0x6d, 0x69, 0x6e, 0x67, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, + 0x64, 0x73, 0x12, 0x38, 0x0a, 0x0e, 0x71, 0x75, 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, + 0x61, 0x6e, 0x64, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x10, 0x2e, 0x72, 0x6f, 0x76, + 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x0e, 0x71, 0x75, + 0x65, 0x75, 0x65, 0x64, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x73, 0x12, 0x20, 0x0a, 0x04, + 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x0c, 0x2e, 0x72, 0x6f, 0x76, + 0x65, 0x61, 0x70, 0x69, 0x2e, 0x4c, 0x6f, 0x67, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x2a, 0x55, + 0x0a, 0x0b, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x54, 0x79, 0x70, 0x65, 0x12, 0x08, 0x0a, + 0x04, 0x6e, 0x6f, 0x6e, 0x65, 0x10, 0x00, 0x12, 0x08, 0x0a, 0x04, 0x6d, 0x6f, 0x76, 0x65, 0x10, + 0x01, 0x12, 0x09, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x73, 0x68, 0x10, 0x02, 0x12, 0x0a, 0x0a, 0x06, + 0x72, 0x65, 0x70, 0x61, 0x69, 0x72, 0x10, 0x03, 0x12, 0x0c, 0x0a, 0x08, 0x72, 0x65, 0x63, 0x68, + 0x61, 0x72, 0x67, 0x65, 0x10, 0x04, 0x12, 0x0d, 0x0a, 0x09, 0x62, 0x72, 0x6f, 0x61, 0x64, 0x63, + 0x61, 0x73, 0x74, 0x10, 0x05, 0x32, 0xcf, 0x02, 0x0a, 0x04, 0x52, 0x6f, 0x76, 0x65, 0x12, 0x4d, + 0x0a, 0x0c, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x1c, + 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x1d, 0x2e, 0x72, + 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x41, 0x0a, + 0x08, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x12, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, + 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x71, 0x75, + 0x65, 0x73, 0x74, 0x1a, 0x19, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x65, + 0x67, 0x69, 0x73, 0x74, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x3e, 0x0a, 0x07, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x12, 0x17, 0x2e, 0x72, 0x6f, + 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x1a, 0x18, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x43, + 0x6f, 0x6d, 0x6d, 0x61, 0x6e, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x38, 0x0a, 0x05, 0x52, 0x61, 0x64, 0x61, 0x72, 0x12, 0x15, 0x2e, 0x72, 0x6f, 0x76, 0x65, + 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, + 0x1a, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x52, 0x61, 0x64, 0x61, 0x72, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x3b, 0x0a, 0x06, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, + 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x24, 0x5a, 0x22, 0x67, 0x69, 0x74, 0x68, 0x75, + 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6d, 0x64, 0x69, 0x6c, 0x75, 0x7a, 0x2f, 0x72, 0x6f, 0x76, + 0x65, 0x2f, 0x70, 0x6b, 0x67, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( - file_rove_rove_proto_rawDescOnce sync.Once - file_rove_rove_proto_rawDescData = file_rove_rove_proto_rawDesc + file_roveapi_roveapi_proto_rawDescOnce sync.Once + file_roveapi_roveapi_proto_rawDescData = file_roveapi_roveapi_proto_rawDesc ) -func file_rove_rove_proto_rawDescGZIP() []byte { - file_rove_rove_proto_rawDescOnce.Do(func() { - file_rove_rove_proto_rawDescData = protoimpl.X.CompressGZIP(file_rove_rove_proto_rawDescData) +func file_roveapi_roveapi_proto_rawDescGZIP() []byte { + file_roveapi_roveapi_proto_rawDescOnce.Do(func() { + 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_rove_rove_proto_msgTypes = make([]protoimpl.MessageInfo, 14) -var file_rove_rove_proto_goTypes = []interface{}{ - (CommandType)(0), // 0: rove.CommandType - (*ServerStatusRequest)(nil), // 1: rove.ServerStatusRequest - (*ServerStatusResponse)(nil), // 2: rove.ServerStatusResponse - (*RegisterRequest)(nil), // 3: rove.RegisterRequest - (*Account)(nil), // 4: rove.Account - (*RegisterResponse)(nil), // 5: rove.RegisterResponse - (*Command)(nil), // 6: rove.Command - (*CommandRequest)(nil), // 7: rove.CommandRequest - (*CommandResponse)(nil), // 8: rove.CommandResponse - (*RadarRequest)(nil), // 9: rove.RadarRequest - (*RadarResponse)(nil), // 10: rove.RadarResponse - (*StatusRequest)(nil), // 11: rove.StatusRequest - (*Log)(nil), // 12: rove.Log - (*Vector)(nil), // 13: rove.Vector - (*StatusResponse)(nil), // 14: rove.StatusResponse +var file_roveapi_roveapi_proto_enumTypes = make([]protoimpl.EnumInfo, 1) +var file_roveapi_roveapi_proto_msgTypes = make([]protoimpl.MessageInfo, 14) +var file_roveapi_roveapi_proto_goTypes = []interface{}{ + (CommandType)(0), // 0: roveapi.CommandType + (*ServerStatusRequest)(nil), // 1: roveapi.ServerStatusRequest + (*ServerStatusResponse)(nil), // 2: roveapi.ServerStatusResponse + (*RegisterRequest)(nil), // 3: roveapi.RegisterRequest + (*Account)(nil), // 4: roveapi.Account + (*RegisterResponse)(nil), // 5: roveapi.RegisterResponse + (*Command)(nil), // 6: roveapi.Command + (*CommandRequest)(nil), // 7: roveapi.CommandRequest + (*CommandResponse)(nil), // 8: roveapi.CommandResponse + (*RadarRequest)(nil), // 9: roveapi.RadarRequest + (*RadarResponse)(nil), // 10: roveapi.RadarResponse + (*StatusRequest)(nil), // 11: roveapi.StatusRequest + (*Log)(nil), // 12: roveapi.Log + (*Vector)(nil), // 13: roveapi.Vector + (*StatusResponse)(nil), // 14: roveapi.StatusResponse } -var file_rove_rove_proto_depIdxs = []int32{ - 4, // 0: rove.RegisterResponse.account:type_name -> rove.Account - 0, // 1: rove.Command.command:type_name -> rove.CommandType - 4, // 2: rove.CommandRequest.account:type_name -> rove.Account - 6, // 3: rove.CommandRequest.commands:type_name -> rove.Command - 4, // 4: rove.RadarRequest.account:type_name -> rove.Account - 4, // 5: rove.StatusRequest.account:type_name -> rove.Account - 13, // 6: rove.StatusResponse.position:type_name -> rove.Vector - 6, // 7: rove.StatusResponse.incomingCommands:type_name -> rove.Command - 6, // 8: rove.StatusResponse.queuedCommands:type_name -> rove.Command - 12, // 9: rove.StatusResponse.logs:type_name -> rove.Log - 1, // 10: rove.Rove.ServerStatus:input_type -> rove.ServerStatusRequest - 3, // 11: rove.Rove.Register:input_type -> rove.RegisterRequest - 7, // 12: rove.Rove.Command:input_type -> rove.CommandRequest - 9, // 13: rove.Rove.Radar:input_type -> rove.RadarRequest - 11, // 14: rove.Rove.Status:input_type -> rove.StatusRequest - 2, // 15: rove.Rove.ServerStatus:output_type -> rove.ServerStatusResponse - 5, // 16: rove.Rove.Register:output_type -> rove.RegisterResponse - 8, // 17: rove.Rove.Command:output_type -> rove.CommandResponse - 10, // 18: rove.Rove.Radar:output_type -> rove.RadarResponse - 14, // 19: rove.Rove.Status:output_type -> rove.StatusResponse +var file_roveapi_roveapi_proto_depIdxs = []int32{ + 4, // 0: roveapi.RegisterResponse.account:type_name -> roveapi.Account + 0, // 1: roveapi.Command.command:type_name -> roveapi.CommandType + 4, // 2: roveapi.CommandRequest.account:type_name -> roveapi.Account + 6, // 3: roveapi.CommandRequest.commands:type_name -> roveapi.Command + 4, // 4: roveapi.RadarRequest.account:type_name -> roveapi.Account + 4, // 5: roveapi.StatusRequest.account:type_name -> roveapi.Account + 13, // 6: roveapi.StatusResponse.position:type_name -> roveapi.Vector + 6, // 7: roveapi.StatusResponse.incomingCommands:type_name -> roveapi.Command + 6, // 8: roveapi.StatusResponse.queuedCommands:type_name -> roveapi.Command + 12, // 9: roveapi.StatusResponse.logs:type_name -> roveapi.Log + 1, // 10: roveapi.Rove.ServerStatus:input_type -> roveapi.ServerStatusRequest + 3, // 11: roveapi.Rove.Register:input_type -> roveapi.RegisterRequest + 7, // 12: roveapi.Rove.Command:input_type -> roveapi.CommandRequest + 9, // 13: roveapi.Rove.Radar:input_type -> roveapi.RadarRequest + 11, // 14: roveapi.Rove.Status:input_type -> roveapi.StatusRequest + 2, // 15: roveapi.Rove.ServerStatus:output_type -> roveapi.ServerStatusResponse + 5, // 16: roveapi.Rove.Register:output_type -> roveapi.RegisterResponse + 8, // 17: roveapi.Rove.Command:output_type -> roveapi.CommandResponse + 10, // 18: roveapi.Rove.Radar:output_type -> roveapi.RadarResponse + 14, // 19: roveapi.Rove.Status:output_type -> roveapi.StatusResponse 15, // [15:20] is the sub-list for method output_type 10, // [10:15] is the sub-list for method input_type 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 } -func init() { file_rove_rove_proto_init() } -func file_rove_rove_proto_init() { - if File_rove_rove_proto != nil { +func init() { file_roveapi_roveapi_proto_init() } +func file_roveapi_roveapi_proto_init() { + if File_roveapi_roveapi_proto != nil { return } 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 { case 0: return &v.state @@ -1191,7 +1196,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1203,7 +1208,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1215,7 +1220,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1227,7 +1232,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1239,7 +1244,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1251,7 +1256,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1263,7 +1268,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1275,7 +1280,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1287,7 +1292,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1299,7 +1304,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1311,7 +1316,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1323,7 +1328,7 @@ func file_rove_rove_proto_init() { 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 { case 0: return &v.state @@ -1335,7 +1340,7 @@ func file_rove_rove_proto_init() { 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 { case 0: 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_Message)(nil), } @@ -1356,21 +1361,21 @@ func file_rove_rove_proto_init() { out := protoimpl.TypeBuilder{ File: protoimpl.DescBuilder{ GoPackagePath: reflect.TypeOf(x{}).PkgPath(), - RawDescriptor: file_rove_rove_proto_rawDesc, + RawDescriptor: file_roveapi_roveapi_proto_rawDesc, NumEnums: 1, NumMessages: 14, NumExtensions: 0, NumServices: 1, }, - GoTypes: file_rove_rove_proto_goTypes, - DependencyIndexes: file_rove_rove_proto_depIdxs, - EnumInfos: file_rove_rove_proto_enumTypes, - MessageInfos: file_rove_rove_proto_msgTypes, + GoTypes: file_roveapi_roveapi_proto_goTypes, + DependencyIndexes: file_roveapi_roveapi_proto_depIdxs, + EnumInfos: file_roveapi_roveapi_proto_enumTypes, + MessageInfos: file_roveapi_roveapi_proto_msgTypes, }.Build() - File_rove_rove_proto = out.File - file_rove_rove_proto_rawDesc = nil - file_rove_rove_proto_goTypes = nil - file_rove_rove_proto_depIdxs = nil + File_roveapi_roveapi_proto = out.File + file_roveapi_roveapi_proto_rawDesc = nil + file_roveapi_roveapi_proto_goTypes = nil + file_roveapi_roveapi_proto_depIdxs = nil } // 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { 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) { 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 { return nil, err } @@ -1512,7 +1517,7 @@ func _Rove_ServerStatus_Handler(srv interface{}, ctx context.Context, dec func(i } info := &grpc.UnaryServerInfo{ Server: srv, - FullMethod: "/rove.Rove/ServerStatus", + FullMethod: "/roveapi.Rove/ServerStatus", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/rove.Rove/Register", + FullMethod: "/roveapi.Rove/Register", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/rove.Rove/Command", + FullMethod: "/roveapi.Rove/Command", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/rove.Rove/Radar", + FullMethod: "/roveapi.Rove/Radar", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ Server: srv, - FullMethod: "/rove.Rove/Status", + FullMethod: "/roveapi.Rove/Status", } handler := func(ctx context.Context, req interface{}) (interface{}, error) { 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{ - ServiceName: "rove.Rove", + ServiceName: "roveapi.Rove", HandlerType: (*RoveServer)(nil), Methods: []grpc.MethodDesc{ { @@ -1618,5 +1623,5 @@ var _Rove_serviceDesc = grpc.ServiceDesc{ }, }, Streams: []grpc.StreamDesc{}, - Metadata: "rove/rove.proto", + Metadata: "roveapi/roveapi.proto", } diff --git a/proto/rove/rove.proto b/proto/roveapi/roveapi.proto similarity index 98% rename from proto/rove/rove.proto rename to proto/roveapi/roveapi.proto index ab0160e..f39d2a6 100644 --- a/proto/rove/rove.proto +++ b/proto/roveapi/roveapi.proto @@ -4,8 +4,8 @@ syntax = "proto3"; // // Rove is an asychronous nomadic game about exploring a planet as part of a // loose community -package rove; -option go_package = "github.com/mdiluz/rove/pkg/rove"; +package roveapi; +option go_package = "github.com/mdiluz/rove/pkg/roveapi"; // The Rove server hosts a single game session and world with multiple players service Rove { From 065f79cbb308bf60e4244cc30ba89d499ee44a07 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:11:38 +0100 Subject: [PATCH 11/18] Fix warping to non-empty space --- pkg/rove/world_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index 33ae973..52e8eec 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -144,6 +144,7 @@ func TestWorld_RoverStash(t *testing.T) { Y: 0.0, } + world.Atlas.SetObject(pos, objects.Object{Type: objects.None}) err = world.WarpRover(a, pos) assert.NoError(t, err, "Failed to set position for rover") From 97d3be000b7aba3748c1283c645b0ce01f131939 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:14:32 +0100 Subject: [PATCH 12/18] Re-order some World members --- pkg/rove/world.go | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/pkg/rove/world.go b/pkg/rove/world.go index 490747b..dcb39ea 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -18,32 +18,29 @@ import ( // World describes a self contained universe and everything in it 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 map[string]Rover `json:"rovers"` // Atlas represends the world map of chunks and tiles 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 CommandQueue map[string]CommandStream `json:"commands"` - // Incoming represents the set of commands to add to the queue at the end of the current tick CommandIncoming map[string]CommandStream `json:"incoming"` + // Mutex to lock around all world operations + worldMutex sync.RWMutex // Mutex to lock around command operations cmdMutex sync.RWMutex - // Set of possible words to use for names 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") From 5b1fe61097e81e3220c95dfacbca8f72c3b28a9d Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:22:59 +0100 Subject: [PATCH 13/18] Move vector into maths package --- pkg/atlas/atlas.go | 8 +- pkg/atlas/atlas_test.go | 114 +++++++++++++-------------- pkg/atlas/chunkAtlas.go | 43 +++++----- pkg/bearing/bearing.go | 6 +- pkg/bearing/bearing_test.go | 4 +- pkg/{vector => maths}/vector.go | 18 ++--- pkg/{vector => maths}/vector_test.go | 2 +- pkg/rove/command_test.go | 8 +- pkg/rove/rover.go | 4 +- pkg/rove/world.go | 24 +++--- pkg/rove/world_test.go | 34 ++++---- 11 files changed, 131 insertions(+), 134 deletions(-) rename pkg/{vector => maths}/vector.go (78%) rename pkg/{vector => maths}/vector_test.go (99%) diff --git a/pkg/atlas/atlas.go b/pkg/atlas/atlas.go index d4054db..22873f7 100644 --- a/pkg/atlas/atlas.go +++ b/pkg/atlas/atlas.go @@ -1,8 +1,8 @@ package atlas import ( + "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/vector" ) // Tile describes the type of terrain @@ -25,11 +25,11 @@ const ( // Atlas represents a 2D world atlas of tiles and objects type Atlas interface { // SetTile sets a location on the Atlas to a type of tile - SetTile(v vector.Vector, tile Tile) + SetTile(v maths.Vector, tile Tile) // SetObject will set a location on the Atlas to contain an object - SetObject(v vector.Vector, obj objects.Object) + SetObject(v maths.Vector, obj objects.Object) // QueryPosition queries a position on the atlas - QueryPosition(v vector.Vector) (byte, objects.Object) + QueryPosition(v maths.Vector) (byte, objects.Object) } diff --git a/pkg/atlas/atlas_test.go b/pkg/atlas/atlas_test.go index 1b1447e..4792e0b 100644 --- a/pkg/atlas/atlas_test.go +++ b/pkg/atlas/atlas_test.go @@ -4,8 +4,8 @@ import ( "fmt" "testing" + "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/vector" "github.com/stretchr/testify/assert" ) @@ -21,49 +21,49 @@ func TestAtlas_toChunk(t *testing.T) { assert.NotNil(t, a) // Get a tile to spawn the chunks - a.QueryPosition(vector.Vector{X: -1, Y: -1}) - a.QueryPosition(vector.Vector{X: 0, Y: 0}) + a.QueryPosition(maths.Vector{X: -1, Y: -1}) + a.QueryPosition(maths.Vector{X: 0, Y: 0}) assert.Equal(t, 2*2, len(a.Chunks)) // Chunks should look like: // 2 | 3 // ----- // 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 0, Y: -1}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 0, Y: -1}) 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -1, Y: 0}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -1, Y: 0}) assert.Equal(t, 2, chunkID) a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // 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)) - a.QueryPosition(vector.Vector{X: 1, Y: 1}) + a.QueryPosition(maths.Vector{X: 1, Y: 1}) assert.Equal(t, 2*2, len(a.Chunks)) // Chunks should look like: // 2 | 3 // ----- // 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: -2}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: -2}) 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 1}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -2, Y: 1}) assert.Equal(t, 2, chunkID) a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // 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)) - a.QueryPosition(vector.Vector{X: -3, Y: -3}) + a.QueryPosition(maths.Vector{X: -3, Y: -3}) assert.Equal(t, 4*4, len(a.Chunks)) // Chunks should look like: @@ -74,19 +74,19 @@ func TestAtlas_toChunk(t *testing.T) { // 4 | 5 || 6 | 7 // ---------------- // 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 1, Y: -3}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 1, Y: -3}) 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: -2, Y: 2}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: -2, Y: 2}) assert.Equal(t, 13, chunkID) a = NewChunkAtlas(3).(*chunkBasedAtlas) assert.NotNil(t, a) // 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)) // Chunks should look like: @@ -94,13 +94,13 @@ func TestAtlas_toChunk(t *testing.T) { // ------- // || 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 3, Y: 1}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 3, Y: 1}) 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) - chunkID = a.worldSpaceToChunkIndex(vector.Vector{X: 5, Y: 5}) + chunkID = a.worldSpaceToChunkIndex(maths.Vector{X: 5, Y: 5}) assert.Equal(t, 3, chunkID) } @@ -109,36 +109,36 @@ func TestAtlas_toWorld(t *testing.T) { assert.NotNil(t, a) // 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)) // Chunks should look like: // 2 | 3 // ----- // 0 | 1 - assert.Equal(t, vector.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: -1, Y: -1}, a.chunkOriginInWorldSpace(0)) + assert.Equal(t, maths.Vector{X: 0, Y: -1}, a.chunkOriginInWorldSpace(1)) a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // 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)) - a.QueryPosition(vector.Vector{X: 1, Y: 1}) + a.QueryPosition(maths.Vector{X: 1, Y: 1}) assert.Equal(t, 2*2, len(a.Chunks)) // Chunks should look like: // 2 | 3 // ----- // 0 | 1 - assert.Equal(t, vector.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: -2}, a.chunkOriginInWorldSpace(0)) + assert.Equal(t, maths.Vector{X: -2, Y: 0}, a.chunkOriginInWorldSpace(2)) a = NewChunkAtlas(2).(*chunkBasedAtlas) assert.NotNil(t, a) // 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)) - a.QueryPosition(vector.Vector{X: -3, Y: -3}) + a.QueryPosition(maths.Vector{X: -3, Y: -3}) assert.Equal(t, 4*4, len(a.Chunks)) // Chunks should look like: @@ -149,13 +149,13 @@ func TestAtlas_toWorld(t *testing.T) { // 4 | 5 || 6 | 7 // ---------------- // 0 | 1 || 2 | 3 - assert.Equal(t, vector.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: -4, Y: -4}, a.chunkOriginInWorldSpace(0)) + assert.Equal(t, maths.Vector{X: 2, Y: -2}, a.chunkOriginInWorldSpace(7)) a = NewChunkAtlas(3).(*chunkBasedAtlas) assert.NotNil(t, a) // 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)) // Chunks should look like: @@ -163,7 +163,7 @@ func TestAtlas_toWorld(t *testing.T) { // ------- // || 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) { @@ -171,13 +171,13 @@ func TestAtlas_GetSetTile(t *testing.T) { assert.NotNil(t, a) // Set the origin tile to 1 and test it - a.SetTile(vector.Vector{X: 0, Y: 0}, 1) - tile, _ := a.QueryPosition(vector.Vector{X: 0, Y: 0}) + a.SetTile(maths.Vector{X: 0, Y: 0}, 1) + tile, _ := a.QueryPosition(maths.Vector{X: 0, Y: 0}) assert.Equal(t, byte(1), tile) // Set another tile to 1 and test it - a.SetTile(vector.Vector{X: 5, Y: -2}, 2) - tile, _ = a.QueryPosition(vector.Vector{X: 5, Y: -2}) + a.SetTile(maths.Vector{X: 5, Y: -2}, 2) + tile, _ = a.QueryPosition(maths.Vector{X: 5, Y: -2}) assert.Equal(t, byte(2), tile) } @@ -186,13 +186,13 @@ func TestAtlas_GetSetObject(t *testing.T) { assert.NotNil(t, a) // Set the origin tile to 1 and test it - a.SetObject(vector.Vector{X: 0, Y: 0}, objects.Object{Type: objects.LargeRock}) - _, obj := a.QueryPosition(vector.Vector{X: 0, Y: 0}) + a.SetObject(maths.Vector{X: 0, Y: 0}, objects.Object{Type: objects.LargeRock}) + _, obj := a.QueryPosition(maths.Vector{X: 0, Y: 0}) assert.Equal(t, objects.Object{Type: objects.LargeRock}, obj) // Set another tile to 1 and test it - a.SetObject(vector.Vector{X: 5, Y: -2}, objects.Object{Type: objects.SmallRock}) - _, obj = a.QueryPosition(vector.Vector{X: 5, Y: -2}) + a.SetObject(maths.Vector{X: 5, Y: -2}, objects.Object{Type: objects.SmallRock}) + _, obj = a.QueryPosition(maths.Vector{X: 5, Y: -2}) assert.Equal(t, objects.Object{Type: objects.SmallRock}, obj) } @@ -203,27 +203,27 @@ func TestAtlas_Grown(t *testing.T) { assert.Equal(t, 1, len(a.Chunks)) // Set a few tiles to values - a.SetTile(vector.Vector{X: 0, Y: 0}, 1) - a.SetTile(vector.Vector{X: -1, Y: -1}, 2) - a.SetTile(vector.Vector{X: 1, Y: -2}, 3) + a.SetTile(maths.Vector{X: 0, Y: 0}, 1) + a.SetTile(maths.Vector{X: -1, Y: -1}, 2) + a.SetTile(maths.Vector{X: 1, Y: -2}, 3) // 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) - tile, _ = a.QueryPosition(vector.Vector{X: -1, Y: -1}) + tile, _ = a.QueryPosition(maths.Vector{X: -1, Y: -1}) 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) - tile, _ = a.QueryPosition(vector.Vector{X: 0, Y: 0}) + tile, _ = a.QueryPosition(maths.Vector{X: 0, Y: 0}) 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) - tile, _ = a.QueryPosition(vector.Vector{X: 1, Y: -2}) + tile, _ = a.QueryPosition(maths.Vector{X: 1, Y: -2}) assert.Equal(t, byte(3), tile) } @@ -237,7 +237,7 @@ func TestAtlas_GetSetCorrect(t *testing.T) { assert.NotNil(t, a) 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.SetObject(pos, objects.Object{Type: objects.LargeRock}) tile, obj := a.QueryPosition(pos) @@ -253,13 +253,13 @@ func TestAtlas_GetSetCorrect(t *testing.T) { func TestAtlas_WorldGen(t *testing.T) { a := NewChunkAtlas(8) // 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 num := 20 for j := num - 1; j >= 0; j-- { 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 { fmt.Printf("%c", o.Type) } else if t != byte(TileNone) { diff --git a/pkg/atlas/chunkAtlas.go b/pkg/atlas/chunkAtlas.go index 1caac1e..c3c969e 100644 --- a/pkg/atlas/chunkAtlas.go +++ b/pkg/atlas/chunkAtlas.go @@ -6,7 +6,6 @@ import ( "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/vector" "github.com/ojrac/opensimplex-go" ) @@ -27,10 +26,10 @@ type chunkBasedAtlas struct { 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"` + LowerBound maths.Vector `json:"lowerBound"` // UpperBound is the top left corner of the current chunks (curent chunks cover < this value) - UpperBound vector.Vector `json:"upperBound"` + UpperBound maths.Vector `json:"upperBound"` // ChunkSize is the x/y dimensions of each square chunk ChunkSize int `json:"chunksize"` @@ -54,8 +53,8 @@ func NewChunkAtlas(chunkSize int) Atlas { a := chunkBasedAtlas{ ChunkSize: chunkSize, Chunks: make([]chunk, 1), - LowerBound: vector.Vector{X: 0, Y: 0}, - UpperBound: vector.Vector{X: chunkSize, Y: chunkSize}, + LowerBound: maths.Vector{X: 0, Y: 0}, + UpperBound: maths.Vector{X: chunkSize, Y: chunkSize}, terrainNoise: opensimplex.New(noiseSeed), objectNoise: opensimplex.New(noiseSeed), } @@ -65,21 +64,21 @@ func NewChunkAtlas(chunkSize int) Atlas { } // SetTile sets an individual tile's kind -func (a *chunkBasedAtlas) SetTile(v vector.Vector, tile Tile) { +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 vector.Vector, obj objects.Object) { +func (a *chunkBasedAtlas) SetObject(v maths.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 *chunkBasedAtlas) QueryPosition(v vector.Vector) (byte, objects.Object) { +func (a *chunkBasedAtlas) QueryPosition(v maths.Vector) (byte, objects.Object) { c := a.worldSpaceToChunkWithGrow(v) local := a.worldSpaceToChunkLocal(v) a.populate(c) @@ -89,7 +88,7 @@ func (a *chunkBasedAtlas) QueryPosition(v vector.Vector) (byte, objects.Object) } // chunkTileID returns the tile index within a chunk -func (a *chunkBasedAtlas) chunkTileIndex(local vector.Vector) int { +func (a *chunkBasedAtlas) chunkTileIndex(local maths.Vector) int { return local.X + local.Y*a.ChunkSize } @@ -148,7 +147,7 @@ func (a *chunkBasedAtlas) populate(chunk int) { } // setTile sets a tile in a specific chunk -func (a *chunkBasedAtlas) setTile(chunk int, local vector.Vector, tile byte) { +func (a *chunkBasedAtlas) setTile(chunk int, local maths.Vector, tile byte) { a.populate(chunk) c := a.Chunks[chunk] c.Tiles[a.chunkTileIndex(local)] = tile @@ -156,7 +155,7 @@ func (a *chunkBasedAtlas) setTile(chunk int, local vector.Vector, tile byte) { } // setObject sets an object in a specific chunk -func (a *chunkBasedAtlas) setObject(chunk int, local vector.Vector, object objects.Object) { +func (a *chunkBasedAtlas) setObject(chunk int, local maths.Vector, object objects.Object) { a.populate(chunk) c := a.Chunks[chunk] @@ -170,12 +169,12 @@ func (a *chunkBasedAtlas) setObject(chunk int, local vector.Vector, object objec } // worldSpaceToChunkLocal gets a chunk local coordinate for a tile -func (a *chunkBasedAtlas) worldSpaceToChunkLocal(v vector.Vector) vector.Vector { - return vector.Vector{X: maths.Pmod(v.X, a.ChunkSize), Y: maths.Pmod(v.Y, a.ChunkSize)} +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 vector.Vector) int { +func (a *chunkBasedAtlas) worldSpaceToChunkIndex(v maths.Vector) int { // Shift the vector by our current min v = v.Added(a.LowerBound.Negated()) @@ -191,13 +190,13 @@ func (a *chunkBasedAtlas) worldSpaceToChunkIndex(v vector.Vector) int { } // chunkOriginInWorldSpace returns the origin of the chunk in world space -func (a *chunkBasedAtlas) chunkOriginInWorldSpace(chunk int) vector.Vector { +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 := vector.Vector{ + v := maths.Vector{ X: chunk % widthInChunks, Y: chunk / widthInChunks, } @@ -208,15 +207,15 @@ func (a *chunkBasedAtlas) chunkOriginInWorldSpace(chunk int) vector.Vector { } // getNewBounds gets new lower and upper bounds for the world space given a vector -func (a *chunkBasedAtlas) 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) +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 = vector.Vector{ + lower = maths.Vector{ X: maths.RoundDown(lower.X, a.ChunkSize), Y: maths.RoundDown(lower.Y, a.ChunkSize), } - upper = vector.Vector{ + upper = maths.Vector{ X: maths.RoundUp(upper.X, a.ChunkSize), Y: maths.RoundUp(upper.Y, a.ChunkSize), } @@ -224,7 +223,7 @@ func (a *chunkBasedAtlas) getNewBounds(v vector.Vector) (lower vector.Vector, up } // worldSpaceToTrunkWithGrow will expand the current atlas for a given world space position if needed -func (a *chunkBasedAtlas) worldSpaceToChunkWithGrow(v vector.Vector) int { +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) diff --git a/pkg/bearing/bearing.go b/pkg/bearing/bearing.go index 303c195..2eec3ba 100644 --- a/pkg/bearing/bearing.go +++ b/pkg/bearing/bearing.go @@ -4,7 +4,7 @@ import ( "fmt" "strings" - "github.com/mdiluz/rove/pkg/vector" + "github.com/mdiluz/rove/pkg/maths" ) // Bearing describes a compass direction @@ -67,7 +67,7 @@ func FromString(s string) (Bearing, error) { return -1, fmt.Errorf("unknown bearing: %s", s) } -var bearingVectors = []vector.Vector{ +var bearingVectors = []maths.Vector{ {X: 0, Y: 1}, // N {X: 1, Y: 1}, // NE {X: 1, Y: 0}, // E @@ -79,6 +79,6 @@ var bearingVectors = []vector.Vector{ } // Vector converts a Direction to a Vector -func (d Bearing) Vector() vector.Vector { +func (d Bearing) Vector() maths.Vector { return bearingVectors[d] } diff --git a/pkg/bearing/bearing_test.go b/pkg/bearing/bearing_test.go index 1232239..5bb36bc 100644 --- a/pkg/bearing/bearing_test.go +++ b/pkg/bearing/bearing_test.go @@ -3,7 +3,7 @@ package bearing import ( "testing" - "github.com/mdiluz/rove/pkg/vector" + "github.com/mdiluz/rove/pkg/maths" "github.com/stretchr/testify/assert" ) @@ -12,7 +12,7 @@ func TestDirection(t *testing.T) { assert.Equal(t, "North", dir.String()) assert.Equal(t, "N", dir.ShortString()) - assert.Equal(t, vector.Vector{X: 0, Y: 1}, dir.Vector()) + assert.Equal(t, maths.Vector{X: 0, Y: 1}, dir.Vector()) dir, err := FromString("N") assert.NoError(t, err) diff --git a/pkg/vector/vector.go b/pkg/maths/vector.go similarity index 78% rename from pkg/vector/vector.go rename to pkg/maths/vector.go index a8955be..2dd3bad 100644 --- a/pkg/vector/vector.go +++ b/pkg/maths/vector.go @@ -1,9 +1,7 @@ -package vector +package maths import ( "math" - - "github.com/mdiluz/rove/pkg/maths" ) // Vector desribes a 3D vector @@ -71,15 +69,15 @@ func (v Vector) DividedFloor(val int) Vector { // Abs returns an absolute version of the 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 -func Min(v1 Vector, v2 Vector) Vector { - return Vector{maths.Min(v1.X, v2.X), maths.Min(v1.Y, v2.Y)} +// Min2 returns the minimum values in both vectors +func Min2(v1 Vector, v2 Vector) Vector { + return Vector{Min(v1.X, v2.X), Min(v1.Y, v2.Y)} } -// Max returns the max values in both vectors -func Max(v1 Vector, v2 Vector) Vector { - return Vector{maths.Max(v1.X, v2.X), maths.Max(v1.Y, v2.Y)} +// Max2 returns the max values in both vectors +func Max2(v1 Vector, v2 Vector) Vector { + return Vector{Max(v1.X, v2.X), Max(v1.Y, v2.Y)} } diff --git a/pkg/vector/vector_test.go b/pkg/maths/vector_test.go similarity index 99% rename from pkg/vector/vector_test.go rename to pkg/maths/vector_test.go index 5d92136..4177780 100644 --- a/pkg/vector/vector_test.go +++ b/pkg/maths/vector_test.go @@ -1,4 +1,4 @@ -package vector +package maths import ( "math" diff --git a/pkg/rove/command_test.go b/pkg/rove/command_test.go index f4f6bd9..e01a487 100644 --- a/pkg/rove/command_test.go +++ b/pkg/rove/command_test.go @@ -3,8 +3,8 @@ package rove import ( "testing" + "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/roveapi" - "github.com/mdiluz/rove/pkg/vector" "github.com/stretchr/testify/assert" ) @@ -12,7 +12,7 @@ func TestCommand_Move(t *testing.T) { world := NewWorld(8) a, err := world.SpawnRover() assert.NoError(t, err) - pos := vector.Vector{ + pos := maths.Vector{ X: 1.0, Y: 2.0, } @@ -30,7 +30,7 @@ func TestCommand_Move(t *testing.T) { newPos, err := world.RoverPosition(a) 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") } @@ -38,7 +38,7 @@ func TestCommand_Recharge(t *testing.T) { world := NewWorld(8) a, err := world.SpawnRover() assert.NoError(t, err) - pos := vector.Vector{ + pos := maths.Vector{ X: 1.0, Y: 2.0, } diff --git a/pkg/rove/rover.go b/pkg/rove/rover.go index 9ab0401..45fb8f0 100644 --- a/pkg/rove/rover.go +++ b/pkg/rove/rover.go @@ -5,8 +5,8 @@ import ( "log" "time" + "github.com/mdiluz/rove/pkg/maths" "github.com/mdiluz/rove/pkg/objects" - "github.com/mdiluz/rove/pkg/vector" ) // RoverLogEntry describes a single log entry for the rover @@ -24,7 +24,7 @@ type Rover struct { Name string `json:"name"` // 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 int `json:"range"` diff --git a/pkg/rove/world.go b/pkg/rove/world.go index dcb39ea..eb2ef85 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -11,9 +11,9 @@ import ( "github.com/google/uuid" "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/roveapi" - "github.com/mdiluz/rove/pkg/vector" ) // World describes a self contained universe and everything in it @@ -103,7 +103,7 @@ func (w *World) SpawnRover() (string, error) { } // Spawn in a random place near the origin - rover.Pos = vector.Vector{ + rover.Pos = maths.Vector{ X: 10 - rand.Intn(20), Y: 10 - rand.Intn(20), } @@ -115,7 +115,7 @@ func (w *World) SpawnRover() (string, error) { break } else { // 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}) } } @@ -215,19 +215,19 @@ func (w *World) DestroyRover(rover string) error { } // 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() defer w.worldMutex.RUnlock() i, ok := w.Rovers[rover] if !ok { - return vector.Vector{}, fmt.Errorf("no rover matching id") + return maths.Vector{}, fmt.Errorf("no rover matching id") } return i.Pos, nil } // 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() defer w.worldMutex.Unlock() @@ -254,7 +254,7 @@ func (w *World) RoverInventory(rover string) ([]objects.Object, error) { } // 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() defer w.worldMutex.Unlock() @@ -279,13 +279,13 @@ func (w *World) WarpRover(rover string, pos vector.Vector) error { } // 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 bearing.Bearing) (maths.Vector, error) { w.worldMutex.Lock() defer w.worldMutex.Unlock() i, ok := w.Rovers[rover] 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 @@ -368,11 +368,11 @@ func (w *World) RadarFromRover(rover string) (radar []byte, objs []byte, err err roverPos := r.Pos // Get the radar min and max values - radarMin := vector.Vector{ + radarMin := maths.Vector{ X: roverPos.X - r.Range, Y: roverPos.Y - r.Range, } - radarMax := vector.Vector{ + radarMax := maths.Vector{ X: roverPos.X + r.Range, Y: roverPos.Y + r.Range, } @@ -382,7 +382,7 @@ func (w *World) RadarFromRover(rover string) (radar []byte, objs []byte, err err objs = make([]byte, radarSpan*radarSpan) for j := radarMin.Y; j <= radarMax.Y; j++ { 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) diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index 52e8eec..89ea9c7 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -5,9 +5,9 @@ import ( "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/roveapi" - "github.com/mdiluz/rove/pkg/vector" "github.com/stretchr/testify/assert" ) @@ -68,7 +68,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) { a, err := world.SpawnRover() assert.NoError(t, err) - pos := vector.Vector{ + pos := maths.Vector{ X: 0.0, Y: 0.0, } @@ -83,7 +83,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) { b := bearing.North newPos, err = world.MoveRover(a, b) 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") rover, err := world.GetRover(a) @@ -92,7 +92,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) { 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 - world.Atlas.SetObject(vector.Vector{X: 0, Y: 2}, objects.Object{Type: objects.LargeRock}) + world.Atlas.SetObject(maths.Vector{X: 0, Y: 2}, objects.Object{Type: objects.LargeRock}) newPos, err = world.MoveRover(a, b) assert.NoError(t, err, "Failed to move rover") assert.Equal(t, pos, newPos, "Failed to correctly not move position for rover into wall") @@ -111,9 +111,9 @@ func TestWorld_RadarFromRover(t *testing.T) { assert.NoError(t, err) // 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(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) assert.NoError(t, err, "Failed to get radar from rover") @@ -139,7 +139,7 @@ func TestWorld_RoverStash(t *testing.T) { a, err := world.SpawnRover() assert.NoError(t, err) - pos := vector.Vector{ + pos := maths.Vector{ X: 0.0, Y: 0.0, } @@ -215,7 +215,7 @@ func TestWorld_RoverDamage(t *testing.T) { a, err := world.SpawnRover() assert.NoError(t, err) - pos := vector.Vector{ + pos := maths.Vector{ X: 0.0, Y: 0.0, } @@ -226,7 +226,7 @@ func TestWorld_RoverDamage(t *testing.T) { info, err := world.GetRover(a) 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}, objects.Object{Type: objects.LargeRock}) vec, err := world.MoveRover(a, bearing.North) assert.NoError(t, err, "Failed to move rover") @@ -243,7 +243,7 @@ func TestWorld_RoverRepair(t *testing.T) { a, err := world.SpawnRover() assert.NoError(t, err) - pos := vector.Vector{ + pos := maths.Vector{ X: 0.0, Y: 0.0, } @@ -263,7 +263,7 @@ func TestWorld_RoverRepair(t *testing.T) { assert.NoError(t, err, "Failed to stash") assert.Equal(t, objects.SmallRock, 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}, objects.Object{Type: objects.LargeRock}) // Try and bump into the rock vec, err := world.MoveRover(a, bearing.North) @@ -378,8 +378,8 @@ func TestWorld_Broadcast(t *testing.T) { assert.NoError(t, err) // Warp rovers near to eachother - assert.NoError(t, world.WarpRover(a, vector.Vector{X: 0, Y: 0})) - assert.NoError(t, world.WarpRover(b, vector.Vector{X: 1, Y: 0})) + assert.NoError(t, world.WarpRover(a, maths.Vector{X: 0, Y: 0})) + assert.NoError(t, world.WarpRover(b, maths.Vector{X: 1, Y: 0})) // Broadcast from a assert.NoError(t, world.RoverBroadcast(a, []byte{'A', 'B', 'C'})) @@ -396,8 +396,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") // Warp B outside of the range of A - world.Atlas.SetObject(vector.Vector{X: ra.Range, Y: 0}, objects.Object{Type: objects.None}) - assert.NoError(t, world.WarpRover(b, vector.Vector{X: ra.Range, Y: 0})) + world.Atlas.SetObject(maths.Vector{X: ra.Range, Y: 0}, objects.Object{Type: objects.None}) + assert.NoError(t, world.WarpRover(b, maths.Vector{X: ra.Range, Y: 0})) // Broadcast from a again assert.NoError(t, world.RoverBroadcast(a, []byte{'X', 'Y', 'Z'})) @@ -413,8 +413,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") // Warp B outside of the range of A - world.Atlas.SetObject(vector.Vector{X: ra.Range + 1, Y: 0}, objects.Object{Type: objects.None}) - 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}, objects.Object{Type: objects.None}) + assert.NoError(t, world.WarpRover(b, maths.Vector{X: ra.Range + 1, Y: 0})) // Broadcast from a again assert.NoError(t, world.RoverBroadcast(a, []byte{'H', 'J', 'K'})) From f40f7123d43b6f3731c3fa4937be851a35e76053 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:24:54 +0100 Subject: [PATCH 14/18] Move bearing into maths --- cmd/rove/main.go | 4 ++-- pkg/{bearing => maths}/bearing.go | 8 +++----- pkg/{bearing => maths}/bearing_test.go | 5 ++--- pkg/rove/world.go | 7 +++---- pkg/rove/world_test.go | 15 +++++++-------- 5 files changed, 17 insertions(+), 22 deletions(-) rename pkg/{bearing => maths}/bearing.go (92%) rename pkg/{bearing => maths}/bearing_test.go (83%) diff --git a/cmd/rove/main.go b/cmd/rove/main.go index af48a61..cf239bf 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -11,7 +11,7 @@ import ( "time" "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/roveapi" "github.com/mdiluz/rove/pkg/version" @@ -216,7 +216,7 @@ func InnerMain(command string, args ...string) error { i++ if len(args) == i { 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 } commands = append(commands, diff --git a/pkg/bearing/bearing.go b/pkg/maths/bearing.go similarity index 92% rename from pkg/bearing/bearing.go rename to pkg/maths/bearing.go index 2eec3ba..220855b 100644 --- a/pkg/bearing/bearing.go +++ b/pkg/maths/bearing.go @@ -1,10 +1,8 @@ -package bearing +package maths import ( "fmt" "strings" - - "github.com/mdiluz/rove/pkg/maths" ) // Bearing describes a compass direction @@ -67,7 +65,7 @@ func FromString(s string) (Bearing, error) { return -1, fmt.Errorf("unknown bearing: %s", s) } -var bearingVectors = []maths.Vector{ +var bearingVectors = []Vector{ {X: 0, Y: 1}, // N {X: 1, Y: 1}, // NE {X: 1, Y: 0}, // E @@ -79,6 +77,6 @@ var bearingVectors = []maths.Vector{ } // Vector converts a Direction to a Vector -func (d Bearing) Vector() maths.Vector { +func (d Bearing) Vector() Vector { return bearingVectors[d] } diff --git a/pkg/bearing/bearing_test.go b/pkg/maths/bearing_test.go similarity index 83% rename from pkg/bearing/bearing_test.go rename to pkg/maths/bearing_test.go index 5bb36bc..bb97043 100644 --- a/pkg/bearing/bearing_test.go +++ b/pkg/maths/bearing_test.go @@ -1,9 +1,8 @@ -package bearing +package maths import ( "testing" - "github.com/mdiluz/rove/pkg/maths" "github.com/stretchr/testify/assert" ) @@ -12,7 +11,7 @@ func TestDirection(t *testing.T) { assert.Equal(t, "North", dir.String()) assert.Equal(t, "N", dir.ShortString()) - assert.Equal(t, maths.Vector{X: 0, Y: 1}, dir.Vector()) + assert.Equal(t, Vector{X: 0, Y: 1}, dir.Vector()) dir, err := FromString("N") assert.NoError(t, err) diff --git a/pkg/rove/world.go b/pkg/rove/world.go index eb2ef85..559073e 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -10,7 +10,6 @@ import ( "github.com/google/uuid" "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/roveapi" @@ -279,7 +278,7 @@ func (w *World) WarpRover(rover string, pos maths.Vector) error { } // MoveRover attempts to move a rover in a specific direction -func (w *World) MoveRover(rover string, b bearing.Bearing) (maths.Vector, error) { +func (w *World) MoveRover(rover string, b maths.Bearing) (maths.Vector, error) { w.worldMutex.Lock() defer w.worldMutex.Unlock() @@ -428,7 +427,7 @@ func (w *World) Enqueue(rover string, commands ...Command) error { for _, c := range commands { switch c.Command { 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) } case roveapi.CommandType_broadcast: @@ -507,7 +506,7 @@ func (w *World) ExecuteCommand(c *Command, rover string) (err error) { switch c.Command { case roveapi.CommandType_move: - if dir, err := bearing.FromString(c.Bearing); err != nil { + if dir, err := maths.FromString(c.Bearing); err != nil { return err } else if _, err := w.MoveRover(rover, dir); err != nil { return err diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index 89ea9c7..78e9160 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -4,7 +4,6 @@ import ( "testing" "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/roveapi" @@ -80,7 +79,7 @@ func TestWorld_GetSetMovePosition(t *testing.T) { assert.NoError(t, err, "Failed to 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) assert.NoError(t, err, "Failed to set position for rover") pos.Add(maths.Vector{X: 0, Y: 1}) @@ -228,7 +227,7 @@ func TestWorld_RoverDamage(t *testing.T) { world.Atlas.SetObject(maths.Vector{X: 0.0, Y: 1.0}, objects.Object{Type: objects.LargeRock}) - vec, err := world.MoveRover(a, bearing.North) + vec, err := world.MoveRover(a, maths.North) assert.NoError(t, err, "Failed to move rover") assert.Equal(t, pos, vec, "Rover managed to move into large rock") @@ -266,7 +265,7 @@ func TestWorld_RoverRepair(t *testing.T) { world.Atlas.SetObject(maths.Vector{X: 0.0, Y: 1.0}, objects.Object{Type: objects.LargeRock}) // 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.Equal(t, pos, vec, "Rover managed to move into large rock") @@ -313,13 +312,13 @@ func TestWorld_Charge(t *testing.T) { assert.NoError(t, err, "Failed to get position for rover") // Ensure the path ahead is empty - world.Atlas.SetTile(initialPos.Added(bearing.North.Vector()), atlas.TileRock) - world.Atlas.SetObject(initialPos.Added(bearing.North.Vector()), objects.Object{Type: objects.None}) + world.Atlas.SetTile(initialPos.Added(maths.North.Vector()), atlas.TileRock) + world.Atlas.SetObject(initialPos.Added(maths.North.Vector()), objects.Object{Type: objects.None}) // 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.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 rover, err := world.GetRover(a) From f0ab2abf6e81488f1f07c02a6f203d023b4a70d9 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:39:33 +0100 Subject: [PATCH 15/18] Move object into atlas --- cmd/rove/main.go | 3 +-- pkg/atlas/atlas.go | 5 ++-- pkg/atlas/atlas_test.go | 15 +++++------ pkg/atlas/chunkAtlas.go | 27 ++++++++++--------- pkg/{objects => atlas}/objects.go | 24 ++++++++--------- pkg/rove/rover.go | 4 +-- pkg/rove/world.go | 17 ++++++------ pkg/rove/world_test.go | 43 +++++++++++++++---------------- 8 files changed, 66 insertions(+), 72 deletions(-) rename pkg/{objects => atlas}/objects.go (63%) diff --git a/cmd/rove/main.go b/cmd/rove/main.go index cf239bf..1ec0b24 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -12,7 +12,6 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/version" "golang.org/x/net/context" @@ -288,7 +287,7 @@ func InnerMain(command string, args ...string) error { for i := 0; i < num; i++ { t := response.Tiles[i+num*j] o := response.Objects[i+num*j] - if o != byte(objects.None) { + if o != byte(atlas.ObjectNone) { fmt.Printf("%c", o) } else if t != byte(atlas.TileNone) { fmt.Printf("%c", t) diff --git a/pkg/atlas/atlas.go b/pkg/atlas/atlas.go index 22873f7..1a2f3fb 100644 --- a/pkg/atlas/atlas.go +++ b/pkg/atlas/atlas.go @@ -2,7 +2,6 @@ package atlas import ( "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" ) // Tile describes the type of terrain @@ -28,8 +27,8 @@ type Atlas interface { SetTile(v maths.Vector, tile Tile) // SetObject will set a location on the Atlas to contain an object - SetObject(v maths.Vector, obj objects.Object) + SetObject(v maths.Vector, obj Object) // QueryPosition queries a position on the atlas - QueryPosition(v maths.Vector) (byte, objects.Object) + QueryPosition(v maths.Vector) (byte, Object) } diff --git a/pkg/atlas/atlas_test.go b/pkg/atlas/atlas_test.go index 4792e0b..9305b07 100644 --- a/pkg/atlas/atlas_test.go +++ b/pkg/atlas/atlas_test.go @@ -5,7 +5,6 @@ import ( "testing" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" "github.com/stretchr/testify/assert" ) @@ -186,14 +185,14 @@ func TestAtlas_GetSetObject(t *testing.T) { assert.NotNil(t, a) // Set the origin tile to 1 and test it - a.SetObject(maths.Vector{X: 0, Y: 0}, objects.Object{Type: objects.LargeRock}) + a.SetObject(maths.Vector{X: 0, Y: 0}, Object{Type: ObjectLargeRock}) _, 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 - a.SetObject(maths.Vector{X: 5, Y: -2}, objects.Object{Type: objects.SmallRock}) + a.SetObject(maths.Vector{X: 5, Y: -2}, Object{Type: ObjectSmallRock}) _, 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) { @@ -239,11 +238,11 @@ func TestAtlas_GetSetCorrect(t *testing.T) { pos := maths.Vector{X: x, Y: y} a.SetTile(pos, TileRock) - a.SetObject(pos, objects.Object{Type: objects.LargeRock}) + a.SetObject(pos, Object{Type: ObjectLargeRock}) tile, obj := a.QueryPosition(pos) assert.Equal(t, TileRock, Tile(tile)) - assert.Equal(t, objects.Object{Type: objects.LargeRock}, obj) + assert.Equal(t, Object{Type: ObjectLargeRock}, obj) } } @@ -260,7 +259,7 @@ func TestAtlas_WorldGen(t *testing.T) { for j := num - 1; j >= 0; j-- { for i := 0; i < num; i++ { t, o := a.QueryPosition(maths.Vector{X: i, Y: j}) - if o.Type != objects.None { + if o.Type != ObjectNone { fmt.Printf("%c", o.Type) } else if t != byte(TileNone) { fmt.Printf("%c", t) diff --git a/pkg/atlas/chunkAtlas.go b/pkg/atlas/chunkAtlas.go index c3c969e..daee6e6 100644 --- a/pkg/atlas/chunkAtlas.go +++ b/pkg/atlas/chunkAtlas.go @@ -5,7 +5,6 @@ import ( "math/rand" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" "github.com/ojrac/opensimplex-go" ) @@ -16,7 +15,7 @@ type chunk struct { // Objects represents the objects within the chunk // only one possible object per tile for now - Objects map[int]objects.Object `json:"objects"` + Objects map[int]Object `json:"objects"` } // chunkBasedAtlas represents a grid of Chunks @@ -71,14 +70,14 @@ func (a *chunkBasedAtlas) SetTile(v maths.Vector, tile Tile) { } // SetObject sets the object on a tile -func (a *chunkBasedAtlas) SetObject(v maths.Vector, obj objects.Object) { +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, objects.Object) { +func (a *chunkBasedAtlas) QueryPosition(v maths.Vector) (byte, Object) { c := a.worldSpaceToChunkWithGrow(v) local := a.worldSpaceToChunkLocal(v) a.populate(c) @@ -100,7 +99,7 @@ func (a *chunkBasedAtlas) populate(chunk int) { } c.Tiles = make([]byte, a.ChunkSize*a.ChunkSize) - c.Objects = make(map[int]objects.Object) + c.Objects = make(map[int]Object) origin := a.chunkOriginInWorldSpace(chunk) for i := 0; i < a.ChunkSize; i++ { @@ -121,15 +120,15 @@ func (a *chunkBasedAtlas) populate(chunk int) { // 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 + var obj = ObjectNone switch { case o > 0.6: - obj = objects.LargeRock + obj = ObjectLargeRock case o > 0.5: - obj = objects.SmallRock + obj = ObjectSmallRock } - if obj != objects.None { - c.Objects[j*a.ChunkSize+i] = objects.Object{Type: obj} + if obj != ObjectNone { + c.Objects[j*a.ChunkSize+i] = Object{Type: obj} } } } @@ -137,9 +136,9 @@ func (a *chunkBasedAtlas) populate(chunk int) { // Set up any objects for i := 0; i < len(c.Tiles); i++ { if rand.Intn(16) == 0 { - c.Objects[i] = objects.Object{Type: objects.LargeRock} + c.Objects[i] = Object{Type: ObjectLargeRock} } else if rand.Intn(32) == 0 { - c.Objects[i] = objects.Object{Type: objects.SmallRock} + c.Objects[i] = Object{Type: ObjectSmallRock} } } @@ -155,12 +154,12 @@ func (a *chunkBasedAtlas) setTile(chunk int, local maths.Vector, tile byte) { } // setObject sets an object in a specific chunk -func (a *chunkBasedAtlas) setObject(chunk int, local maths.Vector, object objects.Object) { +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 != objects.None { + if object.Type != ObjectNone { c.Objects[i] = object } else { delete(c.Objects, i) diff --git a/pkg/objects/objects.go b/pkg/atlas/objects.go similarity index 63% rename from pkg/objects/objects.go rename to pkg/atlas/objects.go index 9338b68..68b4ef8 100644 --- a/pkg/objects/objects.go +++ b/pkg/atlas/objects.go @@ -1,21 +1,21 @@ -package objects +package atlas // Type represents an object type type Type byte // Types of objects const ( - // None represents no object at all - None = Type(0) + // ObjectNone represents no object at all + ObjectNone = Type(0) - // Rover represents a live rover - Rover = Type('R') + // ObjectRover represents a live rover + ObjectRover = Type('R') - // SmallRock is a small stashable rock - SmallRock = Type('o') + // ObjectSmallRock is a small stashable rock + ObjectSmallRock = Type('o') - // LargeRock is a large blocking rock - LargeRock = Type('O') + // ObjectLargeRock is a large blocking rock + ObjectLargeRock = Type('O') ) // Object represents an object in the world @@ -26,8 +26,8 @@ type Object struct { // IsBlocking checks if an object is a blocking object func (o *Object) IsBlocking() bool { var blocking = [...]Type{ - Rover, - LargeRock, + ObjectRover, + ObjectLargeRock, } for _, t := range blocking { @@ -41,7 +41,7 @@ func (o *Object) IsBlocking() bool { // IsStashable checks if an object is stashable func (o *Object) IsStashable() bool { var stashable = [...]Type{ - SmallRock, + ObjectSmallRock, } for _, t := range stashable { diff --git a/pkg/rove/rover.go b/pkg/rove/rover.go index 45fb8f0..089b44a 100644 --- a/pkg/rove/rover.go +++ b/pkg/rove/rover.go @@ -5,8 +5,8 @@ import ( "log" "time" + "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" ) // RoverLogEntry describes a single log entry for the rover @@ -30,7 +30,7 @@ type Rover struct { Range int `json:"range"` // 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 int `json:"capacity"` diff --git a/pkg/rove/world.go b/pkg/rove/world.go index 559073e..b0e796f 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -11,7 +11,6 @@ import ( "github.com/google/uuid" "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/roveapi" ) @@ -241,7 +240,7 @@ func (w *World) SetRoverPosition(rover string, pos maths.Vector) error { } // 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() defer w.worldMutex.RUnlock() @@ -319,35 +318,35 @@ func (w *World) MoveRover(rover string, b maths.Bearing) (maths.Vector, error) { } // 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() defer w.worldMutex.Unlock() r, ok := w.Rovers[rover] 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 if len(r.Inventory) >= r.Capacity { - return objects.None, nil + return atlas.ObjectNone, nil } // Ensure the rover has energy if r.Charge <= 0 { - return objects.None, nil + return atlas.ObjectNone, nil } r.Charge-- _, obj := w.Atlas.QueryPosition(r.Pos) if !obj.IsStashable() { - return objects.None, nil + return atlas.ObjectNone, nil } r.AddLogEntryf("stashed %c", obj.Type) r.Inventory = append(r.Inventory, obj) 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 } @@ -402,7 +401,7 @@ func (w *World) RadarFromRover(rover string) (radar []byte, objs []byte, err err if dist.X <= r.Range && dist.Y <= r.Range { relative := r.Pos.Added(radarMin.Negated()) index := relative.X + relative.Y*radarSpan - objs[index] = byte(objects.Rover) + objs[index] = byte(atlas.ObjectRover) } } diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index 78e9160..ceaff43 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -5,7 +5,6 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/objects" "github.com/mdiluz/rove/pkg/roveapi" "github.com/stretchr/testify/assert" ) @@ -91,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") // Place a tile in front of the rover - world.Atlas.SetObject(maths.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) assert.NoError(t, err, "Failed to move rover") assert.Equal(t, pos, newPos, "Failed to correctly not move position for rover into wall") @@ -121,8 +120,8 @@ func TestWorld_RadarFromRover(t *testing.T) { assert.Equal(t, fullRange*fullRange, len(objs), "Radar returned wrong length") // Test the expected values - assert.Equal(t, byte(objects.Rover), objs[1+fullRange]) - assert.Equal(t, byte(objects.Rover), objs[4+4*fullRange]) + assert.Equal(t, byte(atlas.ObjectRover), objs[1+fullRange]) + assert.Equal(t, byte(atlas.ObjectRover), objs[4+4*fullRange]) // Check the radar results are stable radar1, objs1, err := world.RadarFromRover(a) @@ -143,7 +142,7 @@ func TestWorld_RoverStash(t *testing.T) { Y: 0.0, } - world.Atlas.SetObject(pos, objects.Object{Type: objects.None}) + world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectNone}) err = world.WarpRover(a, pos) 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++ { // Place an object - world.Atlas.SetObject(pos, objects.Object{Type: objects.SmallRock}) + world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectSmallRock}) // Pick it up o, err := world.RoverStash(a) 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 _, 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 inv, err := world.RoverInventory(a) assert.NoError(t, err, "Failed to get inventory") 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 info, err := world.GetRover(a) @@ -187,16 +186,16 @@ func TestWorld_RoverStash(t *testing.T) { } // 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 o, err := world.RoverStash(a) 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 _, 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 inv, err := world.RoverInventory(a) @@ -225,7 +224,7 @@ func TestWorld_RoverDamage(t *testing.T) { info, err := world.GetRover(a) assert.NoError(t, err, "couldn't get rover info") - world.Atlas.SetObject(maths.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, maths.North) assert.NoError(t, err, "Failed to move rover") @@ -248,7 +247,7 @@ func TestWorld_RoverRepair(t *testing.T) { } 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) assert.NoError(t, err, "Failed to set position for rover") @@ -257,12 +256,12 @@ func TestWorld_RoverRepair(t *testing.T) { assert.NoError(t, err, "couldn't get rover info") // 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) 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(maths.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 vec, err := world.MoveRover(a, maths.North) @@ -282,10 +281,10 @@ func TestWorld_RoverRepair(t *testing.T) { assert.Contains(t, newinfo.Logs[len(newinfo.Logs)-1].Text, "repair", "Rover logs should contain the repair") // Check again that it can't repair past the max - world.Atlas.SetObject(pos, objects.Object{Type: objects.SmallRock}) + world.Atlas.SetObject(pos, atlas.Object{Type: atlas.ObjectSmallRock}) o, err = world.RoverStash(a) 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: roveapi.CommandType_repair}, a) assert.NoError(t, err, "Failed to repair rover") @@ -313,7 +312,7 @@ func TestWorld_Charge(t *testing.T) { // Ensure the path ahead is empty world.Atlas.SetTile(initialPos.Added(maths.North.Vector()), atlas.TileRock) - world.Atlas.SetObject(initialPos.Added(maths.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) newPos, err := world.MoveRover(a, maths.North) @@ -395,7 +394,7 @@ 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") // Warp B outside of the range of A - world.Atlas.SetObject(maths.Vector{X: ra.Range, Y: 0}, objects.Object{Type: objects.None}) + 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 @@ -412,7 +411,7 @@ 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") // Warp B outside of the range of A - world.Atlas.SetObject(maths.Vector{X: ra.Range + 1, Y: 0}, objects.Object{Type: objects.None}) + 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 From 9ccb7ac019189d2693f949a26019fc2b82f12005 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:48:03 +0100 Subject: [PATCH 16/18] Remove google proto files, no longer needed --- proto/google/README.grpc-gateway | 23 -- proto/google/api/annotations.proto | 31 --- proto/google/api/http.proto | 318 --------------------------- proto/google/api/httpbody.proto | 78 ------- proto/google/rpc/code.proto | 186 ---------------- proto/google/rpc/error_details.proto | 200 ----------------- proto/google/rpc/status.proto | 92 -------- 7 files changed, 928 deletions(-) delete mode 100644 proto/google/README.grpc-gateway delete mode 100644 proto/google/api/annotations.proto delete mode 100644 proto/google/api/http.proto delete mode 100644 proto/google/api/httpbody.proto delete mode 100644 proto/google/rpc/code.proto delete mode 100644 proto/google/rpc/error_details.proto delete mode 100644 proto/google/rpc/status.proto diff --git a/proto/google/README.grpc-gateway b/proto/google/README.grpc-gateway deleted file mode 100644 index b7d1bea..0000000 --- a/proto/google/README.grpc-gateway +++ /dev/null @@ -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 diff --git a/proto/google/api/annotations.proto b/proto/google/api/annotations.proto deleted file mode 100644 index 85c361b..0000000 --- a/proto/google/api/annotations.proto +++ /dev/null @@ -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; -} diff --git a/proto/google/api/http.proto b/proto/google/api/http.proto deleted file mode 100644 index 2bd3a19..0000000 --- a/proto/google/api/http.proto +++ /dev/null @@ -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: .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¶m=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; -} diff --git a/proto/google/api/httpbody.proto b/proto/google/api/httpbody.proto deleted file mode 100644 index 4428515..0000000 --- a/proto/google/api/httpbody.proto +++ /dev/null @@ -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; -} \ No newline at end of file diff --git a/proto/google/rpc/code.proto b/proto/google/rpc/code.proto deleted file mode 100644 index 8fef411..0000000 --- a/proto/google/rpc/code.proto +++ /dev/null @@ -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; -} diff --git a/proto/google/rpc/error_details.proto b/proto/google/rpc/error_details.proto deleted file mode 100644 index f24ae00..0000000 --- a/proto/google/rpc/error_details.proto +++ /dev/null @@ -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:" or "project:". - 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:" or "project:". - 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; -} diff --git a/proto/google/rpc/status.proto b/proto/google/rpc/status.proto deleted file mode 100644 index 0839ee9..0000000 --- a/proto/google/rpc/status.proto +++ /dev/null @@ -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; -} From 46f81abbd7bd72c3d5062e4d9b2e3231d80c45a0 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 18:57:57 +0100 Subject: [PATCH 17/18] Move accounts into rove-server.internal --- Makefile | 2 +- {pkg/accounts => cmd/rove-server/internal}/accounts.go | 2 +- {pkg/accounts => cmd/rove-server/internal}/accounts_test.go | 2 +- cmd/rove-server/internal/server.go | 5 ++--- .../rove-server/internal}/simpleAccountant.go | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) rename {pkg/accounts => cmd/rove-server/internal}/accounts.go (98%) rename {pkg/accounts => cmd/rove-server/internal}/accounts_test.go (98%) rename {pkg/accounts => cmd/rove-server/internal}/simpleAccountant.go (99%) diff --git a/Makefile b/Makefile index b28ac4f..b36c19a 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ VERSION := $(shell git describe --always --long --dirty --tags) build: @echo Running no-output build 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: @echo Installing to GOPATH diff --git a/pkg/accounts/accounts.go b/cmd/rove-server/internal/accounts.go similarity index 98% rename from pkg/accounts/accounts.go rename to cmd/rove-server/internal/accounts.go index 69508c0..99362ad 100644 --- a/pkg/accounts/accounts.go +++ b/cmd/rove-server/internal/accounts.go @@ -1,4 +1,4 @@ -package accounts +package internal // Accountant decribes something that stores accounts and account values type Accountant interface { diff --git a/pkg/accounts/accounts_test.go b/cmd/rove-server/internal/accounts_test.go similarity index 98% rename from pkg/accounts/accounts_test.go rename to cmd/rove-server/internal/accounts_test.go index bd2416f..9e7891f 100644 --- a/pkg/accounts/accounts_test.go +++ b/cmd/rove-server/internal/accounts_test.go @@ -1,4 +1,4 @@ -package accounts +package internal import ( "testing" diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go index f633601..ad0c315 100644 --- a/cmd/rove-server/internal/server.go +++ b/cmd/rove-server/internal/server.go @@ -6,7 +6,6 @@ import ( "net" "sync" - "github.com/mdiluz/rove/pkg/accounts" "github.com/mdiluz/rove/pkg/persistence" "github.com/mdiluz/rove/pkg/rove" "github.com/mdiluz/rove/pkg/roveapi" @@ -29,7 +28,7 @@ type Server struct { world *rove.World // Accountant - accountant accounts.Accountant + accountant Accountant // gRPC server netListener net.Listener @@ -81,7 +80,7 @@ func NewServer(opts ...ServerOption) *Server { persistence: EphemeralData, schedule: cron.New(), world: rove.NewWorld(32), - accountant: accounts.NewSimpleAccountant(), + accountant: NewSimpleAccountant(), } // Apply all options diff --git a/pkg/accounts/simpleAccountant.go b/cmd/rove-server/internal/simpleAccountant.go similarity index 99% rename from pkg/accounts/simpleAccountant.go rename to cmd/rove-server/internal/simpleAccountant.go index 023fe2f..3168f30 100644 --- a/pkg/accounts/simpleAccountant.go +++ b/cmd/rove-server/internal/simpleAccountant.go @@ -1,4 +1,4 @@ -package accounts +package internal import ( "fmt" From 737534f739a383b3b51fad3a90d148518019ffb5 Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Fri, 10 Jul 2020 19:00:31 +0100 Subject: [PATCH 18/18] Move roveapi into the proto dir --- Makefile | 10 +++------- cmd/rove-server/internal/routes.go | 2 +- cmd/rove-server/internal/server.go | 2 +- cmd/rove/main.go | 2 +- pkg/rove/command.go | 2 +- pkg/rove/command_test.go | 2 +- pkg/rove/world.go | 2 +- pkg/rove/world_test.go | 2 +- {pkg => proto}/roveapi/roveapi.pb.go | 6 +++--- proto/roveapi/roveapi.proto | 2 +- 10 files changed, 14 insertions(+), 18 deletions(-) rename {pkg => proto}/roveapi/roveapi.pb.go (99%) diff --git a/Makefile b/Makefile index b36c19a..b73faf0 100644 --- a/Makefile +++ b/Makefile @@ -12,14 +12,10 @@ install: gen: @echo Installing go dependencies - go install \ - 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 install github.com/golang/protobuf/protoc-gen-go go mod download - @echo Generating rove server gRPC and gateway - protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:pkg/ proto/roveapi/roveapi.proto - protoc --proto_path proto --grpc-gateway_out=paths=source_relative:pkg/ proto/roveapi/roveapi.proto + @echo Generating rove server gRPC + protoc --proto_path proto --go_out=plugins=grpc,paths=source_relative:proto/ proto/roveapi/roveapi.proto test: @echo Unit tests diff --git a/cmd/rove-server/internal/routes.go b/cmd/rove-server/internal/routes.go index 8e8706c..0fb41d8 100644 --- a/cmd/rove-server/internal/routes.go +++ b/cmd/rove-server/internal/routes.go @@ -6,8 +6,8 @@ import ( "log" "github.com/mdiluz/rove/pkg/rove" - "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/version" + "github.com/mdiluz/rove/proto/roveapi" ) // ServerStatus returns the status of the current server to a gRPC request diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go index ad0c315..102c30d 100644 --- a/cmd/rove-server/internal/server.go +++ b/cmd/rove-server/internal/server.go @@ -8,7 +8,7 @@ import ( "github.com/mdiluz/rove/pkg/persistence" "github.com/mdiluz/rove/pkg/rove" - "github.com/mdiluz/rove/pkg/roveapi" + "github.com/mdiluz/rove/proto/roveapi" "github.com/robfig/cron" "google.golang.org/grpc" ) diff --git a/cmd/rove/main.go b/cmd/rove/main.go index 1ec0b24..8a19e68 100644 --- a/cmd/rove/main.go +++ b/cmd/rove/main.go @@ -12,8 +12,8 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/roveapi" "github.com/mdiluz/rove/pkg/version" + "github.com/mdiluz/rove/proto/roveapi" "golang.org/x/net/context" "google.golang.org/grpc" ) diff --git a/pkg/rove/command.go b/pkg/rove/command.go index 6016555..86e9cad 100644 --- a/pkg/rove/command.go +++ b/pkg/rove/command.go @@ -1,6 +1,6 @@ package rove -import "github.com/mdiluz/rove/pkg/roveapi" +import "github.com/mdiluz/rove/proto/roveapi" // Command represends a single command to execute type Command struct { diff --git a/pkg/rove/command_test.go b/pkg/rove/command_test.go index e01a487..9150fde 100644 --- a/pkg/rove/command_test.go +++ b/pkg/rove/command_test.go @@ -4,7 +4,7 @@ import ( "testing" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/roveapi" + "github.com/mdiluz/rove/proto/roveapi" "github.com/stretchr/testify/assert" ) diff --git a/pkg/rove/world.go b/pkg/rove/world.go index b0e796f..04cad81 100644 --- a/pkg/rove/world.go +++ b/pkg/rove/world.go @@ -11,7 +11,7 @@ import ( "github.com/google/uuid" "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/roveapi" + "github.com/mdiluz/rove/proto/roveapi" ) // World describes a self contained universe and everything in it diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go index ceaff43..f3be5c0 100644 --- a/pkg/rove/world_test.go +++ b/pkg/rove/world_test.go @@ -5,7 +5,7 @@ import ( "github.com/mdiluz/rove/pkg/atlas" "github.com/mdiluz/rove/pkg/maths" - "github.com/mdiluz/rove/pkg/roveapi" + "github.com/mdiluz/rove/proto/roveapi" "github.com/stretchr/testify/assert" ) diff --git a/pkg/roveapi/roveapi.pb.go b/proto/roveapi/roveapi.pb.go similarity index 99% rename from pkg/roveapi/roveapi.pb.go rename to proto/roveapi/roveapi.pb.go index 491231d..1eeeabd 100644 --- a/pkg/roveapi/roveapi.pb.go +++ b/proto/roveapi/roveapi.pb.go @@ -1113,10 +1113,10 @@ var file_roveapi_roveapi_proto_rawDesc = []byte{ 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x17, 0x2e, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x24, 0x5a, 0x22, 0x67, 0x69, 0x74, 0x68, 0x75, + 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, 0x6b, 0x67, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x62, 0x06, 0x70, - 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x72, 0x6f, 0x76, 0x65, 0x61, 0x70, 0x69, 0x62, + 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/proto/roveapi/roveapi.proto b/proto/roveapi/roveapi.proto index f39d2a6..9dd2577 100644 --- a/proto/roveapi/roveapi.proto +++ b/proto/roveapi/roveapi.proto @@ -5,7 +5,7 @@ syntax = "proto3"; // Rove is an asychronous nomadic game about exploring a planet as part of a // loose community package roveapi; -option go_package = "github.com/mdiluz/rove/pkg/roveapi"; +option go_package = "github.com/mdiluz/rove/proto/roveapi"; // The Rove server hosts a single game session and world with multiple players service Rove {