From 6f2d67bd7c14e312cc5b44acef62addd2a8aa93e Mon Sep 17 00:00:00 2001
From: Marc Di Luzio <marc.diluzio@gmail.com>
Date: Fri, 24 Jul 2020 22:22:32 +0100
Subject: [PATCH] Tag rovers by the controlling account

---
 cmd/rove-server/internal/server.go |  2 +-
 pkg/rove/command_test.go           | 14 +++++++-------
 pkg/rove/rover.go                  |  3 +++
 pkg/rove/world.go                  | 12 ++++++++++--
 pkg/rove/world_test.go             | 26 +++++++++++++-------------
 5 files changed, 34 insertions(+), 23 deletions(-)

diff --git a/cmd/rove-server/internal/server.go b/cmd/rove-server/internal/server.go
index 564656e..42392f3 100644
--- a/cmd/rove-server/internal/server.go
+++ b/cmd/rove-server/internal/server.go
@@ -205,7 +205,7 @@ func (s *Server) LoadWorld() error {
 
 // SpawnRoverForAccount spawns the rover rover for an account
 func (s *Server) SpawnRoverForAccount(account string) (string, error) {
-	inst, err := s.world.SpawnRover()
+	inst, err := s.world.SpawnRover(account)
 	if err != nil {
 		return "", err
 	}
diff --git a/pkg/rove/command_test.go b/pkg/rove/command_test.go
index 9a8a35a..6560e53 100644
--- a/pkg/rove/command_test.go
+++ b/pkg/rove/command_test.go
@@ -10,7 +10,7 @@ import (
 
 func TestCommand_Toggle(t *testing.T) {
 	w := NewWorld(8)
-	a, err := w.SpawnRover()
+	a, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	r, err := w.GetRover(a)
@@ -36,7 +36,7 @@ func TestCommand_Toggle(t *testing.T) {
 
 func TestCommand_Turn(t *testing.T) {
 	w := NewWorld(8)
-	a, err := w.SpawnRover()
+	a, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	err = w.Enqueue(a, &roveapi.Command{Command: roveapi.CommandType_turn, Bearing: roveapi.Bearing_NorthWest})
@@ -50,7 +50,7 @@ func TestCommand_Turn(t *testing.T) {
 
 func TestCommand_Stash(t *testing.T) {
 	w := NewWorld(8)
-	name, err := w.SpawnRover()
+	name, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	info, err := w.GetRover(name)
@@ -78,7 +78,7 @@ func TestCommand_Stash(t *testing.T) {
 
 func TestCommand_Repair(t *testing.T) {
 	w := NewWorld(8)
-	name, err := w.SpawnRover()
+	name, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	info, err := w.GetRover(name)
@@ -118,7 +118,7 @@ func TestCommand_Repair(t *testing.T) {
 
 func TestCommand_Broadcast(t *testing.T) {
 	w := NewWorld(8)
-	name, err := w.SpawnRover()
+	name, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	// Enqueue the broadcast and tick
@@ -133,7 +133,7 @@ func TestCommand_Broadcast(t *testing.T) {
 
 func TestCommand_Salvage(t *testing.T) {
 	w := NewWorld(8)
-	name, err := w.SpawnRover()
+	name, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	info, err := w.GetRover(name)
@@ -161,7 +161,7 @@ func TestCommand_Salvage(t *testing.T) {
 
 func TestCommand_Invalid(t *testing.T) {
 	w := NewWorld(8)
-	name, err := w.SpawnRover()
+	name, err := w.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	err = w.Enqueue(name, &roveapi.Command{Command: roveapi.CommandType_none})
diff --git a/pkg/rove/rover.go b/pkg/rove/rover.go
index ce0edcd..d0fb9cb 100644
--- a/pkg/rove/rover.go
+++ b/pkg/rove/rover.go
@@ -66,6 +66,9 @@ type Rover struct {
 
 	// Logs Stores log of information
 	Logs []RoverLogEntry
+
+	// The account that owns this rover
+	Owner string
 }
 
 // DefaultRover returns a default rover object with default settings
diff --git a/pkg/rove/world.go b/pkg/rove/world.go
index 0d828ae..922ab70 100644
--- a/pkg/rove/world.go
+++ b/pkg/rove/world.go
@@ -63,13 +63,16 @@ func NewWorld(chunkSize int) *World {
 }
 
 // SpawnRover adds an rover to the game
-func (w *World) SpawnRover() (string, error) {
+func (w *World) SpawnRover(account string) (string, error) {
 	w.worldMutex.Lock()
 	defer w.worldMutex.Unlock()
 
 	// Initialise the rover
 	rover := DefaultRover()
 
+	// Assign the owner
+	rover.Owner = account
+
 	// Spawn in a random place near the origin
 	rover.Pos = maths.Vector{
 		X: 10 - rand.Intn(20),
@@ -375,6 +378,9 @@ func (w *World) RoverTransfer(rover string) (string, error) {
 	oldRover.AddLogEntryf("transferring to dormant rover %s", newRover.Name)
 	newRover.AddLogEntryf("transferred from rover %s", oldRover.Name)
 
+	// Clear the old owner
+	oldRover.Owner = ""
+
 	// Marshal old rover
 	oldRoverData, err := json.Marshal(oldRover)
 	if err != nil {
@@ -384,7 +390,9 @@ func (w *World) RoverTransfer(rover string) (string, error) {
 	// Add this new rover to tracking
 	w.Rovers[newRover.Name] = &newRover
 
-	// TODO: Swap account rover to the dormant one
+	// Swap account rover to the dormant one
+	newRover.Owner = oldRover.Owner
+	w.Accountant.AssignData(oldRover.Owner, "rover", newRover.Name)
 
 	// Place the old rover into the world
 	w.Atlas.SetObject(oldRover.Pos, Object{Type: roveapi.Object_RoverDormant, Data: oldRoverData})
diff --git a/pkg/rove/world_test.go b/pkg/rove/world_test.go
index e1fa700..d0c4c01 100644
--- a/pkg/rove/world_test.go
+++ b/pkg/rove/world_test.go
@@ -18,9 +18,9 @@ func TestNewWorld(t *testing.T) {
 
 func TestWorld_CreateRover(t *testing.T) {
 	world := NewWorld(8)
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
-	b, err := world.SpawnRover()
+	b, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	// Basic duplicate check
@@ -33,7 +33,7 @@ func TestWorld_CreateRover(t *testing.T) {
 
 func TestWorld_GetRover(t *testing.T) {
 	world := NewWorld(4)
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	rover, err := world.GetRover(a)
@@ -44,9 +44,9 @@ func TestWorld_GetRover(t *testing.T) {
 
 func TestWorld_DestroyRover(t *testing.T) {
 	world := NewWorld(1)
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
-	b, err := world.SpawnRover()
+	b, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	err = world.DestroyRover(a)
@@ -62,7 +62,7 @@ func TestWorld_DestroyRover(t *testing.T) {
 
 func TestWorld_GetSetMovePosition(t *testing.T) {
 	world := NewWorld(4)
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	pos := maths.Vector{
@@ -97,9 +97,9 @@ func TestWorld_GetSetMovePosition(t *testing.T) {
 func TestWorld_RadarFromRover(t *testing.T) {
 	// Create world that should have visible walls on the radar
 	world := NewWorld(2)
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
-	b, err := world.SpawnRover()
+	b, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	// Warp the rovers into position
@@ -130,7 +130,7 @@ func TestWorld_RadarFromRover(t *testing.T) {
 
 func TestWorld_RoverDamage(t *testing.T) {
 	world := NewWorld(2)
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	pos := maths.Vector{
@@ -160,7 +160,7 @@ func TestWorld_RoverDamage(t *testing.T) {
 func TestWorld_Daytime(t *testing.T) {
 	world := NewWorld(1)
 
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	// Remove rover charge
@@ -199,10 +199,10 @@ func TestWorld_Daytime(t *testing.T) {
 func TestWorld_Broadcast(t *testing.T) {
 	world := NewWorld(8)
 
-	a, err := world.SpawnRover()
+	a, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
-	b, err := world.SpawnRover()
+	b, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	// Warp rovers near to eachother
@@ -265,7 +265,7 @@ func TestWorld_Sailing(t *testing.T) {
 	world.Tick()                       // One initial tick to set the wind direction the first time
 	world.Wind = roveapi.Bearing_North // Set the wind direction to north
 
-	name, err := world.SpawnRover()
+	name, err := world.SpawnRover("tmp")
 	assert.NoError(t, err)
 
 	// Warp the rover to 0,0 after clearing it