2023-12-23 09:54:47 +00:00
|
|
|
package app
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"fmt"
|
2023-12-30 09:10:03 +00:00
|
|
|
"time"
|
2023-12-23 09:54:47 +00:00
|
|
|
|
|
|
|
"gitea.dwysokinski.me/twhelp/corev3/internal/domain"
|
|
|
|
)
|
|
|
|
|
2023-12-25 09:13:42 +00:00
|
|
|
type ServerRepository interface {
|
|
|
|
CreateOrUpdate(ctx context.Context, params ...domain.CreateServerParams) error
|
2024-02-07 07:17:47 +00:00
|
|
|
List(ctx context.Context, params domain.ListServersParams) (domain.ListServersResult, error)
|
2023-12-25 11:04:12 +00:00
|
|
|
Update(ctx context.Context, key string, params domain.UpdateServerParams) error
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
2023-12-23 09:54:47 +00:00
|
|
|
type ServerService struct {
|
2023-12-30 08:38:32 +00:00
|
|
|
repo ServerRepository
|
|
|
|
twSvc TWService
|
|
|
|
pub ServerPublisher
|
2023-12-23 09:54:47 +00:00
|
|
|
}
|
|
|
|
|
2023-12-30 08:38:32 +00:00
|
|
|
func NewServerService(repo ServerRepository, twSvc TWService, pub ServerPublisher) *ServerService {
|
|
|
|
return &ServerService{repo: repo, twSvc: twSvc, pub: pub}
|
2023-12-23 09:54:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *ServerService) Sync(ctx context.Context, payload domain.SyncServersCmdPayload) error {
|
2023-12-25 09:13:42 +00:00
|
|
|
versionCode := payload.VersionCode()
|
|
|
|
|
2023-12-27 08:07:40 +00:00
|
|
|
openServers, err := svc.twSvc.GetOpenServers(ctx, payload.URL())
|
2023-12-23 09:54:47 +00:00
|
|
|
if err != nil {
|
2023-12-29 08:23:05 +00:00
|
|
|
return fmt.Errorf("%s: couldn't get open servers: %w", versionCode, err)
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
specialServers, err := svc.listAllSpecial(ctx, versionCode)
|
|
|
|
if err != nil {
|
2023-12-29 08:23:05 +00:00
|
|
|
return fmt.Errorf("%s: couldn't list special servers: %w", versionCode, err)
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
2024-01-03 08:59:24 +00:00
|
|
|
currentlyStoredOpenServers, err := svc.ListAllOpen(ctx, versionCode)
|
2023-12-25 09:13:42 +00:00
|
|
|
if err != nil {
|
2023-12-29 08:23:05 +00:00
|
|
|
return fmt.Errorf("%s: couldn't list open servers: %w", versionCode, err)
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
openServersWithoutSpecial := openServers.FilterOutSpecial(specialServers)
|
|
|
|
|
|
|
|
serversToBeClosed, err := currentlyStoredOpenServers.Close(openServersWithoutSpecial)
|
|
|
|
if err != nil {
|
2023-12-29 08:23:05 +00:00
|
|
|
return fmt.Errorf("%s: couldn't close servers: %w", versionCode, err)
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
params, err := domain.NewCreateServerParams(append(openServersWithoutSpecial, serversToBeClosed...), versionCode)
|
|
|
|
if err != nil {
|
2023-12-29 08:23:05 +00:00
|
|
|
return fmt.Errorf("%s: %w", versionCode, err)
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
2023-12-25 09:53:01 +00:00
|
|
|
if err = svc.repo.CreateOrUpdate(ctx, params...); err != nil {
|
2023-12-29 08:23:05 +00:00
|
|
|
return fmt.Errorf("%s: couldn't create/update servers: %w", versionCode, err)
|
2023-12-25 09:53:01 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
payloads, err := domain.NewServerSyncedEventPayloads(openServersWithoutSpecial, versionCode)
|
|
|
|
if err != nil {
|
2024-01-04 10:44:36 +00:00
|
|
|
return fmt.Errorf("%s: couldn't construct domain.ServerSyncedEventPayload: %w", versionCode, err)
|
2023-12-25 09:53:01 +00:00
|
|
|
}
|
|
|
|
|
2024-01-04 10:44:36 +00:00
|
|
|
if err = svc.pub.EventSynced(ctx, payloads...); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", versionCode, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2023-12-25 09:13:42 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *ServerService) listAllSpecial(ctx context.Context, versionCode string) (domain.Servers, error) {
|
|
|
|
params := domain.NewListServersParams()
|
|
|
|
if err := params.SetVersionCodes([]string{versionCode}); err != nil {
|
|
|
|
return nil, err
|
2023-12-23 09:54:47 +00:00
|
|
|
}
|
2023-12-25 09:13:42 +00:00
|
|
|
if err := params.SetSpecial(domain.NullBool{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: true,
|
2023-12-25 09:13:42 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.ListAll(ctx, params)
|
|
|
|
}
|
|
|
|
|
2024-01-03 08:59:24 +00:00
|
|
|
func (svc *ServerService) ListAllOpen(ctx context.Context, versionCode string) (domain.Servers, error) {
|
2023-12-25 09:13:42 +00:00
|
|
|
params := domain.NewListServersParams()
|
|
|
|
if err := params.SetVersionCodes([]string{versionCode}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err := params.SetOpen(domain.NullBool{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: true,
|
2023-12-25 09:13:42 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.ListAll(ctx, params)
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListAll retrieves all servers from the database based on the given params in an optimal way.
|
2024-02-07 07:17:47 +00:00
|
|
|
// You can't specify a custom limit/cursor/sort for this operation.
|
2023-12-25 09:13:42 +00:00
|
|
|
func (svc *ServerService) ListAll(ctx context.Context, params domain.ListServersParams) (domain.Servers, error) {
|
|
|
|
if err := params.SetLimit(domain.ServerListMaxLimit); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
if err := params.SetSort([]domain.ServerSort{domain.ServerSortKeyASC}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2024-02-09 11:30:01 +00:00
|
|
|
if err := params.SetCursor(domain.ServerCursor{}); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-12-25 09:13:42 +00:00
|
|
|
|
|
|
|
var servers domain.Servers
|
|
|
|
|
|
|
|
for {
|
2024-02-07 07:17:47 +00:00
|
|
|
res, err := svc.repo.List(ctx, params)
|
2023-12-25 09:13:42 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-02-07 07:17:47 +00:00
|
|
|
servers = append(servers, res.Servers()...)
|
|
|
|
|
|
|
|
if res.Next().IsZero() {
|
2023-12-25 09:13:42 +00:00
|
|
|
return servers, nil
|
|
|
|
}
|
|
|
|
|
2024-02-07 07:17:47 +00:00
|
|
|
if err = params.SetCursor(res.Next()); err != nil {
|
2023-12-25 09:13:42 +00:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
2023-12-23 09:54:47 +00:00
|
|
|
}
|
2023-12-25 11:04:12 +00:00
|
|
|
|
2024-02-09 11:30:01 +00:00
|
|
|
func (svc *ServerService) List(ctx context.Context, params domain.ListServersParams) (domain.ListServersResult, error) {
|
|
|
|
return svc.repo.List(ctx, params)
|
|
|
|
}
|
|
|
|
|
2023-12-25 11:04:12 +00:00
|
|
|
func (svc *ServerService) SyncConfigAndInfo(ctx context.Context, payload domain.ServerSyncedEventPayload) error {
|
2023-12-30 09:10:03 +00:00
|
|
|
key := payload.Key()
|
2023-12-27 08:07:40 +00:00
|
|
|
u := payload.URL()
|
2023-12-25 11:04:12 +00:00
|
|
|
|
2023-12-27 08:07:40 +00:00
|
|
|
cfg, err := svc.twSvc.GetServerConfig(ctx, u)
|
2023-12-25 11:04:12 +00:00
|
|
|
if err != nil {
|
2023-12-30 09:10:03 +00:00
|
|
|
return fmt.Errorf("%s: couldn't get server config: %w", key, err)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
|
|
|
|
2023-12-27 08:07:40 +00:00
|
|
|
buildingInfo, err := svc.twSvc.GetBuildingInfo(ctx, u)
|
2023-12-25 11:04:12 +00:00
|
|
|
if err != nil {
|
2023-12-30 09:10:03 +00:00
|
|
|
return fmt.Errorf("%s: couldn't get building info: %w", key, err)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
|
|
|
|
2023-12-27 08:07:40 +00:00
|
|
|
unitInfo, err := svc.twSvc.GetUnitInfo(ctx, u)
|
2023-12-25 11:04:12 +00:00
|
|
|
if err != nil {
|
2023-12-30 09:10:03 +00:00
|
|
|
return fmt.Errorf("%s: couldn't get unit info: %w", key, err)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err = updateParams.SetConfig(domain.NullServerConfig{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: cfg,
|
2023-12-25 11:04:12 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
2023-12-30 09:10:03 +00:00
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
|
|
|
if err = updateParams.SetBuildingInfo(domain.NullBuildingInfo{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: buildingInfo,
|
2023-12-25 11:04:12 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
2023-12-30 09:10:03 +00:00
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
|
|
|
if err = updateParams.SetUnitInfo(domain.NullUnitInfo{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: unitInfo,
|
2023-12-25 11:04:12 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
2023-12-30 09:10:03 +00:00
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
|
|
|
|
2023-12-30 09:10:03 +00:00
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (svc *ServerService) UpdateNumTribes(ctx context.Context, payload domain.TribesSyncedEventPayload) error {
|
|
|
|
key := payload.ServerKey()
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err := updateParams.SetNumTribes(domain.NullInt{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: payload.NumTribes(),
|
2023-12-30 09:10:03 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
if err := updateParams.SetTribeDataSyncedAt(domain.NullTime{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: time.Now(),
|
2023-12-30 09:10:03 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
2023-12-25 11:04:12 +00:00
|
|
|
}
|
2024-01-01 10:53:59 +00:00
|
|
|
|
|
|
|
func (svc *ServerService) UpdateNumPlayers(ctx context.Context, payload domain.PlayersSyncedEventPayload) error {
|
|
|
|
key := payload.ServerKey()
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err := updateParams.SetNumPlayers(domain.NullInt{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: payload.NumPlayers(),
|
2024-01-01 10:53:59 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
if err := updateParams.SetPlayerDataSyncedAt(domain.NullTime{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: time.Now(),
|
2024-01-01 10:53:59 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
|
|
|
}
|
2024-01-02 10:47:02 +00:00
|
|
|
|
|
|
|
func (svc *ServerService) UpdateNumVillages(ctx context.Context, payload domain.VillagesSyncedEventPayload) error {
|
|
|
|
key := payload.ServerKey()
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err := updateParams.SetNumVillages(domain.NullInt{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: payload.NumVillages(),
|
2024-01-02 10:47:02 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
if err := updateParams.SetNumPlayerVillages(domain.NullInt{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: payload.NumPlayerVillages(),
|
2024-01-02 10:47:02 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
if err := updateParams.SetNumBarbarianVillages(domain.NullInt{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: payload.NumBarbarianVillages(),
|
2024-01-02 10:47:02 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
if err := updateParams.SetNumBonusVillages(domain.NullInt{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: payload.NumBonusVillages(),
|
2024-01-02 10:47:02 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
if err := updateParams.SetVillageDataSyncedAt(domain.NullTime{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: time.Now(),
|
2024-01-02 10:47:02 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
|
|
|
}
|
2024-01-04 10:44:36 +00:00
|
|
|
|
|
|
|
func (svc *ServerService) UpdateEnnoblementDataSyncedAt(
|
|
|
|
ctx context.Context,
|
|
|
|
payload domain.EnnoblementsSyncedEventPayload,
|
|
|
|
) error {
|
|
|
|
key := payload.ServerKey()
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err := updateParams.SetEnnoblementDataSyncedAt(domain.NullTime{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: time.Now(),
|
2024-01-04 10:44:36 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
|
|
|
}
|
2024-01-15 07:00:08 +00:00
|
|
|
|
|
|
|
func (svc *ServerService) UpdateTribeSnapshotsCreatedAt(
|
|
|
|
ctx context.Context,
|
|
|
|
payload domain.SnapshotsCreatedEventPayload,
|
|
|
|
) error {
|
|
|
|
key := payload.ServerKey()
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err := updateParams.SetTribeSnapshotsCreatedAt(domain.NullTime{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: time.Now(),
|
2024-01-15 07:00:08 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
|
|
|
}
|
2024-01-16 06:28:03 +00:00
|
|
|
|
|
|
|
func (svc *ServerService) UpdatePlayerSnapshotsCreatedAt(
|
|
|
|
ctx context.Context,
|
|
|
|
payload domain.SnapshotsCreatedEventPayload,
|
|
|
|
) error {
|
|
|
|
key := payload.ServerKey()
|
|
|
|
|
|
|
|
var updateParams domain.UpdateServerParams
|
|
|
|
if err := updateParams.SetPlayerSnapshotsCreatedAt(domain.NullTime{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: time.Now(),
|
2024-01-16 06:28:03 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return fmt.Errorf("%s: %w", key, err)
|
|
|
|
}
|
|
|
|
|
|
|
|
return svc.repo.Update(ctx, key, updateParams)
|
|
|
|
}
|
2024-02-10 10:53:14 +00:00
|
|
|
|
|
|
|
func (svc *ServerService) GetNormalByVersionCodeAndServerKey(
|
|
|
|
ctx context.Context,
|
|
|
|
versionCode, key string,
|
|
|
|
) (domain.Server, error) {
|
|
|
|
params := domain.NewListServersParams()
|
|
|
|
if err := params.SetVersionCodes([]string{versionCode}); err != nil {
|
|
|
|
return domain.Server{}, err
|
|
|
|
}
|
|
|
|
if err := params.SetKeys([]string{key}); err != nil {
|
|
|
|
return domain.Server{}, err
|
|
|
|
}
|
|
|
|
if err := params.SetSpecial(domain.NullBool{
|
2024-02-28 06:59:10 +00:00
|
|
|
V: false,
|
2024-02-10 10:53:14 +00:00
|
|
|
Valid: true,
|
|
|
|
}); err != nil {
|
|
|
|
return domain.Server{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
res, err := svc.repo.List(ctx, params)
|
|
|
|
if err != nil {
|
|
|
|
return domain.Server{}, err
|
|
|
|
}
|
|
|
|
|
|
|
|
servers := res.Servers()
|
|
|
|
if len(servers) == 0 {
|
|
|
|
return domain.Server{}, domain.ServerNotFoundError{
|
|
|
|
Key: key,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return servers[0], nil
|
|
|
|
}
|