rove/cmd/rove-server/internal/routes.go

168 lines
4.6 KiB
Go
Raw Normal View History

package internal
2020-06-04 17:23:27 +01:00
import (
"context"
2020-06-04 17:23:27 +01:00
"fmt"
"github.com/mdiluz/rove/pkg/game"
"github.com/mdiluz/rove/pkg/rove"
2020-06-04 17:23:27 +01:00
"github.com/mdiluz/rove/pkg/version"
)
2020-07-04 23:11:22 +01:00
// 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{
Ready: true,
Version: version.Version,
TickRate: int32(s.minutesPerTick),
CurrentTick: int32(s.world.CurrentTicks),
2020-06-06 16:37:57 +01:00
}
// TODO: Verify the accountant is up and ready too
2020-06-06 16:37:57 +01:00
// If there's a schedule, respond with it
if len(s.schedule.Entries()) > 0 {
response.NextTick = s.schedule.Entries()[0].Next.Format("15:04:05")
}
return response, nil
2020-06-04 17:23:27 +01:00
}
2020-06-30 23:59:58 +01:00
// Register registers a new account for a gRPC request
func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove.RegisterResponse, error) {
if len(req.Name) == 0 {
return nil, fmt.Errorf("empty account name")
}
2020-06-05 16:43:25 +01:00
if acc, err := s.accountant.RegisterAccount(req.Name); err != nil {
return nil, err
} else if _, err := s.SpawnRoverForAccount(req.Name); err != nil {
return nil, fmt.Errorf("failed to spawn rover for account: %s", err)
} else if err := s.SaveWorld(); err != nil {
return nil, fmt.Errorf("internal server error when saving world: %s", err)
2020-06-04 17:23:27 +01:00
} else {
return &rove.RegisterResponse{
Account: &rove.Account{
Name: acc.Name,
Secret: acc.Data["secret"],
},
}, nil
}
}
2020-07-04 23:11:12 +01:00
// Status returns rover information for a gRPC request
2020-07-06 18:04:10 +01:00
func (s *Server) Status(ctx context.Context, req *rove.StatusRequest) (response *rove.StatusResponse, err error) {
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
return nil, err
} else if !valid {
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
2020-06-04 17:23:27 +01:00
} else if resp, err := s.accountant.GetValue(req.Account.Name, "rover"); err != nil {
return nil, err
2020-06-04 17:23:27 +01:00
} else if rover, err := s.world.GetRover(resp); err != nil {
return nil, fmt.Errorf("error getting rover: %s", err)
} else {
var inv []byte
for _, i := range rover.Inventory {
inv = append(inv, byte(i.Type))
}
i, q := s.world.RoverCommands(resp)
var incoming, queued []*rove.Command
for _, i := range i {
incoming = append(incoming, &rove.Command{
Command: i.Command,
Bearing: i.Bearing,
})
}
for _, q := range q {
queued = append(queued, &rove.Command{
Command: q.Command,
Bearing: q.Bearing,
})
}
2020-07-04 23:11:12 +01:00
response = &rove.StatusResponse{
Name: rover.Name,
Position: &rove.Vector{
X: int32(rover.Pos.X),
Y: int32(rover.Pos.Y),
},
2020-07-04 12:19:51 +01:00
Range: int32(rover.Range),
Inventory: inv,
Capacity: int32(rover.Capacity),
Integrity: int32(rover.Integrity),
MaximumIntegrity: int32(rover.MaximumIntegrity),
Charge: int32(rover.Charge),
MaximumCharge: int32(rover.MaximumCharge),
IncomingCommands: incoming,
QueuedCommands: queued,
}
2020-06-04 17:23:27 +01:00
}
return response, nil
2020-06-04 17:23:27 +01:00
}
2020-06-30 23:59:58 +01:00
// Radar returns the radar information for a rover
func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.RadarResponse, error) {
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
return nil, err
} else if !valid {
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
}
2020-06-04 17:23:27 +01:00
response := &rove.RadarResponse{}
2020-06-04 17:23:27 +01:00
resp, err := s.accountant.GetValue(req.Account.Name, "rover")
if err != nil {
return nil, err
} else if rover, err := s.world.GetRover(resp); err != nil {
return nil, fmt.Errorf("error getting rover attributes: %s", err)
} else if radar, objs, err := s.world.RadarFromRover(resp); err != nil {
return nil, fmt.Errorf("error getting radar from rover: %s", err)
2020-06-04 17:23:27 +01:00
} else {
response.Objects = objs
response.Tiles = radar
response.Range = int32(rover.Range)
2020-06-04 17:23:27 +01:00
}
return response, nil
2020-06-04 17:23:27 +01:00
}
2020-06-05 22:23:01 +01:00
2020-07-05 12:55:01 +01:00
// Command issues commands to the world based on a gRPC request
func (s *Server) Command(ctx context.Context, req *rove.CommandRequest) (*rove.CommandResponse, error) {
if valid, err := s.accountant.VerifySecret(req.Account.Name, req.Account.Secret); err != nil {
return nil, err
} else if !valid {
return nil, fmt.Errorf("Secret incorrect for account %s", req.Account.Name)
}
resp, err := s.accountant.GetValue(req.Account.Name, "rover")
if err != nil {
return nil, err
}
var cmds []game.Command
for _, c := range req.Commands {
cmds = append(cmds, game.Command{
Bearing: c.Bearing,
Command: c.Command})
}
2020-06-05 22:23:01 +01:00
if err := s.world.Enqueue(resp, cmds...); err != nil {
return nil, err
2020-06-05 22:23:01 +01:00
}
2020-07-05 12:55:01 +01:00
return &rove.CommandResponse{}, nil
2020-06-05 22:23:01 +01:00
}