aozhiwei a8ff5bf545 1
2024-03-19 20:00:28 +08:00

451 lines
10 KiB
Go

package team
import (
"q5"
"f5"
"cs"
"main/common"
"main/constant"
"sort"
"strings"
"github.com/golang/protobuf/proto"
)
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
accountIdHash map[string]common.Player
matchOk *team
matchTick int64
}
func (this *team) init(copyIdx int32, teamUuid string, owner common.Player, mapInfo* common.MapInfoRsp) {
this.sortIdx++
this.teamUuid = teamUuid
this.copyIdx = copyIdx
this.zoneId = owner.GetZoneId()
this.nodeId = owner.GetNodeId()
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.accountIdHash[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.accountIdHash[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.accountIdHash[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.accountIdHash) >= 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.state = constant.TEAM_STATE_STARTED
this.startTime = startTime
this.stateNotifyMsg.State = proto.Int32(this.state)
this.genStartGameInfo()
this.SendStateNotify()
f5.GetTimer().SetInterval(1000, func(e int32, args *q5.Args) {
if e == q5.TIMER_EXEC_EVENT {
this.SendStateNotify()
}
})
}
func (this *team) CanStartGame(hum common.Player) bool {
if !this.IsLock() {
if this.GetMemberNum() > 0 {
allReady := true
for _, m := range this.accountIdHash {
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
_matchMgr.addMatch(this)
this.SendStateNotify()
} else {
this.state = constant.TEAM_STATE_STARTED
this.startTime = f5.GetApp().GetNowSeconds()
this.stateNotifyMsg.State = proto.Int32(this.state)
this.genStartGameInfo()
this.SendStateNotify()
f5.GetTimer().SetInterval(1000, func(e int32, args *q5.Args) {
if e == q5.TIMER_EXEC_EVENT {
this.SendStateNotify()
}
})
}
}
}
func (this *team) GetMemberNum() int32 {
return int32(len(this.accountIdHash))
}
func (this *team) chooseNextLeader() {
nextLeader := this.owner
for _, m := range this.accountIdHash {
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.Started() {
if this.IsLeader(hum) {
delete(this.accountIdHash, hum.GetAccountId())
if this.GetMemberNum() > 0 {
this.chooseNextLeader()
}
} else {
delete(this.accountIdHash, hum.GetAccountId())
}
if this.GetMemberNum() < 0 {
this.Disband()
}
}
}
func (this *team) Disband() {
if !this.Started() {
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.Started() {
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.accountIdHash, target.GetAccountId())
}
}
}
}
func (this *team) HandoverLeader(hum common.Player, targetId string) {
if !this.Started() {
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.Started() {
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.accountIdHash {
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"`
} `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),
}
{
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.accountIdHash {
ele2 := q5.NewSliceElement(&ele.Members)
ele2.AccountId = m.GetAccountId()
ele2.SpecSkill = m.GetSpecSkill()
ele2.HeroUniId = m.GetHeroUniid()
}
}
}
sign := q5.Md5Str(q5.EncodeJson(&startInfo) + "520d8eAbB(8cf1^#$^&!@d833a42c820432PDAFE^^)")
payload := sign + ":" + "normal_room|" + q5.EncodeJson(&startInfo)
this.stateNotifyMsg.JoinMsg.TeamUuid = proto.String(this.getMainTeam().GetTeamUuid())
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.zoneId) + "_" +
q5.ToString(this.nodeId) + "_" +
q5.ToString(this.copyIdx) + "_";
newId := q5.ToString(this.zoneId) + "_" +
q5.ToString(this.nodeId) + "_" +
q5.ToString(nextCopyIdx) + "_";
this.nextTeamUuid = strings.Replace(this.GetTeamUuid(), oldId, newId, 0)
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.nextTeamUuid, this.owner, nextMapInfo)
_teamMgr.addTeam(nextTeam)
}
func (this *team) broadcastMsg(msg proto.Message) {
for _, m := range this.accountIdHash {
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(&notifyMsg.TeamInfo.Members, 0, 1)
for _, m := range this.accountIdHash {
m_pb := &cs.MFTeamMember{}
q5.AppendSlice(&notifyMsg.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.accountIdHash {
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.accountIdHash = map[string]common.Player{}
return t
}