These were a "security" feature but pre-emptive and just add complications when we can implement secrets later
187 lines
5 KiB
Go
187 lines
5 KiB
Go
package internal
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
|
|
"github.com/mdiluz/rove/pkg/rove"
|
|
"github.com/mdiluz/rove/pkg/version"
|
|
)
|
|
|
|
// Handler describes a function that handles any incoming request and can respond
|
|
type Handler func(*Server, map[string]string, io.ReadCloser, io.Writer) (interface{}, error)
|
|
|
|
// Route defines the information for a single path->function route
|
|
type Route struct {
|
|
path string
|
|
method string
|
|
handler Handler
|
|
}
|
|
|
|
// Routes is an array of all the Routes
|
|
var Routes = []Route{
|
|
{
|
|
path: "/status",
|
|
method: http.MethodGet,
|
|
handler: HandleStatus,
|
|
},
|
|
{
|
|
path: "/register",
|
|
method: http.MethodPost,
|
|
handler: HandleRegister,
|
|
},
|
|
{
|
|
path: "/{account}/command",
|
|
method: http.MethodPost,
|
|
handler: HandleCommand,
|
|
},
|
|
{
|
|
path: "/{account}/radar",
|
|
method: http.MethodGet,
|
|
handler: HandleRadar,
|
|
},
|
|
{
|
|
path: "/{account}/rover",
|
|
method: http.MethodGet,
|
|
handler: HandleRover,
|
|
},
|
|
}
|
|
|
|
// HandleStatus handles the /status request
|
|
func HandleStatus(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer) (interface{}, error) {
|
|
|
|
// Simply return the current server status
|
|
response := rove.StatusResponse{
|
|
Ready: true,
|
|
Version: version.Version,
|
|
Tick: s.tick,
|
|
}
|
|
|
|
// 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
|
|
}
|
|
|
|
// HandleRegister handles /register endpoint
|
|
func HandleRegister(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer) (interface{}, error) {
|
|
var response = rove.RegisterResponse{
|
|
Success: false,
|
|
}
|
|
|
|
// Decode the registration info, verify it and register the account
|
|
var data rove.RegisterData
|
|
err := json.NewDecoder(b).Decode(&data)
|
|
if err != nil {
|
|
fmt.Printf("Failed to decode json: %s\n", err)
|
|
response.Error = err.Error()
|
|
|
|
} else if len(data.Name) == 0 {
|
|
response.Error = "Cannot register empty name"
|
|
|
|
} else if acc, err := s.accountant.RegisterAccount(data.Name); err != nil {
|
|
response.Error = err.Error()
|
|
|
|
} else if _, _, err := s.SpawnRoverForAccount(acc.Name); err != nil {
|
|
response.Error = err.Error()
|
|
|
|
} else if err := s.SaveAll(); err != nil {
|
|
response.Error = fmt.Sprintf("Internal server error when saving: %s", err)
|
|
|
|
} else {
|
|
// Save out the new accounts
|
|
response.Success = true
|
|
}
|
|
|
|
fmt.Printf("register response:%+v\n", response)
|
|
return response, nil
|
|
}
|
|
|
|
// HandleSpawn will spawn the player entity for the associated account
|
|
func HandleCommand(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer) (interface{}, error) {
|
|
var response = rove.CommandResponse{
|
|
Success: false,
|
|
}
|
|
|
|
id := vars["account"]
|
|
|
|
// Decode the commands, verify them and the account, and execute the commands
|
|
var data rove.CommandData
|
|
if err := json.NewDecoder(b).Decode(&data); err != nil {
|
|
fmt.Printf("Failed to decode json: %s\n", err)
|
|
response.Error = err.Error()
|
|
|
|
} else if len(id) == 0 {
|
|
response.Error = "No account ID provided"
|
|
|
|
} else if inst, err := s.accountant.GetRover(id); err != nil {
|
|
response.Error = fmt.Sprintf("Provided account has no rover: %s", err)
|
|
|
|
} else if err := s.world.Enqueue(inst, data.Commands...); err != nil {
|
|
response.Error = fmt.Sprintf("Failed to execute commands: %s", err)
|
|
|
|
} else {
|
|
response.Success = true
|
|
}
|
|
|
|
fmt.Printf("command response \taccount:%s\tresponse:%+v\n", id, response)
|
|
return response, nil
|
|
}
|
|
|
|
// HandleRadar handles the radar request
|
|
func HandleRadar(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer) (interface{}, error) {
|
|
var response = rove.RadarResponse{
|
|
Success: false,
|
|
}
|
|
|
|
id := vars["account"]
|
|
if len(id) == 0 {
|
|
response.Error = "No account ID provided"
|
|
|
|
} else if inst, err := s.accountant.GetRover(id); err != nil {
|
|
response.Error = fmt.Sprintf("Provided account has no rover: %s", err)
|
|
|
|
} else if attrib, err := s.world.RoverAttributes(inst); err != nil {
|
|
response.Error = fmt.Sprintf("Error getting rover attributes: %s", err)
|
|
|
|
} else if radar, err := s.world.RadarFromRover(inst); err != nil {
|
|
response.Error = fmt.Sprintf("Error getting radar from rover: %s", err)
|
|
|
|
} else {
|
|
response.Tiles = radar
|
|
response.Range = attrib.Range
|
|
response.Success = true
|
|
}
|
|
|
|
fmt.Printf("radar response \taccount:%s\tresponse:%+v\n", id, response)
|
|
return response, nil
|
|
}
|
|
|
|
// HandleRover handles the rover request
|
|
func HandleRover(s *Server, vars map[string]string, b io.ReadCloser, w io.Writer) (interface{}, error) {
|
|
var response = rove.RoverResponse{
|
|
Success: false,
|
|
}
|
|
|
|
id := vars["account"]
|
|
if len(id) == 0 {
|
|
response.Error = "No account ID provided"
|
|
|
|
} else if inst, err := s.accountant.GetRover(id); err != nil {
|
|
response.Error = fmt.Sprintf("Provided account has no rover: %s", err)
|
|
|
|
} else if attribs, err := s.world.RoverAttributes(inst); err != nil {
|
|
response.Error = fmt.Sprintf("Error getting radar from rover: %s", err)
|
|
|
|
} else {
|
|
response.Attributes = attribs
|
|
response.Success = true
|
|
}
|
|
|
|
fmt.Printf("rover response \taccount:%s\tresponse:%+v\n", id, response)
|
|
return response, nil
|
|
}
|