Skip to content

Commit

Permalink
Merge pull request #273 from inada-s/team-shuffle-opt
Browse files Browse the repository at this point in the history
Team shuffle opt
  • Loading branch information
inada-s authored Aug 7, 2023
2 parents ef1ea37 + 2f7a055 commit c3b4e0c
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 36 deletions.
5 changes: 4 additions & 1 deletion gdxsv/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -250,9 +250,12 @@ type DB interface {
// This function is used when a battle starts.
AddBattleRecord(battle *BattleRecord) error

// GetBattleRecordUser load a battle record by battle_code and user_id.
// GetBattleRecordUser loads a battle record by battle_code and user_id.
GetBattleRecordUser(battleCode string, userID string) (*BattleRecord, error)

// GetLastBattleRecords finds BattleRecords for everyone who participated in the last match.
GetLastBattleRecords(userID string) ([]*BattleRecord, error)

// SetReplayURL updates battle_record to set replay_url.
SetReplayURL(battleCode string, url string) error

Expand Down
8 changes: 8 additions & 0 deletions gdxsv/db_sqlite.go
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,14 @@ func (db SQLiteDB) GetBattleRecordUser(battleCode string, userID string) (*Battl
return b, err
}

func (db SQLiteDB) GetLastBattleRecords(userID string) ([]*BattleRecord, error) {
var results []*BattleRecord
err := db.Select(&results, `SELECT * FROM battle_record WHERE battle_code IN (
SELECT battle_code FROM battle_record WHERE user_id == ? ORDER BY ROWID DESC LIMIT 1
)`, userID)
return results, err
}

func (db SQLiteDB) SetReplayURL(battleCode string, url string) error {
_, err := db.Exec(`UPDATE battle_record SET replay_url = ? WHERE battle_code = ?`, url, battleCode)
return err
Expand Down
24 changes: 11 additions & 13 deletions gdxsv/lbs_handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,7 @@ var _ = register(lbsUserDecide, func(p *LbsPeer, m *LbsMessage) {
p.DBUser = *u
p.app.userPeers[p.UserID] = p
p.logger = p.logger.With(zap.String("user_id", p.UserID), zap.String("handle_name", p.Name))
p.logger.Info("LoginUser", zap.Any("platform_info", p.PlatformInfo))
p.SendMessage(NewServerAnswer(m).Writer().WriteString(p.UserID).Msg())
p.SendMessage(NewServerQuestion(lbsAskGameCode))
})
Expand Down Expand Up @@ -762,20 +763,18 @@ var _ = register(lbsWinLose, func(p *LbsPeer, m *LbsMessage) {
})

var _ = register(lbsDeviceData, func(p *LbsPeer, m *LbsMessage) {
r := m.Reader()
data1 := r.Read16()
data2 := r.Read16()
data3 := r.Read16()
data4 := r.Read16()
data5 := r.Read16()
data6 := r.Read16()
data7 := r.Read16()
data8 := r.Read16()
p.logger.Sugar().Info("DeviceData", data1, data2, data3, data4, data5, data6, data7, data8)
// r := m.Reader()
// data1 := r.Read16()
// data2 := r.Read16()
// data3 := r.Read16()
// data4 := r.Read16()
// data5 := r.Read16()
// data6 := r.Read16()
// data7 := r.Read16()
// data8 := r.Read16()
// PS2: 0 0 0 999 1 0 0 0
// DC1: 0 0 0 0 1 0 0 0
// DC2: 0 0 0 0 1 0 0 0

p.SendMessage(NewServerAnswer(m))
})

Expand Down Expand Up @@ -1591,7 +1590,7 @@ var _ = register(lbsExtSyncSharedData, func(p *LbsPeer, m *LbsMessage) {
return
}

p.logger.Info("update mcs status", zap.Any("mcs_status", mcsStatus))
p.logger.Debug("update mcs status", zap.Any("mcs_status", mcsStatus))
p.app.mcsPeers[mcsStatus.PublicAddr] = p
p.mcsStatus = &mcsStatus
sharedData.SyncMcsToLbs(&mcsStatus)
Expand Down Expand Up @@ -1626,7 +1625,6 @@ var _ = register(lbsPlatformInfo, func(p *LbsPeer, m *LbsMessage) {
zap.String("os", p.PlatformInfo["os"]),
zap.String("cpu", p.PlatformInfo["cpu"]),
)
p.logger.Info("PlatformInfo", zap.Any("platform_info", p.PlatformInfo))
}

if p.PlatformInfo["cpu"] == "x86/64" {
Expand Down
41 changes: 38 additions & 3 deletions gdxsv/lbs_lobby.go
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,6 @@ func (l *LbsLobby) Enter(p *LbsPeer) {
// Send game patch for offline testing
if l.LobbySetting.PatchNames != "" {
patchList := l.makePatchList()
logger.Info("patchList", zap.Any("patchList", patchList))
patchBin, err := pb.Marshal(patchList)
if err != nil {
logger.Error("pb.Marshal patch", zap.Error(err))
Expand Down Expand Up @@ -557,6 +556,23 @@ func teamShuffle(seed int64, peers []*LbsPeer) []uint16 {
teams[i], teams[j] = teams[j], teams[i]
})

// Special case - Shuffle twice if the team is same of the previous match
sameTeam := false
for i, p := range peers {
for j, q := range peers {
if i != j && teams[i] == teams[j] {
if getLastTeamUserID(p.UserID) == q.UserID && getLastTeamUserID(q.UserID) == p.UserID {
sameTeam = true
}
}
}
}
if sameTeam {
r.Shuffle(len(teams), func(i, j int) {
teams[i], teams[j] = teams[j], teams[i]
})
}

// Special case - Region friendly team
// Pair with player in the same region group when the peer regions are like [A, A, B, B].
var groups []string
Expand Down Expand Up @@ -586,6 +602,27 @@ func teamShuffle(seed int64, peers []*LbsPeer) []uint16 {
return teams[:len(peers)]
}

func getLastTeamUserID(userID string) string {
records, err := getDB().GetLastBattleRecords(userID)
if err != nil {
return ""
}

userTeam := TeamNone
for _, r := range records {
if r.UserID == userID {
userTeam = r.Team
}
}
for _, r := range records {
if r.Team == userTeam && r.UserID != userID {
return r.UserID
}
}

return ""
}

func (l *LbsLobby) pickLobbyBattleParticipants() []*LbsPeer {
peers := l.getNextLobbyBattleParticipants()

Expand Down Expand Up @@ -813,7 +850,6 @@ func (l *LbsLobby) checkLobbyBattleStart(force bool) {
}

patchList := l.makePatchList()
logger.Info("patchList", zap.Any("patchList", patchList))
patchBin, err := pb.Marshal(patchList)
if err != nil {
logger.Error("pb.Marshal patch", zap.Error(err))
Expand All @@ -829,7 +865,6 @@ func (l *LbsLobby) checkLobbyBattleStart(force bool) {
logger.Error("makeP2PMatchingMsg failed", zap.Error(err))
return
}
logger.Info("p2pMatchingMsg", zap.Any("p2pMatchingMsg", p2pMatchingMsgs[0]))
}

sharedData.ShareMcsGame(&McsGame{
Expand Down
127 changes: 109 additions & 18 deletions gdxsv/lbs_lobby_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,24 @@ import (
)

func Test_teamShuffle(t *testing.T) {
makePeer := func(userID string) *LbsPeer {
return &LbsPeer{
DBUser: DBUser{
UserID: userID,
},
}
}

makePeerWithRegion := func(userID string, region string) *LbsPeer {
p := makePeer(userID)
p.bestRegion = region
return p
}

type args struct {
seed int64
peers []*LbsPeer
seed int64
peers []*LbsPeer
lastTeamUserID []string
}
tests := []struct {
name string
Expand All @@ -17,16 +32,40 @@ func Test_teamShuffle(t *testing.T) {
{
name: "random shuffle seed 1",
args: args{
seed: 1,
peers: []*LbsPeer{&LbsPeer{}, &LbsPeer{}, &LbsPeer{}, &LbsPeer{}},
seed: 1,
peers: []*LbsPeer{
makePeer("1"),
makePeer("2"),
makePeer("3"),
makePeer("4"),
},
},
want: []uint16{1, 1, 2, 2},
},
{
name: "random shuffle seed 2",
args: args{
seed: 2,
peers: []*LbsPeer{&LbsPeer{}, &LbsPeer{}, &LbsPeer{}, &LbsPeer{}},
seed: 2,
peers: []*LbsPeer{
makePeer("1"),
makePeer("2"),
makePeer("3"),
makePeer("4"),
},
},
want: []uint16{1, 2, 2, 1},
},
{
name: "random shuffle avoid same team",
args: args{
seed: 1,
peers: []*LbsPeer{
makePeer("1"),
makePeer("2"),
makePeer("3"),
makePeer("4"),
},
lastTeamUserID: []string{"2", "1", "", ""},
},
want: []uint16{1, 2, 2, 1},
},
Expand All @@ -35,8 +74,11 @@ func Test_teamShuffle(t *testing.T) {
args: args{
seed: 1,
peers: []*LbsPeer{
&LbsPeer{bestRegion: "us-east1"}, &LbsPeer{bestRegion: "us-east1"},
&LbsPeer{bestRegion: "us-west1"}, &LbsPeer{bestRegion: "us-west1"}},
makePeerWithRegion("1", "us-east1"),
makePeerWithRegion("2", "us-east1"),
makePeerWithRegion("3", "us-west1"),
makePeerWithRegion("4", "us-west1"),
},
},
want: []uint16{1, 1, 2, 2},
},
Expand All @@ -45,8 +87,11 @@ func Test_teamShuffle(t *testing.T) {
args: args{
seed: 2,
peers: []*LbsPeer{
&LbsPeer{bestRegion: "us-east1"}, &LbsPeer{bestRegion: "us-east1"},
&LbsPeer{bestRegion: "us-west1"}, &LbsPeer{bestRegion: "us-west1"}},
makePeerWithRegion("1", "us-east1"),
makePeerWithRegion("2", "us-east1"),
makePeerWithRegion("3", "us-west1"),
makePeerWithRegion("4", "us-west1"),
},
},
want: []uint16{2, 2, 1, 1},
},
Expand All @@ -55,38 +100,84 @@ func Test_teamShuffle(t *testing.T) {
args: args{
seed: 2,
peers: []*LbsPeer{
&LbsPeer{}, &LbsPeer{bestRegion: "us-east1"},
&LbsPeer{bestRegion: "us-west1"}, &LbsPeer{bestRegion: "us-west1"}},
makePeerWithRegion("1", "asia-east1"),
makePeerWithRegion("2", "us-east1"),
makePeerWithRegion("3", "us-west1"),
makePeerWithRegion("4", "us-west1"),
},
},
want: []uint16{1, 2, 2, 1},
},
{
name: "two players",
args: args{
seed: 9,
peers: []*LbsPeer{&LbsPeer{}, &LbsPeer{}},
seed: 9,
peers: []*LbsPeer{
makePeer("1"),
makePeer("2"),
},
},
want: []uint16{2, 1},
},
{
name: "three players",
args: args{
seed: 2,
peers: []*LbsPeer{&LbsPeer{}, &LbsPeer{}, &LbsPeer{}},
seed: 2,
peers: []*LbsPeer{
makePeer("1"),
makePeer("2"),
makePeer("3"),
},
},
want: []uint16{1, 2, 2},
},
{
name: "more than five players is not supported",
args: args{
seed: 1,
peers: []*LbsPeer{&LbsPeer{}, &LbsPeer{}, &LbsPeer{}, &LbsPeer{}, &LbsPeer{}},
seed: 1,
peers: []*LbsPeer{
makePeer("1"),
makePeer("2"),
makePeer("3"),
makePeer("4"),
makePeer("5"),
},
},
want: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.args.lastTeamUserID != nil {
used := map[string]bool{}
for i, peer := range tt.args.peers {
if used[peer.UserID] {
continue
}

team := TeamRenpo
if 2 <= len(used) {
team = TeamZeon
}

used[peer.UserID] = true
mustInsertBattleRecord(BattleRecord{
BattleCode: "123456789",
UserID: peer.UserID,
Team: team,
})

teamUserID := tt.args.lastTeamUserID[i]
if teamUserID != "" {
used[teamUserID] = true
mustInsertBattleRecord(BattleRecord{
BattleCode: "123456789",
UserID: teamUserID,
Team: team,
})
}
}
}
teams := teamShuffle(tt.args.seed, tt.args.peers)
assertEq(t, tt.want, teams)
})
Expand Down
1 change: 1 addition & 0 deletions gdxsv/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,7 @@ func getDB() DB {
}

func prepareDB() {
logger.Sugar().Info("using database %s", conf.DBName)
conn, err := sqlx.Open("sqlite3", conf.DBName)
if err != nil {
logger.Fatal("failed to open database", zap.Error(err))
Expand Down
2 changes: 1 addition & 1 deletion gdxsv/mcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ func (mcs *Mcs) DialAndSyncWithLbs(lobbyAddr string, battlePublicAddr string, ba
continue
}

logger.Info("lbs_status updated", zap.Any("lbs_status", &lbsStatus))
logger.Debug("lbs_status updated", zap.Any("lbs_status", &lbsStatus))

sharedData.SyncLbsToMcs(&lbsStatus)
}
Expand Down

0 comments on commit c3b4e0c

Please sign in to comment.