| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471 |
- package model
- import (
- "rocommon/util"
- "roserver/baseserver/aoi"
- "roserver/baseserver/model"
- "roserver/serverproto"
- )
- type MapRole struct {
- uid uint64
- cliID model.ClientID //gate
- selfObj *aoi.AoiObject
- pos serverproto.Position
- targetPos serverproto.Position
- ownerUid uint64
- isHide bool
- unitType int32
- aoiMap *AoiMap
- //测试发送全量移动数据
- bTestSend bool
- showInfo *serverproto.PlayerShowInfo
- IsMaster bool
- }
- func newMapRole(uid uint64, position *serverproto.Position, aoiMap *AoiMap, ownerUid uint64) *MapRole {
- mapRole := &MapRole{
- uid: uid,
- ownerUid: ownerUid,
- selfObj: nil,
- bTestSend: false,
- aoiMap: aoiMap,
- showInfo: &serverproto.PlayerShowInfo{},
- }
- mapRole.pos = *position
- return mapRole
- }
- func (this *MapRole) isSummon() bool {
- return this.ownerUid > 0
- }
- //todo
- // gate消息需要合并
- func (this *MapRole) syncSurrounding() {
- //ghost只更新坐标位置,不发送消息
- if !this.IsMaster {
- return
- }
- //通知其他玩家
- enterOtherNtfMsg := &serverproto.SCPlayerEnterNtf{}
- enterOtherNtfMsg.Players = append(enterOtherNtfMsg.Players,
- &serverproto.Player{Uid: this.uid,
- Pos: &serverproto.Position{X: this.pos.X, Y: this.pos.Y, Z: this.pos.Z},
- UType: this.unitType})
- //通知自己
- enterSelfNtfMsg := &serverproto.SCPlayerEnterNtf{}
- var serverUidList = map[string][]uint64{}
- //通知别的玩家显示当前玩家
- for _, data := range this.selfObj.AoiInfo.EnterSet.List() {
- if data.(uint64) == this.uid {
- continue
- }
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- if otherRole == nil {
- continue
- }
- //判断当前别的玩家的移动列表中的人数是否超过上限
- if !otherRole.selfObj.AoiInfo.MoveNoNtfSet.Has(this.uid) && !otherRole.isSummon() {
- //todo...这边可以对相同的消息做缓存处理
- //todo... 如果otherRole在同一个gate可以通过压缩的方式来提升效率
- //otherRole.SendGate(enterOtherNtfMsg)
- //添加到同服务器列表中
- serviceID := otherRole.cliID.ServiceID
- serverUidList[serviceID] = append(serverUidList[serviceID], otherRole.cliID.SessID)
- if len(serverUidList[serviceID]) >= MAX_SEND_NUM {
- this.SendGate(enterOtherNtfMsg, serverUidList[serviceID], true)
- serverUidList[serviceID] = []uint64{}
- }
- }
- //判断召唤物对自己是否可见
- if otherRole.isHide {
- if otherRole.ownerUid == this.uid {
- enterSelfNtfMsg.Players = append(enterSelfNtfMsg.Players, &serverproto.Player{
- Uid: otherRole.uid,
- Pos: &otherRole.pos,
- UType: otherRole.unitType,
- })
- }
- } else {
- enterSelfNtfMsg.Players = append(enterSelfNtfMsg.Players, &serverproto.Player{
- Uid: otherRole.uid,
- Pos: &otherRole.pos,
- UType: otherRole.unitType,
- })
- }
- //通知自己显示别的玩家
- if len(enterSelfNtfMsg.Players) >= MAX_SEND_NUM {
- this.SendGate(enterSelfNtfMsg, nil, true)
- enterSelfNtfMsg.Players = enterSelfNtfMsg.Players[0:0]
- }
- }
- //剩余未发送部分处理
- for key, _ := range serverUidList {
- if len(serverUidList[key]) > 0 && key != "" {
- SendGate(key, enterOtherNtfMsg, serverUidList[key], true)
- }
- }
- //通知自己显示别的玩家
- if len(enterSelfNtfMsg.Players) > 0 {
- this.SendGate(enterSelfNtfMsg, nil, true)
- }
- }
- func (this *MapRole) summonSyncSurrounding() {
- //通知其他玩家
- enterOtherNtfMsg := &serverproto.SCPlayerEnterNtf{}
- enterOtherNtfMsg.Players = append(enterOtherNtfMsg.Players,
- &serverproto.Player{Uid: this.uid,
- Pos: &serverproto.Position{X: this.pos.X, Y: this.pos.Y, Z: this.pos.Z},
- UType: this.unitType})
- var serverUidList = map[string][]uint64{}
- //通知别的玩家显示当前玩家
- for _, data := range this.selfObj.AoiInfo.MoveSet.List() {
- if data.(uint64) == this.uid {
- continue
- }
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- if otherRole == nil {
- continue
- }
- //判断当前别的玩家的移动列表中的人数是否超过上限
- if !otherRole.selfObj.AoiInfo.MoveNoNtfSet.Has(this.uid) && !otherRole.isSummon() {
- //todo...这边可以对相同的消息做缓存处理
- //todo... 如果otherRole在同一个gate可以通过压缩的方式来提升效率
- //otherRole.SendGate(enterOtherNtfMsg)
- //添加到同服务器列表中
- serviceID := otherRole.cliID.ServiceID
- serverUidList[serviceID] = append(serverUidList[serviceID], otherRole.cliID.SessID)
- if len(serverUidList[serviceID]) >= MAX_SEND_NUM {
- this.SendGate(enterOtherNtfMsg, serverUidList[serviceID], true)
- serverUidList[serviceID] = []uint64{}
- }
- }
- }
- //剩余未发送部分处理
- for key, _ := range serverUidList {
- if len(serverUidList[key]) > 0 && key != "" {
- SendGate(key, enterOtherNtfMsg, serverUidList[key], true)
- }
- }
- }
- //可见状态变更处理
- func (this *MapRole) summonVisibleSyncSurrounding() {
- //通知其他玩家
- var ntfMsg interface{} = nil
- if this.isHide {
- ntfMsg = &serverproto.SCPlayerLeaveNtf{}
- ntfMsg.(*serverproto.SCPlayerLeaveNtf).Players = append(ntfMsg.(*serverproto.SCPlayerLeaveNtf).Players,
- &serverproto.Player{Uid: this.uid, Pos: &serverproto.Position{X: this.pos.X, Y: this.pos.Y, Z: this.pos.Z}, UType: this.unitType})
- } else {
- ntfMsg = &serverproto.SCPlayerEnterNtf{}
- ntfMsg.(*serverproto.SCPlayerEnterNtf).Players = append(ntfMsg.(*serverproto.SCPlayerEnterNtf).Players,
- &serverproto.Player{Uid: this.uid,
- Pos: &serverproto.Position{X: this.pos.X, Y: this.pos.Y, Z: this.pos.Z},
- UType: this.unitType})
- }
- var serverUidList = map[string][]uint64{}
- //通知别的玩家显示当前玩家
- for _, data := range this.selfObj.AoiInfo.MoveSet.List() {
- if data.(uint64) == this.uid {
- continue
- }
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- if otherRole == nil || otherRole.isSummon() {
- continue
- }
- if this.isHide {
- }
- //这边可以对相同的消息做缓存处理
- //如果otherRole在同一个gate可以通过压缩的方式来提升效率
- //otherRole.SendGate(enterOtherNtfMsg)
- //添加到同服务器列表中
- serviceID := otherRole.cliID.ServiceID
- serverUidList[serviceID] = append(serverUidList[serviceID], otherRole.cliID.SessID)
- if len(serverUidList[serviceID]) >= MAX_SEND_NUM {
- this.SendGate(ntfMsg, serverUidList[serviceID], true)
- serverUidList[serviceID] = []uint64{}
- }
- }
- //剩余未发送部分处理
- for key, _ := range serverUidList {
- if len(serverUidList[key]) > 0 && key != "" {
- SendGate(key, ntfMsg, serverUidList[key], true)
- }
- }
- }
- func (this *MapRole) playerMove(pos *serverproto.Position) {
- updateObj, ret := this.aoiMap.aoi.Update(this.uid, *this.aoiMap.aoi.AoiArea, pos.X, pos.Y, this.IsMaster)
- if updateObj == nil {
- return
- }
- this.pos = *pos
- //只处理master
- if !this.IsMaster {
- return
- }
- //只发送移动信息
- if !ret {
- //MoveOnlySet处理
- this.playerMoveNtf()
- } else {
- //enter处理
- this.syncSurrounding()
- //位置同步信息
- //MoveOnlySet处理
- this.playerMoveNtf()
- //LeaveSet处理
- //通知离开视野的玩家
- this.playerLeaveNtf()
- }
- }
- func (this *MapRole) playerMoveNtf() {
- //MoveOnlySet处理
- //位置同步信息
- syncOtherNtfMsg := &serverproto.SCSyncPlayersNtf{}
- syncOtherNtfMsg.Players = append(syncOtherNtfMsg.Players,
- &serverproto.Player{Uid: this.uid,
- Pos: &serverproto.Position{X: this.pos.X, Y: this.pos.Y, Z: this.pos.Z},
- UType: this.unitType})
- var serverUidList = map[string][]uint64{}
- for _, data := range this.selfObj.AoiInfo.MoveOnlySet.List() {
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- //移动消息 不发送给召唤物
- if otherRole.isSummon() {
- continue
- }
- if otherRole != nil && !otherRole.selfObj.AoiInfo.MoveNoNtfSet.Has(this.uid) {
- serviceID := otherRole.cliID.ServiceID
- if _, ok := serverUidList[serviceID]; ok {
- serverUidList[serviceID] = append(serverUidList[serviceID], otherRole.cliID.SessID)
- } else {
- serverUidList[serviceID] = []uint64{otherRole.cliID.SessID}
- }
- if len(serverUidList[serviceID]) >= MAX_SEND_NUM {
- SendGate(serviceID, syncOtherNtfMsg, serverUidList[serviceID], true)
- serverUidList[serviceID] = []uint64{}
- }
- }
- }
- //剩余未发送部分处理
- for key, _ := range serverUidList {
- if len(serverUidList[key]) > 0 && key != "" {
- SendGate(key, syncOtherNtfMsg, serverUidList[key], true)
- serverUidList[key] = serverUidList[key][0:0]
- }
- }
- }
- func (this *MapRole) playerLeaveNtf() {
- //LeaveSet处理
- //通知离开视野的玩家
- leaveSelfNtfMsg := &serverproto.SCPlayerLeaveNtf{}
- leaveOtherNtfMsg := &serverproto.SCPlayerLeaveNtf{}
- leaveOtherNtfMsg.Players = append(leaveOtherNtfMsg.Players,
- &serverproto.Player{Uid: this.uid,
- Pos: &serverproto.Position{X: this.pos.X, Y: this.pos.Y, Z: this.pos.Z},
- UType: this.unitType})
- var serverLeaveUidList = map[string][]uint64{}
- for _, data := range this.selfObj.AoiInfo.LeaveSet.List() {
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- if otherRole != nil {
- //移除别的玩家中移动队列中的自己(否则可能会导致发送多次离开消息)
- //1.别人通知自己离开视野 2.自己通知该玩家离开视野
- if otherRole.selfObj.AoiInfo.MoveNoNtfSet.Has(this.uid) {
- otherRole.selfObj.AoiInfo.MoveNoNtfSet.Remove(this.uid)
- } else {
- serviceID := otherRole.cliID.ServiceID
- if _, ok := serverLeaveUidList[serviceID]; ok {
- serverLeaveUidList[serviceID] = append(serverLeaveUidList[serviceID], otherRole.cliID.SessID)
- } else {
- serverLeaveUidList[serviceID] = []uint64{otherRole.cliID.SessID}
- }
- if len(serverLeaveUidList[serviceID]) >= MAX_SEND_NUM {
- SendGate(serviceID, leaveOtherNtfMsg, serverLeaveUidList[serviceID], false)
- serverLeaveUidList[serviceID] = []uint64{}
- }
- }
- otherRole.selfObj.AoiInfo.MoveSet.Remove(this.uid)
- if this.selfObj.AoiInfo.MoveNoNtfSet.Has(otherRole.uid) {
- this.selfObj.AoiInfo.MoveSet.Remove(otherRole.uid)
- this.selfObj.AoiInfo.MoveNoNtfSet.Remove(otherRole.uid)
- }
- leaveSelfNtfMsg.Players = append(leaveSelfNtfMsg.Players,
- &serverproto.Player{Uid: otherRole.uid, UType: otherRole.unitType})
- if len(leaveSelfNtfMsg.Players) >= MAX_SEND_NUM {
- this.SendGate(leaveSelfNtfMsg, nil, true)
- leaveSelfNtfMsg.Players = leaveSelfNtfMsg.Players[0:0]
- }
- }
- }
- //剩余未发送部分处理
- for key, _ := range serverLeaveUidList {
- if len(serverLeaveUidList[key]) > 0 && key != "" {
- SendGate(key, leaveOtherNtfMsg, serverLeaveUidList[key], true)
- }
- }
- //发送给自己有别的玩家离开自己的视野
- if len(leaveSelfNtfMsg.Players) > 0 {
- this.SendGate(leaveSelfNtfMsg, nil, true)
- }
- }
- func (this *MapRole) playerLeave() bool {
- this.bTestSend = false
- util.DebugF("playerLeave uid=%v", this.uid)
- leaveNtfMsg := &serverproto.SCPlayerLeaveNtf{}
- leaveNtfMsg.Players = append(leaveNtfMsg.Players, &serverproto.Player{
- Uid: this.uid,
- Pos: &this.pos,
- UType: this.unitType,
- })
- //通知自己离开地图
- this.SendGate(leaveNtfMsg, nil, true)
- leaveList := this.aoiMap.aoi.LeaveNode(this.uid)
- if leaveList == nil || len(leaveList) <= 0 {
- return true
- }
- util.DebugF("playerLeave uid=%v leaveNotifyList=%v", this.uid, leaveList)
- //通知其他玩家
- for _, data := range leaveList {
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- if otherRole != nil && otherRole.unitType != int32(UnityType_Boss) {
- otherRole.selfObj.AoiInfo.MoveSet.Remove(this.uid)
- otherRole.selfObj.AoiInfo.MoveOnlySet.Remove(this.uid)
- this.selfObj.AoiInfo.MoveNoNtfSet.Remove(otherRole.uid)
- if this.IsMaster {
- otherRole.SendGate(leaveNtfMsg, nil, true)
- }
- }
- }
- return true
- }
- //视野范围内玩家操作通知(avatar,action)
- func (this *MapRole) playerViewNtf(ntfMsg interface{}) {
- var serverUidList = map[string][]uint64{}
- for _, data := range this.selfObj.AoiInfo.MoveSet.List() {
- otherRole := this.aoiMap.getPlayer(data.(uint64))
- if otherRole != nil && !otherRole.selfObj.AoiInfo.MoveNoNtfSet.Has(this.uid) {
- serviceID := otherRole.cliID.ServiceID
- if _, ok := serverUidList[serviceID]; ok {
- serverUidList[serviceID] = append(serverUidList[serviceID], otherRole.cliID.SessID)
- } else {
- serverUidList[serviceID] = []uint64{otherRole.cliID.SessID}
- }
- if len(serverUidList[serviceID]) >= MAX_SEND_NUM {
- SendGate(serviceID, ntfMsg, serverUidList[serviceID], true)
- serverUidList[serviceID] = []uint64{}
- }
- }
- }
- //剩余未发送部分处理
- for key, _ := range serverUidList {
- if len(serverUidList[key]) > 0 && key != "" {
- SendGate(key, ntfMsg, serverUidList[key], true)
- serverUidList[key] = serverUidList[key][0:0]
- }
- }
- util.DebugF("showChange MoveSet=%v", this.selfObj.AoiInfo.MoveSet.List())
- }
- func (this *MapRole) showChange(info *serverproto.PlayerShowInfo) bool {
- if info == nil {
- return false
- }
- if info.NickName != "" {
- this.showInfo.NickName = info.NickName
- }
- if info.FashionData != nil {
- this.showInfo.FashionData = info.FashionData
- }
- //MoveSet处理
- //地图形象显示变更通知
- changeNtfMsg := &serverproto.SCMapOtherPlayersInfoNtf{}
- changeNtfMsg.InfoList = append(changeNtfMsg.InfoList, info)
- this.playerViewNtf(changeNtfMsg)
- return true
- }
- func (this *MapRole) mapDoDoAction(actionId int32, pos *serverproto.Position) bool {
- actionNtfMsg := &serverproto.SCPlayerActionNtf{
- ActionId: actionId,
- Uid: this.uid,
- Pos: pos,
- }
- this.playerViewNtf(actionNtfMsg)
- return true
- }
- func (this *MapRole) TestUpdate() {
- if this.bTestSend {
- this.TestSyncAllPlayer()
- }
- }
- func (this *MapRole) TestSyncAllPlayer() {
- //todo...
- // for test
- testNtfMsg := &serverproto.SCGMSyncAllPlayerNtf{}
- this.SendGate(testNtfMsg, nil, true)
- return
- for _, data := range this.aoiMap.aoi.GetAllNode() {
- if data == nil || data.Id == this.uid {
- continue
- }
- tempPos := this.aoiMap.getPlayer(data.Id).pos
- testNtfMsg.Players = append(testNtfMsg.Players, &serverproto.Player{
- Uid: data.Id,
- Pos: &tempPos,
- })
- if len(testNtfMsg.Players) >= MAX_SEND_NUM {
- this.SendGate(testNtfMsg, nil, true)
- testNtfMsg.Players = testNtfMsg.Players[0:0]
- }
- }
- if len(testNtfMsg.Players) > 0 {
- this.SendGate(testNtfMsg, nil, true)
- }
- }
|