Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 53 additions & 42 deletions apps/matchmakingserver/service/battleground_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -826,53 +826,64 @@ func (s *battleGroundService) PlayerBecomeOffline(ctx context.Context, playerGUI
}

func (s *battleGroundService) ProcessExpiredBattlegroundInvites(ctx context.Context) {
ticker := time.NewTicker(time.Second)
defer ticker.Stop()

for {
select {
case <-time.After(time.Second):
bgs, err := s.battlegroundsRepo.GetAllActiveBattlegrounds(ctx)
if err != nil {
log.Err(err).Msg("failed to get all active battlegrounds")
break
}
for _, bg := range bgs {
for _, invites := range bg.InvitedPlayersPerTeam {
for _, invite := range invites {
if time.Since(invite.InvitedTime) > time.Minute {
err = s.battlegroundsRepo.UpdateBattleground(
ctx,
bg.InstanceID,
repo.RealmWithBattlegroupKey{RealmID: bg.RealmID, BattlegroupID: bg.BattleGroupID},
func(b *battleground.Battleground) error {
b.RemovePlayerFromInvite(uint64(invite.GUID.LowGUID), uint32(invite.GUID.RealmID))
return nil
},
)
if err != nil {
log.Err(err).Msg("failed to remove invite from Battleground")
continue
}

err = s.RemovePlayerFromQueue(ctx, uint64(invite.GUID.LowGUID), uint32(invite.GUID.RealmID), bg.QueueTypeID)
if err != nil {
log.Err(err).Msg("failed to remove invited player from queue")
continue
}

slot := uint8(0) // TODO: provide real slot
err = s.eventsProducer.InviteExpired(&events.MatchmakingEventPlayersInviteExpiredPayload{
RealmID: uint32(invite.GUID.RealmID),
PlayersGUID: []guid.LowType{invite.GUID.LowGUID},
QueueSlotByPlayer: map[guid.LowType]uint8{invite.GUID.LowGUID: slot},
})
if err != nil {
log.Err(err).Msg("Failed to add invited player to queue")
}
}
case <-ticker.C:
s.processExpiredBattlegroundInvitesTick(ctx)
case <-ctx.Done():
return
}
}
}

func (s *battleGroundService) processExpiredBattlegroundInvitesTick(ctx context.Context) {
bgs, err := s.battlegroundsRepo.GetAllActiveBattlegrounds(ctx)
if err != nil {
log.Err(err).Msg("failed to get all active battlegrounds")
return
}
for _, bg := range bgs {
for _, invites := range bg.InvitedPlayersPerTeam {
for _, invite := range invites {
if time.Since(invite.InvitedTime) > time.Minute {
err = s.battlegroundsRepo.UpdateBattleground(
ctx,
bg.InstanceID,
repo.RealmWithBattlegroupKey{RealmID: bg.RealmID, BattlegroupID: bg.BattleGroupID},
func(b *battleground.Battleground) error {
b.RemovePlayerFromInvite(uint64(invite.GUID.LowGUID), uint32(invite.GUID.RealmID))
return nil
},
)
if err != nil {
log.Err(err).Msg("failed to remove invite from Battleground")
continue
}

// Unlink only this battleground: RemovePlayerFromQueue
// removed the player from every battleground of the same
// queue type, including one where they are an active
// participant of a running match.
s.removeBattlegroundLinkForPlayer(BattlegroundKey{
RealmID: bg.RealmID,
InstanceID: bg.InstanceID,
BattlegroupID: bg.BattleGroupID,
}, uint64(invite.GUID.LowGUID), uint32(invite.GUID.RealmID))

slot := uint8(0) // TODO: provide real slot
err = s.eventsProducer.InviteExpired(&events.MatchmakingEventPlayersInviteExpiredPayload{
RealmID: uint32(invite.GUID.RealmID),
PlayersGUID: []guid.LowType{invite.GUID.LowGUID},
QueueSlotByPlayer: map[guid.LowType]uint8{invite.GUID.LowGUID: slot},
})
if err != nil {
log.Err(err).Msg("Failed to add invited player to queue")
}
}
}
case <-ctx.Done():
return
}
}
}
Expand Down
61 changes: 61 additions & 0 deletions apps/matchmakingserver/service/battleground_service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"sync"
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/walkline/ToCloud9/apps/matchmakingserver/battleground"
"github.com/walkline/ToCloud9/apps/matchmakingserver/repo"
"github.com/walkline/ToCloud9/shared/events"
"github.com/walkline/ToCloud9/shared/wow/guid"
)

Expand Down Expand Up @@ -205,3 +207,62 @@ func TestBattlegroundStatusChangedEndedPurgesInvitedLinks(t *testing.T) {
assert.Empty(t, s.GetQueueOrBattlegroundLinkForPlayer(QueuesByRealmAndPlayerKey{activePlayer}))
assert.Empty(t, s.GetQueueOrBattlegroundLinkForPlayer(QueuesByRealmAndPlayerKey{invitedPlayer}))
}

type noopMatchmakingProducer struct{}

func (noopMatchmakingProducer) JoinedQueue(*events.MatchmakingEventPlayersQueuedPayload) error {
return nil
}
func (noopMatchmakingProducer) InvitedToBGOrArena(*events.MatchmakingEventPlayersInvitedPayload) error {
return nil
}
func (noopMatchmakingProducer) InviteExpired(*events.MatchmakingEventPlayersInviteExpiredPayload) error {
return nil
}

func TestExpiredInviteOnlyUnlinksItsBattleground(t *testing.T) {
bgRepo := repo.NewBattlegroundInMemRepo()
player := guid.PlayerUnwrapped{RealmID: 1, LowGUID: 7}

expiredBG := &battleground.Battleground{
InstanceID: 42,
RealmID: 1,
QueueTypeID: battleground.QueueTypeIDWarsongGulch,
Status: battleground.StatusWaitJoin,
}
expiredBG.InvitedPlayersPerTeam[battleground.TeamAlliance] = []battleground.InvitedPlayer{
{GUID: player, InvitedTime: time.Now().Add(-2 * time.Minute)},
}
activeBG := &battleground.Battleground{
InstanceID: 43,
RealmID: 1,
QueueTypeID: battleground.QueueTypeIDWarsongGulch,
Status: battleground.StatusInProgress,
}
activeBG.ActivePlayersPerTeam[battleground.TeamAlliance] = []guid.PlayerUnwrapped{player}
assert.NoError(t, bgRepo.SaveBattleground(context.Background(), expiredBG))
assert.NoError(t, bgRepo.SaveBattleground(context.Background(), activeBG))

s := &battleGroundService{
playersQueueOrBattleground: make(map[QueuesByRealmAndPlayerKey][]QueueOrBattlegroundLink),
battlegroundsRepo: bgRepo,
eventsProducer: noopMatchmakingProducer{},
}
expiredKey := BattlegroundKey{RealmID: 1, InstanceID: 42}
activeKey := BattlegroundKey{RealmID: 1, InstanceID: 43}
s.playersQueueOrBattleground[QueuesByRealmAndPlayerKey{player}] = []QueueOrBattlegroundLink{
{BattlegroundKey: &expiredKey},
{BattlegroundKey: &activeKey},
}

s.processExpiredBattlegroundInvitesTick(context.Background())

links := s.GetQueueOrBattlegroundLinkForPlayer(QueuesByRealmAndPlayerKey{player})
assert.Len(t, links, 1, "the active battleground link must survive")
assert.Equal(t, activeKey, *links[0].BattlegroundKey)

// The invite itself is gone from the expired battleground.
got, err := bgRepo.GetBattlegroundByInstanceID(context.Background(), 42, repo.RealmWithBattlegroupKey{RealmID: 1})
assert.NoError(t, err)
assert.Empty(t, got.InvitedPlayersPerTeam[battleground.TeamAlliance])
}
Loading