522 lines
12 KiB
Go
522 lines
12 KiB
Go
package team
|
|
|
|
import (
|
|
"q5"
|
|
"f5"
|
|
"cs"
|
|
"mt"
|
|
"main/common"
|
|
"main/constant"
|
|
|
|
"sort"
|
|
"strings"
|
|
"github.com/golang/protobuf/proto"
|
|
)
|
|
|
|
type robot struct {
|
|
meta *mt.Robot
|
|
specSkill int32
|
|
}
|
|
|
|
type team struct {
|
|
cs.MsgHandlerImpl
|
|
teamUuid string
|
|
nextTeamUuid string
|
|
copyIdx int32
|
|
zoneId int32
|
|
nodeId int32
|
|
mapInfo* common.MapInfoRsp
|
|
sortIdx int32
|
|
owner common.Player
|
|
state int32
|
|
startTime int64
|
|
stateNotifyMsg *cs.SMTeamStateNotify
|
|
memberIdHash map[string]common.Player
|
|
robotList []*robot
|
|
matchOk *team
|
|
matchTick int64
|
|
}
|
|
|
|
func (this* robot) GetAccountId() string {
|
|
return "6517_2006_" + q5.ToString(this.meta.GetId())
|
|
}
|
|
|
|
func (this* robot) FillMFTeamMember(member_pb *cs.MFTeamMember) {
|
|
member_pb.AccountId = proto.String(this.GetAccountId())
|
|
member_pb.Name = proto.String(this.meta.GetName())
|
|
//member_pb.Id = proto.Int32(this.sortIdx)
|
|
member_pb.IsLeader = proto.Int32(0)
|
|
member_pb.SpecSkill = proto.Int32(this.specSkill)
|
|
{
|
|
member_pb.Hero = &cs.MFHero{}
|
|
member_pb.Hero.HeroId = proto.Int32(this.meta.GetHeroId())
|
|
member_pb.Hero.Quality = proto.Int32(0)
|
|
}
|
|
member_pb.State = proto.Int32(0)
|
|
member_pb.Online = proto.Int32(1)
|
|
member_pb.Permission = proto.Int32(0)
|
|
member_pb.IsReady = proto.Int32(1)
|
|
}
|
|
|
|
func (this *team) init(copyIdx int32, zoneId int32, nodeId int32,
|
|
teamUuid string, owner common.Player, mapInfo* common.MapInfoRsp) {
|
|
this.sortIdx++
|
|
this.teamUuid = teamUuid
|
|
this.copyIdx = copyIdx
|
|
this.zoneId = zoneId
|
|
this.nodeId = nodeId
|
|
this.mapInfo = mapInfo
|
|
this.owner = owner
|
|
this.owner.SetPermission(1)
|
|
this.stateNotifyMsg.JoinMsg.TeamUuid = proto.String(this.teamUuid)
|
|
owner.SetTeam(this)
|
|
owner.SetSortIdx(this.sortIdx)
|
|
this.memberIdHash[owner.GetAccountId()] = owner
|
|
}
|
|
|
|
func (this *team) GetZoneId() int32 {
|
|
return this.zoneId
|
|
}
|
|
|
|
func (this *team) GetNodeId() int32 {
|
|
return this.nodeId
|
|
}
|
|
|
|
func (this *team) GetZnKey() int64 {
|
|
return q5.MkInt64(this.GetZoneId(), this.GetNodeId())
|
|
}
|
|
|
|
func (this *team) GetTeamUuid() string {
|
|
return this.teamUuid
|
|
}
|
|
|
|
func (this *team) CanJoin(accountId string) bool {
|
|
if this.IsCopy() {
|
|
if !this.isFull() {
|
|
return true
|
|
} else if this.GetMemberByAccountId(accountId) != nil {
|
|
return true
|
|
}
|
|
} else {
|
|
return !this.isFull()
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (this *team) GetMemberByAccountId(accountId string) common.Player {
|
|
hum, ok := this.memberIdHash[accountId]
|
|
if ok {
|
|
return hum
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (this *team) OnPlayerOffline(hum common.Player) {
|
|
|
|
}
|
|
|
|
func (this *team) OnPlayerOnline(hum common.Player) {
|
|
|
|
}
|
|
|
|
func (this *team) Join(hum common.Player) bool {
|
|
this.sortIdx++
|
|
hum.SetTeam(this)
|
|
hum.SetSortIdx(this.sortIdx)
|
|
this.memberIdHash[hum.GetAccountId()] = hum
|
|
this.rearrangementSortIdx()
|
|
return true
|
|
}
|
|
|
|
func (this *team) IsLeader(hum common.Player) bool {
|
|
return hum == this.owner
|
|
}
|
|
|
|
func (this *team) isFull() bool {
|
|
return len(this.memberIdHash) >= 4
|
|
}
|
|
|
|
func (this *team) IsCopy() bool {
|
|
return this.copyIdx > 0
|
|
}
|
|
|
|
func (this *team) GetCopyIdx() int32 {
|
|
return this.copyIdx
|
|
}
|
|
|
|
func (this *team) Started() bool {
|
|
return this.state == constant.TEAM_STATE_STARTED
|
|
}
|
|
|
|
func (this *team) Matching() bool {
|
|
return this.state == constant.TEAM_STATE_MATCHING
|
|
}
|
|
|
|
func (this *team) IsLock() bool {
|
|
return this.Started() || this.Matching()
|
|
}
|
|
|
|
func (this *team) setMatchOk(targetM *team) {
|
|
this.matchOk = targetM
|
|
this.matchTick = q5.GetTickCount()
|
|
}
|
|
|
|
func (this *team) isMainTeam() bool {
|
|
return this.getMainTeam() == this
|
|
}
|
|
|
|
func (this *team) getMainTeam() *team {
|
|
if this.matchOk == nil {
|
|
return this
|
|
}
|
|
if this.GetTeamUuid() < this.matchOk.GetTeamUuid() {
|
|
return this
|
|
} else {
|
|
return this.matchOk
|
|
}
|
|
}
|
|
|
|
func (this *team) onMatchOk(startTime int64) {
|
|
this.doStartGame(startTime)
|
|
}
|
|
|
|
func (this *team) CanStartGame(hum common.Player) bool {
|
|
if !this.IsLock() {
|
|
if this.GetMemberNum() > 0 {
|
|
allReady := true
|
|
for _, m := range this.memberIdHash {
|
|
if m != this.owner && !m.IsReady() {
|
|
allReady = false
|
|
break
|
|
}
|
|
}
|
|
return allReady
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (this *team) StartGame() {
|
|
if !this.IsLock() && this.CanStartGame(this.owner) {
|
|
if this.IsMobaMode() {
|
|
this.state = constant.TEAM_STATE_MATCHING
|
|
this.stateNotifyMsg.State = proto.Int32(this.state)
|
|
_matchMgr.addMatch(this)
|
|
this.SendStateNotify()
|
|
} else {
|
|
this.doStartGame(f5.GetApp().GetNowSeconds())
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *team) doStartGame(startTime int64) {
|
|
this.state = constant.TEAM_STATE_STARTED
|
|
this.startTime = startTime
|
|
this.stateNotifyMsg.State = proto.Int32(this.state)
|
|
this.genStartGameInfo()
|
|
this.SendStateNotify()
|
|
count := 1
|
|
f5.GetTimer().SetInterval(1000, func(e int32, args *q5.Args) {
|
|
if e == q5.TIMER_EXEC_EVENT {
|
|
this.SendStateNotify()
|
|
count++
|
|
if count > 10 {
|
|
f5.GetTimer().DeleteRunningTimer()
|
|
_teamMgr.removeTeam(this.GetTeamUuid())
|
|
}
|
|
}
|
|
})
|
|
}
|
|
|
|
func (this *team) GetMemberNum() int32 {
|
|
return int32(len(this.memberIdHash))
|
|
}
|
|
|
|
func (this *team) chooseNextLeader() {
|
|
var nextLeader common.Player
|
|
for _, m := range this.memberIdHash {
|
|
if nextLeader == nil {
|
|
nextLeader = m
|
|
} else if m.GetSortIdx() < nextLeader.GetSortIdx() {
|
|
nextLeader = m
|
|
}
|
|
}
|
|
this.owner = nextLeader
|
|
this.owner.SetPermission(1)
|
|
}
|
|
|
|
func (this *team) Leave(hum common.Player) {
|
|
if !this.IsLock() {
|
|
if this.IsLeader(hum) {
|
|
delete(this.memberIdHash, hum.GetAccountId())
|
|
if this.GetMemberNum() > 0 {
|
|
this.chooseNextLeader()
|
|
}
|
|
} else {
|
|
delete(this.memberIdHash, hum.GetAccountId())
|
|
}
|
|
if this.GetMemberNum() < 0 {
|
|
this.Disband()
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *team) Disband() {
|
|
if !this.IsLock() {
|
|
if this.GetMemberNum() < 0 {
|
|
|
|
} else {
|
|
notifyMsg := &cs.SMTeamDisbandNotify{}
|
|
this.broadcastMsg(notifyMsg)
|
|
}
|
|
_teamMgr.removeTeam(this.GetTeamUuid())
|
|
}
|
|
}
|
|
|
|
func (this *team) KickOut(hum common.Player, targetId string) {
|
|
if !this.IsLock() {
|
|
if this.IsLeader(hum) {
|
|
target := this.GetMemberByAccountId(targetId)
|
|
if target != nil && target != hum {
|
|
notifyMsg := &cs.SMTeamKickoutNotify{}
|
|
notifyMsg.AccountId = proto.String(target.GetAccountId())
|
|
target.SendMsg(notifyMsg)
|
|
delete(this.memberIdHash, target.GetAccountId())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *team) HandoverLeader(hum common.Player, targetId string) {
|
|
if !this.IsLock() {
|
|
if this.IsLeader(hum) {
|
|
target := this.GetMemberByAccountId(targetId)
|
|
if target != nil && target != hum {
|
|
this.owner = target
|
|
this.owner.SetPermission(1)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *team) CancelMatch() {
|
|
if this.Matching() {
|
|
_matchMgr.cancelMatch(this)
|
|
this.state = constant.TEAM_STATE_INIT
|
|
this.stateNotifyMsg.State = proto.Int32(this.state)
|
|
this.SendStateNotify()
|
|
}
|
|
}
|
|
|
|
func (this *team) SetMapInfo(mapInfo *common.MapInfoRsp) {
|
|
if !this.IsLock() {
|
|
this.mapInfo = mapInfo
|
|
}
|
|
}
|
|
|
|
func (this* team) IsMobaMode() bool {
|
|
return this.mapInfo.IsMoba != 0
|
|
}
|
|
|
|
func (this *team) rearrangementSortIdx() {
|
|
members := []common.Player{}
|
|
q5.NewSlice(&members, 0, 4)
|
|
for _, m := range this.memberIdHash {
|
|
q5.AppendSlice(&members, m)
|
|
}
|
|
sort.Slice(members, func(i, j int) bool {
|
|
return members[i].GetSortIdx() < members[j].GetSortIdx()
|
|
})
|
|
idx := int32(0)
|
|
for _, m := range members {
|
|
idx++
|
|
m.SetSortIdx(idx)
|
|
}
|
|
}
|
|
|
|
func (this *team) genStartGameInfo() {
|
|
startInfo := struct {
|
|
ZoneId int32 `json:"zone_id"`
|
|
NodeId int32 `json:"node_id"`
|
|
MapId int32 `json:"map_id"`
|
|
RoomUuid string `json:"room_uuid"`
|
|
StartTime int32 `json:"start_time"`
|
|
TeamList []struct {
|
|
TeamUuid string `json:"team_uuid"`
|
|
Members []struct {
|
|
AccountId string `json:"account_id"`
|
|
SpecSkill int32 `json:"spec_skill"`
|
|
HeroUniId string `json:"hero_uniid"`
|
|
IsAndroid int32 `json:"is_android"`
|
|
} `json:"members"`
|
|
} `json:"team_list"`
|
|
ObList []struct {
|
|
AccountId string `json:"account_id"`
|
|
} `json:"ob_list"`
|
|
} {
|
|
ZoneId: this.GetZoneId(),
|
|
NodeId: this.GetNodeId(),
|
|
MapId: this.mapInfo.MapId,
|
|
RoomUuid: q5.ToString(this.getMainTeam().GetTeamUuid()),
|
|
StartTime: int32(this.startTime),
|
|
}
|
|
this.stateNotifyMsg.JoinMsg.TeamUuid = proto.String(this.getMainTeam().GetTeamUuid())
|
|
q5.NewSlice(&this.stateNotifyMsg.TeamList, 0, 10)
|
|
{
|
|
q5.NewSlice(&startInfo.TeamList, 0, 10)
|
|
teamList := []*team{}
|
|
q5.NewSlice(&teamList, 0, 10)
|
|
if this.isMainTeam() {
|
|
{
|
|
ele := q5.NewSliceElement(&teamList)
|
|
*ele = this
|
|
}
|
|
{
|
|
if this.matchOk != nil {
|
|
ele := q5.NewSliceElement(&teamList)
|
|
*ele = this.matchOk
|
|
}
|
|
}
|
|
} else {
|
|
{
|
|
if this.matchOk != nil {
|
|
ele := q5.NewSliceElement(&teamList)
|
|
*ele = this.matchOk
|
|
}
|
|
}
|
|
{
|
|
ele := q5.NewSliceElement(&teamList)
|
|
*ele = this
|
|
}
|
|
}
|
|
for _, t := range teamList {
|
|
{
|
|
ele := q5.NewSliceElement(&startInfo.TeamList)
|
|
ele.TeamUuid = t.GetTeamUuid()
|
|
for _, m := range t.memberIdHash {
|
|
ele2 := q5.NewSliceElement(&ele.Members)
|
|
ele2.AccountId = m.GetAccountId()
|
|
ele2.SpecSkill = m.GetSpecSkill()
|
|
ele2.HeroUniId = m.GetHeroUniid()
|
|
}
|
|
if this.IsMobaMode() {
|
|
robotIdx := 0
|
|
for i := len(ele.Members); i <= 4; i++ {
|
|
ele2 := q5.NewSliceElement(&ele.Members)
|
|
robot := t.robotList[robotIdx]
|
|
robotIdx++
|
|
ele2.AccountId = robot.GetAccountId()
|
|
ele2.SpecSkill = robot.specSkill
|
|
ele2.HeroUniId = ""
|
|
ele2.IsAndroid = 1
|
|
}
|
|
}
|
|
}
|
|
{
|
|
ele := *q5.NewSliceElement(&this.stateNotifyMsg.TeamList)
|
|
ele.TeamUuid = proto.String(t.GetTeamUuid())
|
|
for _, m := range t.memberIdHash {
|
|
m_pb := q5.NewSliceElement(&ele.Members)
|
|
m.FillMFTeamMember(*m_pb)
|
|
}
|
|
if this.IsMobaMode() {
|
|
robotIdx := 0
|
|
for i := len(ele.Members); i <= 4; i++ {
|
|
robot := t.robotList[robotIdx]
|
|
robotIdx++
|
|
m_pb := q5.NewSliceElement(&ele.Members)
|
|
robot.FillMFTeamMember(*m_pb)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
sign := q5.Md5Str(q5.EncodeJson(&startInfo) + "520d8eAbB(8cf1^#$^&!@d833a42c820432PDAFE^^)")
|
|
payload := sign + ":" + "normal_room|" + q5.EncodeJson(&startInfo)
|
|
this.stateNotifyMsg.JoinMsg.Payload = proto.String(payload)
|
|
this.genNextCopyTeam()
|
|
this.stateNotifyMsg.NextTeamUuid = proto.String(this.nextTeamUuid)
|
|
}
|
|
|
|
func (this *team) genNextCopyTeam() {
|
|
nextCopyIdx := this.copyIdx + 1
|
|
oldId := q5.ToString(this.nodeId) + "_" +
|
|
q5.ToString(this.zoneId) + "_" +
|
|
q5.ToString(this.copyIdx) + "_";
|
|
newId := q5.ToString(this.nodeId) + "_" +
|
|
q5.ToString(this.zoneId) + "_" +
|
|
q5.ToString(nextCopyIdx) + "_";
|
|
this.nextTeamUuid = strings.Replace(this.GetTeamUuid(), oldId, newId, 1)
|
|
if this.nextTeamUuid == this.GetTeamUuid() {
|
|
panic("genNextCopyTeam error1")
|
|
return
|
|
}
|
|
if _teamMgr.GetTeamByUuid(this.nextTeamUuid) != nil {
|
|
panic("genNextCopyTeam error2")
|
|
return
|
|
}
|
|
nextMapInfo := &common.MapInfoRsp{}
|
|
*nextMapInfo = *this.mapInfo
|
|
nextTeam := newTeam()
|
|
nextTeam.init(nextCopyIdx, this.zoneId, this.nodeId,
|
|
this.nextTeamUuid, this.owner.GenNextCopy(), nextMapInfo)
|
|
for _, m := range this.memberIdHash {
|
|
if m != this.owner {
|
|
nextTeam.Join(m.GenNextCopy())
|
|
}
|
|
}
|
|
_teamMgr.addTeam(nextTeam)
|
|
}
|
|
|
|
func (this *team) broadcastMsg(msg proto.Message) {
|
|
for _, m := range this.memberIdHash {
|
|
m.SendMsg(msg)
|
|
}
|
|
}
|
|
|
|
func (this *team) SendUpdateNotify() {
|
|
notifyMsg := &cs.SMTeamUpdateNotify{}
|
|
notifyMsg.TeamInfo = &cs.MFTeam{}
|
|
notifyMsg.TeamInfo.TeamUuid = proto.String(this.teamUuid)
|
|
notifyMsg.TeamInfo.MapId = proto.Int32(this.mapInfo.MapId)
|
|
q5.NewSlice(¬ifyMsg.TeamInfo.Members, 0, 1)
|
|
for _, m := range this.memberIdHash {
|
|
m_pb := &cs.MFTeamMember{}
|
|
q5.AppendSlice(¬ifyMsg.TeamInfo.Members, m_pb)
|
|
m.FillMFTeamMember(m_pb)
|
|
}
|
|
this.broadcastMsg(notifyMsg)
|
|
}
|
|
|
|
func (this *team) SendStateNotify() {
|
|
this.broadcastMsg(this.stateNotifyMsg)
|
|
}
|
|
|
|
func (this *team) canMatch(targetT *team) bool {
|
|
if this == targetT {
|
|
return false
|
|
}
|
|
if this.mapInfo.MapId != targetT.mapInfo.MapId {
|
|
return false
|
|
}
|
|
if this.GetMemberNum() <= 0 || targetT.GetMemberNum() <= 0 {
|
|
return false
|
|
}
|
|
for _, m := range this.memberIdHash {
|
|
if targetT.GetMemberByAccountId(m.GetAccountId()) != nil {
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
}
|
|
|
|
func newTeam() *team {
|
|
t := new(team)
|
|
t.state = constant.TEAM_STATE_INIT
|
|
t.stateNotifyMsg = &cs.SMTeamStateNotify{}
|
|
t.stateNotifyMsg.JoinMsg = &cs.MFJoinMsg{}
|
|
t.memberIdHash = map[string]common.Player{}
|
|
t.robotList = []*robot{}
|
|
return t
|
|
}
|