395 lines
8.2 KiB
Go
395 lines
8.2 KiB
Go
package domain
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"net/url"
|
|
"slices"
|
|
"time"
|
|
)
|
|
|
|
type Server struct {
|
|
key string
|
|
versionCode string
|
|
url *url.URL
|
|
open bool
|
|
special bool
|
|
numPlayers int
|
|
numTribes int
|
|
numVillages int
|
|
numPlayerVillages int
|
|
numBarbarianVillages int
|
|
numBonusVillages int
|
|
config ServerConfig
|
|
buildingInfo BuildingInfo
|
|
unitInfo UnitInfo
|
|
createdAt time.Time
|
|
playerDataSyncedAt time.Time
|
|
playerSnapshotsCreatedAt time.Time
|
|
tribeDataSyncedAt time.Time
|
|
tribeSnapshotsCreatedAt time.Time
|
|
villageDataSyncedAt time.Time
|
|
ennoblementDataSyncedAt time.Time
|
|
}
|
|
|
|
// UnmarshalServerFromDatabase unmarshals Server from the database.
|
|
//
|
|
// It should be used only for unmarshalling from the database!
|
|
// You can't use UnmarshalServerFromDatabase as constructor - It may put domain into the invalid state!
|
|
func UnmarshalServerFromDatabase(
|
|
key string,
|
|
versionCode string,
|
|
rawURL string,
|
|
open bool,
|
|
special bool,
|
|
numPlayers int,
|
|
numTribes int,
|
|
numVillages int,
|
|
numPlayerVillages int,
|
|
numBarbarianVillages int,
|
|
numBonusVillages int,
|
|
config ServerConfig,
|
|
buildingInfo BuildingInfo,
|
|
unitInfo UnitInfo,
|
|
createdAt time.Time,
|
|
playerDataSyncedAt time.Time,
|
|
playerSnapshotsCreatedAt time.Time,
|
|
tribeDataSyncedAt time.Time,
|
|
tribeSnapshotsCreatedAt time.Time,
|
|
villageDataSyncedAt time.Time,
|
|
ennoblementDataSyncedAt time.Time,
|
|
) (Server, error) {
|
|
if key == "" {
|
|
return Server{}, errors.New("key can't be blank")
|
|
}
|
|
|
|
if versionCode == "" {
|
|
return Server{}, errors.New("version code can't be blank")
|
|
}
|
|
|
|
u, err := parseURL(rawURL)
|
|
if err != nil {
|
|
return Server{}, err
|
|
}
|
|
|
|
return Server{
|
|
key: key,
|
|
url: u,
|
|
open: open,
|
|
special: special,
|
|
numPlayers: numPlayers,
|
|
numTribes: numTribes,
|
|
numVillages: numVillages,
|
|
numPlayerVillages: numPlayerVillages,
|
|
numBarbarianVillages: numBarbarianVillages,
|
|
numBonusVillages: numBonusVillages,
|
|
config: config,
|
|
buildingInfo: buildingInfo,
|
|
unitInfo: unitInfo,
|
|
createdAt: createdAt,
|
|
playerDataSyncedAt: playerDataSyncedAt,
|
|
playerSnapshotsCreatedAt: playerSnapshotsCreatedAt,
|
|
tribeDataSyncedAt: tribeDataSyncedAt,
|
|
tribeSnapshotsCreatedAt: tribeSnapshotsCreatedAt,
|
|
villageDataSyncedAt: villageDataSyncedAt,
|
|
ennoblementDataSyncedAt: ennoblementDataSyncedAt,
|
|
versionCode: versionCode,
|
|
}, nil
|
|
}
|
|
|
|
func (s Server) Key() string {
|
|
return s.key
|
|
}
|
|
|
|
func (s Server) VersionCode() string {
|
|
return s.versionCode
|
|
}
|
|
|
|
func (s Server) URL() *url.URL {
|
|
return s.url
|
|
}
|
|
|
|
func (s Server) Open() bool {
|
|
return s.open
|
|
}
|
|
|
|
func (s Server) Special() bool {
|
|
return s.special
|
|
}
|
|
|
|
func (s Server) NumPlayers() int {
|
|
return s.numPlayers
|
|
}
|
|
|
|
func (s Server) NumTribes() int {
|
|
return s.numTribes
|
|
}
|
|
|
|
func (s Server) NumVillages() int {
|
|
return s.numVillages
|
|
}
|
|
|
|
func (s Server) NumPlayerVillages() int {
|
|
return s.numPlayerVillages
|
|
}
|
|
|
|
func (s Server) NumBarbarianVillages() int {
|
|
return s.numBarbarianVillages
|
|
}
|
|
|
|
func (s Server) NumBonusVillages() int {
|
|
return s.numBonusVillages
|
|
}
|
|
|
|
func (s Server) Config() ServerConfig {
|
|
return s.config
|
|
}
|
|
|
|
func (s Server) BuildingInfo() BuildingInfo {
|
|
return s.buildingInfo
|
|
}
|
|
|
|
func (s Server) UnitInfo() UnitInfo {
|
|
return s.unitInfo
|
|
}
|
|
|
|
func (s Server) CreatedAt() time.Time {
|
|
return s.createdAt
|
|
}
|
|
|
|
func (s Server) PlayerDataSyncedAt() time.Time {
|
|
return s.playerDataSyncedAt
|
|
}
|
|
|
|
func (s Server) PlayerSnapshotsCreatedAt() time.Time {
|
|
return s.playerSnapshotsCreatedAt
|
|
}
|
|
|
|
func (s Server) TribeDataSyncedAt() time.Time {
|
|
return s.tribeDataSyncedAt
|
|
}
|
|
|
|
func (s Server) TribeSnapshotsCreatedAt() time.Time {
|
|
return s.tribeSnapshotsCreatedAt
|
|
}
|
|
|
|
func (s Server) VillageDataSyncedAt() time.Time {
|
|
return s.villageDataSyncedAt
|
|
}
|
|
|
|
func (s Server) EnnoblementDataSyncedAt() time.Time {
|
|
return s.ennoblementDataSyncedAt
|
|
}
|
|
|
|
type Servers []Server
|
|
|
|
// Close finds all servers with Server.Open returning true that are not in the given slice with open servers
|
|
// and then converts them to BaseServers with the corrected open value.
|
|
func (ss Servers) Close(open BaseServers) (BaseServers, error) {
|
|
res := make(BaseServers, 0, len(ss))
|
|
|
|
for _, s := range ss {
|
|
if !s.Open() || slices.ContainsFunc(open, func(openServer BaseServer) bool {
|
|
return openServer.Key() == s.Key() && openServer.Open() == s.Open()
|
|
}) {
|
|
continue
|
|
}
|
|
|
|
base, err := NewBaseServer(s.Key(), s.URL().String(), false)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("couldn't construct BaseServer for server with key '%s': %w", s.Key(), err)
|
|
}
|
|
|
|
res = append(res, base)
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
type CreateServerParams struct {
|
|
base BaseServer
|
|
versionCode string
|
|
}
|
|
|
|
func NewCreateServerParams(servers BaseServers, versionCode string) ([]CreateServerParams, error) {
|
|
if err := validateVersionCode(versionCode); err != nil {
|
|
return nil, ValidationError{
|
|
Err: err,
|
|
Field: "versionCode",
|
|
}
|
|
}
|
|
|
|
res := make([]CreateServerParams, 0, len(servers))
|
|
|
|
for i, s := range servers {
|
|
if s.IsZero() {
|
|
return nil, fmt.Errorf("servers[%d] is an empty struct", i)
|
|
}
|
|
|
|
res = append(res, CreateServerParams{
|
|
base: s,
|
|
versionCode: versionCode,
|
|
})
|
|
}
|
|
|
|
return res, nil
|
|
}
|
|
|
|
func (params CreateServerParams) Base() BaseServer {
|
|
return params.base
|
|
}
|
|
|
|
func (params CreateServerParams) VersionCode() string {
|
|
return params.versionCode
|
|
}
|
|
|
|
type ServerSort uint8
|
|
|
|
const (
|
|
ServerSortKeyASC ServerSort = iota + 1
|
|
ServerSortKeyDESC
|
|
ServerSortOpenASC
|
|
ServerSortOpenDESC
|
|
)
|
|
|
|
const ServerListMaxLimit = 500
|
|
|
|
type ListServersParams struct {
|
|
keys []string
|
|
keyGT NullString
|
|
versionCodes []string
|
|
open NullBool
|
|
special NullBool
|
|
sort []ServerSort
|
|
limit int
|
|
offset int
|
|
}
|
|
|
|
func NewListServersParams() ListServersParams {
|
|
return ListServersParams{
|
|
sort: []ServerSort{ServerSortKeyASC},
|
|
limit: ServerListMaxLimit,
|
|
special: NullBool{
|
|
Value: false,
|
|
Valid: true,
|
|
},
|
|
}
|
|
}
|
|
|
|
func (params *ListServersParams) Keys() []string {
|
|
return params.keys
|
|
}
|
|
|
|
func (params *ListServersParams) SetKeys(keys []string) error {
|
|
params.keys = keys
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) KeyGT() NullString {
|
|
return params.keyGT
|
|
}
|
|
|
|
func (params *ListServersParams) SetKeyGT(keyGT NullString) error {
|
|
params.keyGT = keyGT
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) VersionCodes() []string {
|
|
return params.versionCodes
|
|
}
|
|
|
|
func (params *ListServersParams) SetVersionCodes(versionCodes []string) error {
|
|
params.versionCodes = versionCodes
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) Open() NullBool {
|
|
return params.open
|
|
}
|
|
|
|
func (params *ListServersParams) SetOpen(open NullBool) error {
|
|
params.open = open
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) Special() NullBool {
|
|
return params.special
|
|
}
|
|
|
|
func (params *ListServersParams) SetSpecial(special NullBool) error {
|
|
params.special = special
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) Sort() []ServerSort {
|
|
return params.sort
|
|
}
|
|
|
|
const (
|
|
serverSortMinLength = 1
|
|
serverSortMaxLength = 2
|
|
)
|
|
|
|
func (params *ListServersParams) SetSort(sort []ServerSort) error {
|
|
if err := validateSliceLen(sort, serverSortMinLength, serverSortMaxLength); err != nil {
|
|
return ValidationError{
|
|
Field: "sort",
|
|
Err: err,
|
|
}
|
|
}
|
|
|
|
params.sort = sort
|
|
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) Limit() int {
|
|
return params.limit
|
|
}
|
|
|
|
func (params *ListServersParams) SetLimit(limit int) error {
|
|
if limit <= 0 {
|
|
return ValidationError{
|
|
Field: "limit",
|
|
Err: MinGreaterEqualError{
|
|
Min: 1,
|
|
Current: limit,
|
|
},
|
|
}
|
|
}
|
|
|
|
if limit > ServerListMaxLimit {
|
|
return ValidationError{
|
|
Field: "limit",
|
|
Err: MaxLessEqualError{
|
|
Max: ServerListMaxLimit,
|
|
Current: limit,
|
|
},
|
|
}
|
|
}
|
|
|
|
params.limit = limit
|
|
|
|
return nil
|
|
}
|
|
|
|
func (params *ListServersParams) Offset() int {
|
|
return params.offset
|
|
}
|
|
|
|
func (params *ListServersParams) SetOffset(offset int) error {
|
|
if offset < 0 {
|
|
return ValidationError{
|
|
Field: "offset",
|
|
Err: MinGreaterEqualError{
|
|
Min: 0,
|
|
Current: offset,
|
|
},
|
|
}
|
|
}
|
|
|
|
params.offset = offset
|
|
|
|
return nil
|
|
}
|