2020-06-10 17:39:42 +01:00
|
|
|
package internal
|
2020-06-04 17:23:27 +01:00
|
|
|
|
|
|
|
import (
|
2020-06-10 23:23:09 +01:00
|
|
|
"context"
|
2020-06-04 17:23:27 +01:00
|
|
|
"fmt"
|
|
|
|
|
2020-06-10 23:23:09 +01:00
|
|
|
"github.com/mdiluz/rove/pkg/accounts"
|
2020-06-12 22:51:18 +01:00
|
|
|
"github.com/mdiluz/rove/pkg/game"
|
2020-06-05 17:24:27 +01:00
|
|
|
"github.com/mdiluz/rove/pkg/rove"
|
2020-06-04 17:23:27 +01:00
|
|
|
"github.com/mdiluz/rove/pkg/version"
|
2020-06-11 18:16:11 +01:00
|
|
|
"google.golang.org/grpc"
|
2020-06-04 17:23:27 +01:00
|
|
|
)
|
|
|
|
|
2020-06-13 11:57:27 +01:00
|
|
|
func (s *Server) Status(context.Context, *rove.StatusRequest) (*rove.StatusResponse, error) {
|
2020-06-12 22:51:18 +01:00
|
|
|
response := &rove.StatusResponse{
|
2020-06-04 17:23:27 +01:00
|
|
|
Ready: true,
|
|
|
|
Version: version.Version,
|
2020-06-12 22:51:18 +01:00
|
|
|
Tick: int32(s.tick),
|
2020-06-06 16:37:57 +01:00
|
|
|
}
|
|
|
|
|
2020-06-12 22:51:18 +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-13 11:57:27 +01:00
|
|
|
func (s *Server) Register(ctx context.Context, req *rove.RegisterRequest) (*rove.RegisterResponse, error) {
|
2020-06-12 22:51:18 +01:00
|
|
|
if len(req.Name) == 0 {
|
|
|
|
return nil, fmt.Errorf("empty account name")
|
2020-06-10 23:23:09 +01:00
|
|
|
}
|
2020-06-05 16:43:25 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
if _, err := s.accountant.Register(ctx, &accounts.RegisterInfo{Name: req.Name}, grpc.WaitForReady(true)); err != nil {
|
|
|
|
return nil, err
|
2020-06-10 23:23:09 +01:00
|
|
|
|
2020-06-27 00:32:27 +01:00
|
|
|
} else if _, err := s.SpawnRoverForAccount(req.Name); err != nil {
|
2020-06-12 18:58:38 +01:00
|
|
|
return nil, fmt.Errorf("failed to spawn rover for account: %s", err)
|
2020-06-10 18:48:56 +01:00
|
|
|
|
2020-06-10 23:23:09 +01:00
|
|
|
} else if err := s.SaveWorld(); err != nil {
|
2020-06-12 18:58:38 +01:00
|
|
|
return nil, fmt.Errorf("internal server error when saving world: %s", err)
|
2020-06-04 17:23:27 +01:00
|
|
|
}
|
|
|
|
|
2020-06-13 11:57:27 +01:00
|
|
|
return &rove.RegisterResponse{}, nil
|
2020-06-05 16:37:52 +01:00
|
|
|
}
|
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
func (s *Server) Rover(ctx context.Context, req *rove.RoverRequest) (*rove.RoverResponse, error) {
|
|
|
|
response := &rove.RoverResponse{}
|
|
|
|
if len(req.Account) == 0 {
|
|
|
|
return nil, fmt.Errorf("empty account name")
|
2020-06-04 17:23:27 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
} else if resp, err := s.accountant.GetValue(ctx, &accounts.DataKey{Account: req.Account, Key: "rover"}); err != nil {
|
2020-06-12 18:58:38 +01:00
|
|
|
return nil, fmt.Errorf("gRPC failed to contact accountant: %s", err)
|
2020-06-04 17:23:27 +01:00
|
|
|
|
2020-06-27 00:32:27 +01:00
|
|
|
} else if rover, err := s.world.GetRover(resp.Value); err != nil {
|
|
|
|
return nil, fmt.Errorf("error getting rover: %s", err)
|
2020-06-26 23:44:52 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
} else {
|
|
|
|
response = &rove.RoverResponse{
|
2020-06-27 00:32:27 +01:00
|
|
|
Name: rover.Name,
|
2020-06-12 22:51:18 +01:00
|
|
|
Position: &rove.Vector{
|
2020-06-27 00:32:27 +01:00
|
|
|
X: int32(rover.Pos.X),
|
|
|
|
Y: int32(rover.Pos.Y),
|
2020-06-12 22:51:18 +01:00
|
|
|
},
|
2020-06-27 00:32:27 +01:00
|
|
|
Range: int32(rover.Range),
|
|
|
|
Inventory: rover.Inventory,
|
2020-06-27 01:14:17 +01:00
|
|
|
Integrity: int32(rover.Integrity),
|
2020-06-12 22:51:18 +01:00
|
|
|
}
|
2020-06-04 17:23:27 +01:00
|
|
|
}
|
2020-06-05 16:49:24 +01:00
|
|
|
return response, nil
|
2020-06-04 17:23:27 +01:00
|
|
|
}
|
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
func (s *Server) Radar(ctx context.Context, req *rove.RadarRequest) (*rove.RadarResponse, error) {
|
|
|
|
if len(req.Account) == 0 {
|
|
|
|
return nil, fmt.Errorf("empty account name")
|
|
|
|
}
|
2020-06-04 17:23:27 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
response := &rove.RadarResponse{}
|
2020-06-04 17:23:27 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
resp, err := s.accountant.GetValue(ctx, &accounts.DataKey{Account: req.Account, Key: "rover"})
|
|
|
|
if err != nil {
|
2020-06-12 18:58:38 +01:00
|
|
|
return nil, fmt.Errorf("gRPC failed to contact accountant: %s", err)
|
2020-06-10 22:48:45 +01:00
|
|
|
|
2020-06-27 00:32:27 +01:00
|
|
|
} else if rover, err := s.world.GetRover(resp.Value); err != nil {
|
2020-06-12 18:58:38 +01:00
|
|
|
return nil, fmt.Errorf("error getting rover attributes: %s", err)
|
2020-06-08 18:14:24 +01:00
|
|
|
|
2020-06-27 00:32:27 +01:00
|
|
|
} else if radar, err := s.world.RadarFromRover(resp.Value); err != nil {
|
2020-06-12 18:58:38 +01:00
|
|
|
return nil, fmt.Errorf("error getting radar from rover: %s", err)
|
2020-06-04 17:23:27 +01:00
|
|
|
|
2020-06-04 22:14:55 +01:00
|
|
|
} else {
|
2020-06-08 18:14:24 +01:00
|
|
|
response.Tiles = radar
|
2020-06-27 00:32:27 +01:00
|
|
|
response.Range = int32(rover.Range)
|
2020-06-04 17:23:27 +01:00
|
|
|
}
|
|
|
|
|
2020-06-05 16:49:24 +01:00
|
|
|
return response, nil
|
2020-06-04 17:23:27 +01:00
|
|
|
}
|
2020-06-05 22:23:01 +01:00
|
|
|
|
2020-06-13 11:57:27 +01:00
|
|
|
func (s *Server) Commands(ctx context.Context, req *rove.CommandsRequest) (*rove.CommandsResponse, error) {
|
2020-06-12 22:51:18 +01:00
|
|
|
if len(req.Account) == 0 {
|
|
|
|
return nil, fmt.Errorf("empty account")
|
|
|
|
}
|
|
|
|
resp, err := s.accountant.GetValue(ctx, &accounts.DataKey{Account: req.Account, Key: "rover"})
|
2020-06-05 22:23:01 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2020-06-10 23:23:09 +01:00
|
|
|
|
2020-06-12 22:51:18 +01:00
|
|
|
var cmds []game.Command
|
|
|
|
for _, c := range req.Commands {
|
|
|
|
cmds = append(cmds, game.Command{
|
2020-06-26 22:26:27 +01:00
|
|
|
Bearing: c.Bearing,
|
|
|
|
Command: c.Command})
|
2020-06-12 22:51:18 +01:00
|
|
|
}
|
2020-06-05 22:23:01 +01:00
|
|
|
|
2020-06-27 00:32:27 +01:00
|
|
|
if err := s.world.Enqueue(resp.Value, cmds...); err != nil {
|
2020-06-12 22:51:18 +01:00
|
|
|
return nil, err
|
2020-06-05 22:23:01 +01:00
|
|
|
}
|
|
|
|
|
2020-06-13 11:57:27 +01:00
|
|
|
return &rove.CommandsResponse{}, nil
|
2020-06-05 22:23:01 +01:00
|
|
|
}
|