2020-06-22 15:59:56 +00:00
|
|
|
package usecase
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2020-08-01 11:57:18 +00:00
|
|
|
"sort"
|
2020-06-22 15:59:56 +00:00
|
|
|
"strconv"
|
|
|
|
"strings"
|
2020-07-31 18:49:00 +00:00
|
|
|
"sync"
|
2020-06-22 15:59:56 +00:00
|
|
|
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/tribalwarshelp/api/servermap"
|
|
|
|
"github.com/tribalwarshelp/api/village"
|
|
|
|
"github.com/tribalwarshelp/map-generator/generator"
|
|
|
|
"github.com/tribalwarshelp/shared/models"
|
2020-07-31 18:49:00 +00:00
|
|
|
"golang.org/x/sync/errgroup"
|
2020-06-22 15:59:56 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
defaultBarbarianVillagesColor = "#808080"
|
|
|
|
defaultPlayerVillagesColor = "#FF0000"
|
|
|
|
)
|
|
|
|
|
|
|
|
type usecase struct {
|
|
|
|
villageRepo village.Repository
|
|
|
|
}
|
|
|
|
|
|
|
|
func New(villageRepo village.Repository) servermap.Usecase {
|
|
|
|
return &usecase{villageRepo}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (ucase *usecase) GetMarkers(ctx context.Context, cfg servermap.GetMarkersConfig) ([]*generator.Marker, error) {
|
2020-07-31 18:49:00 +00:00
|
|
|
var mutex sync.Mutex
|
|
|
|
g := new(errgroup.Group)
|
|
|
|
|
2020-06-22 15:59:56 +00:00
|
|
|
tribes := make(map[string][]int)
|
|
|
|
tribeIDs := []int{}
|
|
|
|
cache := make(map[int]bool)
|
|
|
|
for _, data := range cfg.Tribes {
|
|
|
|
//id,#color
|
|
|
|
id, color, err := parseQueryParam(data)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "tribe=%s", data)
|
|
|
|
}
|
|
|
|
if ok := cache[id]; ok || color == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
tribeIDs = append(tribeIDs, id)
|
|
|
|
cache[id] = true
|
|
|
|
tribes[color] = append(tribes[color], id)
|
|
|
|
}
|
|
|
|
|
|
|
|
players := make(map[string][]int)
|
|
|
|
playerIDs := []int{}
|
|
|
|
cache = make(map[int]bool)
|
|
|
|
for _, data := range cfg.Players {
|
|
|
|
//id,#color
|
|
|
|
id, color, err := parseQueryParam(data)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "player=%s", data)
|
|
|
|
}
|
|
|
|
if ok := cache[id]; ok || color == "" {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
playerIDs = append(playerIDs, id)
|
|
|
|
cache[id] = true
|
|
|
|
players[color] = append(players[color], id)
|
|
|
|
}
|
|
|
|
|
|
|
|
markers := []*generator.Marker{}
|
|
|
|
|
|
|
|
if cfg.ShowOtherPlayerVillages {
|
2020-07-31 18:49:00 +00:00
|
|
|
g.Go(func() error {
|
|
|
|
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
|
|
|
|
Server: cfg.Server,
|
|
|
|
Filter: &models.VillageFilter{
|
|
|
|
PlayerFilter: &models.PlayerFilter{
|
|
|
|
IdNEQ: append(playerIDs, 0),
|
|
|
|
TribeFilter: &models.TribeFilter{
|
|
|
|
IdNEQ: tribeIDs,
|
|
|
|
},
|
2020-06-22 15:59:56 +00:00
|
|
|
},
|
|
|
|
},
|
2020-08-01 10:26:54 +00:00
|
|
|
Columns: []string{"x", "y"},
|
|
|
|
Count: false,
|
2020-07-31 18:49:00 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
mutex.Lock()
|
|
|
|
markers = append(markers, &generator.Marker{
|
|
|
|
Villages: villages,
|
|
|
|
Color: defaultPlayerVillagesColor,
|
|
|
|
})
|
|
|
|
mutex.Unlock()
|
|
|
|
return nil
|
2020-06-22 15:59:56 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg.ShowBarbarianVillages {
|
2020-07-31 18:49:00 +00:00
|
|
|
g.Go(func() error {
|
|
|
|
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
|
|
|
|
Server: cfg.Server,
|
|
|
|
Filter: &models.VillageFilter{
|
|
|
|
PlayerID: []int{0},
|
|
|
|
},
|
2020-08-01 10:26:54 +00:00
|
|
|
Columns: []string{"x", "y"},
|
|
|
|
Count: false,
|
2020-07-31 18:49:00 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
mutex.Lock()
|
|
|
|
markers = append(markers, &generator.Marker{
|
|
|
|
Villages: villages,
|
|
|
|
Color: defaultBarbarianVillagesColor,
|
|
|
|
})
|
|
|
|
mutex.Unlock()
|
|
|
|
return nil
|
2020-06-22 15:59:56 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
for color, tribeIDs := range tribes {
|
2020-07-31 19:31:33 +00:00
|
|
|
c := color
|
|
|
|
ids := tribeIDs
|
2020-07-31 18:49:00 +00:00
|
|
|
g.Go(func() error {
|
|
|
|
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
|
|
|
|
Server: cfg.Server,
|
|
|
|
Filter: &models.VillageFilter{
|
|
|
|
PlayerFilter: &models.PlayerFilter{
|
2020-07-31 19:31:33 +00:00
|
|
|
TribeID: ids,
|
2020-07-31 18:49:00 +00:00
|
|
|
},
|
2020-06-22 15:59:56 +00:00
|
|
|
},
|
2020-08-01 10:26:54 +00:00
|
|
|
Columns: []string{"x", "y"},
|
|
|
|
Count: false,
|
2020-07-31 18:49:00 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
mutex.Lock()
|
|
|
|
markers = append(markers, &generator.Marker{
|
|
|
|
Villages: villages,
|
2020-07-31 19:31:33 +00:00
|
|
|
Color: c,
|
2020-08-01 11:57:18 +00:00
|
|
|
Larger: cfg.LargerMarkers,
|
2020-07-31 18:49:00 +00:00
|
|
|
})
|
|
|
|
mutex.Unlock()
|
|
|
|
return nil
|
2020-06-22 15:59:56 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
for color, playerIDs := range players {
|
2020-07-31 19:31:33 +00:00
|
|
|
c := color
|
|
|
|
ids := playerIDs
|
2020-07-31 18:49:00 +00:00
|
|
|
g.Go(func() error {
|
|
|
|
villages, _, err := ucase.villageRepo.Fetch(ctx, village.FetchConfig{
|
|
|
|
Server: cfg.Server,
|
|
|
|
Filter: &models.VillageFilter{
|
2020-07-31 19:31:33 +00:00
|
|
|
PlayerID: ids,
|
2020-07-31 18:49:00 +00:00
|
|
|
},
|
2020-08-01 10:26:54 +00:00
|
|
|
Columns: []string{"x", "y"},
|
|
|
|
Count: false,
|
2020-07-31 18:49:00 +00:00
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
mutex.Lock()
|
|
|
|
markers = append(markers, &generator.Marker{
|
|
|
|
Villages: villages,
|
2020-07-31 19:31:33 +00:00
|
|
|
Color: c,
|
2020-08-01 11:57:18 +00:00
|
|
|
Larger: cfg.LargerMarkers,
|
2020-07-31 18:49:00 +00:00
|
|
|
})
|
|
|
|
mutex.Unlock()
|
|
|
|
return nil
|
2020-06-22 15:59:56 +00:00
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-07-31 18:49:00 +00:00
|
|
|
err := g.Wait()
|
2020-08-01 11:57:18 +00:00
|
|
|
sort.SliceStable(markers, func(i, j int) bool {
|
|
|
|
return markers[i].Color < markers[j].Color
|
|
|
|
})
|
2020-07-31 18:49:00 +00:00
|
|
|
return markers, err
|
2020-06-22 15:59:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func parseQueryParam(str string) (int, string, error) {
|
|
|
|
splitted := strings.Split(str, ",")
|
|
|
|
if len(splitted) != 2 {
|
|
|
|
return 0, "", fmt.Errorf("Invalid format (should be id,#hexcolor)")
|
|
|
|
}
|
|
|
|
id, err := strconv.Atoi(splitted[0])
|
|
|
|
if err != nil {
|
|
|
|
return 0, "", errors.Wrapf(err, "Invalid format (should be id,hexcolor)")
|
|
|
|
}
|
|
|
|
if id <= 0 {
|
|
|
|
return 0, "", fmt.Errorf("ID should be greater than 0")
|
|
|
|
}
|
|
|
|
return id, splitted[1], nil
|
|
|
|
}
|