116 lines
2.2 KiB
Go
116 lines
2.2 KiB
Go
package matchpool
|
|
|
|
import (
|
|
"go_dreamfactory/pb"
|
|
"sync"
|
|
"sync/atomic"
|
|
|
|
anypb "google.golang.org/protobuf/types/known/anypb"
|
|
)
|
|
|
|
type MatchPlayer struct {
|
|
Uid string
|
|
Dan int32
|
|
Time int32
|
|
Data *anypb.Any
|
|
}
|
|
|
|
//基础匹配池
|
|
type MPool struct {
|
|
module *MatchPool
|
|
Name string
|
|
MatchNum int32
|
|
Timeout int32
|
|
lock sync.RWMutex
|
|
State int32
|
|
Players map[string]*MatchPlayer
|
|
}
|
|
|
|
func (this *MPool) join(req *pb.JoinMatchPoolReq) {
|
|
this.lock.Lock()
|
|
player := &MatchPlayer{
|
|
Uid: req.Uid,
|
|
Time: 0,
|
|
Data: req.Data,
|
|
}
|
|
this.Players[req.Uid] = player
|
|
this.lock.Unlock()
|
|
|
|
}
|
|
|
|
func (this *MPool) cancel(uid string) {
|
|
this.lock.Lock()
|
|
delete(this.Players, uid)
|
|
this.lock.Unlock()
|
|
}
|
|
|
|
func (this *MPool) match(cd int32) {
|
|
if !atomic.CompareAndSwapInt32(&this.State, 1, 2) { //正在执行,就不要在进来了
|
|
return
|
|
}
|
|
defer func() {
|
|
atomic.StoreInt32(&this.State, 1) //执行完毕释放
|
|
}()
|
|
var (
|
|
ok bool
|
|
playerNum int32
|
|
danplayers map[int32][]*MatchPlayer = make(map[int32][]*MatchPlayer)
|
|
group []*MatchPlayer
|
|
)
|
|
this.lock.Lock()
|
|
for _, v := range this.Players {
|
|
v.Time += cd
|
|
playerNum += 1
|
|
}
|
|
for _, v := range this.Players {
|
|
if _, ok = danplayers[v.Dan]; !ok {
|
|
danplayers[v.Dan] = make([]*MatchPlayer, 0)
|
|
}
|
|
danplayers[v.Dan] = append(danplayers[v.Dan], v)
|
|
}
|
|
this.lock.Unlock()
|
|
|
|
if playerNum == 0 {
|
|
return
|
|
}
|
|
|
|
group = make([]*MatchPlayer, 0)
|
|
locp:
|
|
for _, players := range danplayers {
|
|
if len(players) >= int(this.MatchNum) {
|
|
group = append(group, players[0:this.MatchNum]...)
|
|
break locp
|
|
} else {
|
|
for _, player := range players {
|
|
if player.Time >= this.Timeout {
|
|
group = append(group, players...)
|
|
break locp
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if len(group) > 0 {
|
|
this.matchSucc(group)
|
|
}
|
|
}
|
|
|
|
func (this *MPool) matchSucc(group []*MatchPlayer) {
|
|
var (
|
|
Players map[string]*anypb.Any = make(map[string]*anypb.Any)
|
|
)
|
|
this.lock.Lock()
|
|
for _, v := range group {
|
|
delete(this.Players, v.Uid)
|
|
}
|
|
this.lock.Unlock()
|
|
for _, v := range group {
|
|
Players[v.Uid] = v.Data
|
|
}
|
|
|
|
go this.module.MatchNotice(&pb.SuccMatchNoticeReq{
|
|
Poolname: this.Name,
|
|
Players: Players,
|
|
Missnum: this.MatchNum - int32(len(group)),
|
|
})
|
|
}
|