aozhiwei d91a08d105 1
2024-03-26 13:27:10 +08:00

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(&notifyMsg.TeamInfo.Members, 0, 1)
for _, m := range this.memberIdHash {
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.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
}