| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606 |
- package model
- import (
- "rocommon/util"
- "roserver/baseserver/model"
- "roserver/serverproto"
- "unicode/utf8"
- )
- type RoleSocialOuter interface {
- //获取好友系统列表信息(不包括推荐列表信息)
- FriendReq(reqType int32)
- //添加关注
- FriendAdd(subUid uint64)
- //取消关注
- FriendDel(delUid uint64)
- //添加/删除屏蔽名单
- FriendBlack(blackUid uint64)
- //获取推荐好友列表
- FriendRecommend()
- //搜索玩家
- FriendSearch(searchName string)
- }
- //role interface
- func (this *Role) FriendReq(reqType int32) {
- if this.roleSocial != nil {
- this.roleSocial.FriendReq(reqType)
- }
- }
- func (this *Role) FriendAdd(subUid uint64) {
- if this.roleSocial != nil {
- err := this.roleSocial.FriendAdd(subUid)
- if err != serverproto.ErrorCode_ERROR_OK {
- ackMsg := &serverproto.SCFriendAddAck{
- Error: int32(err),
- }
- this.ReplayGate(ackMsg, true)
- }
- }
- }
- func (this *Role) FriendDel(delUid uint64) {
- if this.roleSocial != nil {
- err := this.roleSocial.FriendDel(delUid)
- if err != serverproto.ErrorCode_ERROR_OK {
- ackMsg := &serverproto.SCFriendDelAck{
- Error: int32(err),
- }
- this.ReplayGate(ackMsg, true)
- }
- }
- }
- func (this *Role) FriendBlack(blackUid uint64) {
- if this.roleSocial != nil {
- err := this.roleSocial.FriendBlack(blackUid)
- if err != serverproto.ErrorCode_ERROR_OK {
- ackMsg := &serverproto.SCFriendBlackAck{
- Error: int32(err),
- }
- this.ReplayGate(ackMsg, true)
- }
- }
- }
- func (this *Role) FriendRecommend() {
- if this.roleSocial != nil {
- this.roleSocial.FriendRecommend()
- }
- }
- func (this *Role) FriendSearch(searchName string) {
- if this.roleSocial != nil {
- err := this.roleSocial.FriendSearch(searchName)
- if err != serverproto.ErrorCode_ERROR_OK {
- ackMsg := &serverproto.SCFriendSearchAck{
- Error: int32(err),
- }
- this.ReplayGate(ackMsg, true)
- }
- }
- }
- const (
- StateTypeSub = 1 //关注列表
- StateTypeFans = 2 //粉丝列表
- StateTypeBlack = 3 //黑名单
- StateTypeRecommend = 4 //推荐列表
- StateClimbingTower = 5 //爬塔数据列表
- StageTypeDemonGuild = 8
- StageTypeDemonMvp = 9
- StateTypeBlack_Add = 10 //添加到黑名单状态
- StateGuildApply = 101 //公会申请列表Type
- FriendTypeNone = 0
- FriendTypeSub = 1 //关注该玩家
- FriendTypeBeSub = 2 //被关注
- FriendTypeAll = 3 //互为关注
- RECOMMEND_NUM = 6 //推荐列表玩家数量
- )
- type RoleSocial struct {
- SaveObject
- roleFriend *serverproto.RoleFriend
- subList map[uint64]struct{} //关注列表
- fansList map[uint64]struct{} //粉丝列表
- blackList map[uint64]struct{} //黑名单列表
- //db 添加或者删除对应id玩家数据
- dbSubList map[uint64]bool
- dbFansList map[uint64]bool
- dbBlackList map[uint64]bool
- recommendIdx int32
- }
- func newRoleSocial(r *Role) *RoleSocial {
- roleSocial := &RoleSocial{
- SaveObject: SaveObject{
- role: r,
- },
- roleFriend: &serverproto.RoleFriend{},
- subList: map[uint64]struct{}{},
- fansList: map[uint64]struct{}{},
- blackList: map[uint64]struct{}{},
- dbSubList: map[uint64]bool{},
- dbFansList: map[uint64]bool{},
- dbBlackList: map[uint64]bool{},
- recommendIdx: 0,
- }
- return roleSocial
- }
- func (this *RoleSocial) GetRole() *Role {
- return this.role
- }
- func (this *RoleSocial) Load(msg interface{}) bool {
- return true
- }
- func (this *RoleSocial) LoadOther(msg interface{}) bool {
- friendInfo := msg.(*serverproto.RoleFriend)
- if friendInfo != nil {
- this.roleFriend = friendInfo
- for i := 0; i < len(this.roleFriend.SubList); i++ {
- this.subList[this.roleFriend.SubList[i]] = struct{}{}
- }
- for i := 0; i < len(this.roleFriend.FansList); i++ {
- this.fansList[this.roleFriend.FansList[i]] = struct{}{}
- }
- for i := 0; i < len(this.roleFriend.BlackList); i++ {
- this.blackList[this.roleFriend.BlackList[i]] = struct{}{}
- }
- util.DebugF("uid=%v RoleSocial=%v", this.role.GetUUid(), friendInfo)
- }
- return true
- }
- func (this *RoleSocial) Save() {
- this.SetDirty(false)
- //根据不同列表不同类型做不同处理,例如删除,添加等操作,添加就保存的话操作太频繁
- dbSaveMsg := &serverproto.SSFriendDataSaveReq{}
- this.getDBSaveList(&dbSaveMsg.SubList, this.dbSubList)
- this.getDBSaveList(&dbSaveMsg.FansList, this.dbFansList)
- this.getDBSaveList(&dbSaveMsg.BlackList, this.dbBlackList)
- this.role.SendDb(dbSaveMsg)
- //clear
- this.dbSubList = map[uint64]bool{}
- this.dbFansList = map[uint64]bool{}
- this.dbBlackList = map[uint64]bool{}
- }
- func (this *RoleSocial) getDBSaveList(saveList *[]*serverproto.KeyValueType64, processList map[uint64]bool) {
- for key, val := range processList {
- var ret int32 = 1 //add
- if !val {
- ret = 2 //del
- }
- *saveList = append(*saveList, &serverproto.KeyValueType64{
- Key: key,
- Value: ret,
- })
- }
- }
- func (this *RoleSocial) isInSubList(targetUid uint64) bool {
- if _, ok := this.subList[targetUid]; ok {
- return true
- }
- return false
- }
- func (this *RoleSocial) isInFansList(targetUid uint64) bool {
- if _, ok := this.fansList[targetUid]; ok {
- return true
- }
- return false
- }
- func (this *RoleSocial) IsInBlackList(targetUid uint64) bool {
- if _, ok := this.blackList[targetUid]; ok {
- return true
- }
- return false
- }
- func (this *RoleSocial) BlackList() map[uint64]struct{} {
- return this.blackList
- }
- func (this *RoleSocial) friendState(targetUid uint64) int32 {
- if this.isInSubList(targetUid) && this.isInFansList(targetUid) {
- return FriendTypeAll
- } else if this.isInSubList(targetUid) {
- return FriendTypeSub
- } else if this.isInFansList(targetUid) {
- return FriendTypeBeSub
- }
- return FriendTypeNone
- }
- func (this *RoleSocial) CanAddSubList(uid uint64) serverproto.ErrorCode {
- if len(this.subList) >= int(model.GlobalSocialSubNumLimit) {
- return serverproto.ErrorCode_ERROR_SOCIAL_SUBLIST_LIMIT
- }
- if _, ok := this.subList[uid]; ok {
- return serverproto.ErrorCode_ERROR_SOCIAL_HAS_IN_SUB_LIST
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- //true->add false->del
- func (this *RoleSocial) HandlerSubList(addDel bool, uid uint64, briefInfo *serverproto.CommonPlayerBriefInfo) {
- if addDel {
- this.subList[uid] = struct{}{}
- if ret, ok := this.dbSubList[briefInfo.Uid]; ok {
- if !ret {
- delete(this.dbSubList, briefInfo.Uid)
- }
- } else {
- this.dbSubList[briefInfo.Uid] = true
- }
- ackMsg := &serverproto.SCFriendAddAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- BriefInfo: briefInfo,
- }
- this.role.ReplayGate(ackMsg, true)
- util.InfoF("uid=%v SubList Add target=%v", this.role.GetUUid(), uid)
- } else {
- delete(this.subList, uid)
- if this.dbSubList[uid] {
- delete(this.dbSubList, uid)
- } else {
- this.dbSubList[uid] = false
- }
- ackMsg := &serverproto.SCFriendDelAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- DelUid: uid,
- }
- this.role.ReplayGate(ackMsg, true)
- util.InfoF("uid=%v SubList Del target=%v", this.role.GetUUid(), uid)
- }
- //Task
- TaskMagCheck(this.role, serverproto.TaskType_Friend_SubFan_Num, 0)
- this.SetDirty(true)
- }
- func (this *RoleSocial) CanAddFansList(uid uint64) serverproto.ErrorCode {
- if len(this.fansList) >= int(model.GlobalSocialFansNumLimit) {
- return serverproto.ErrorCode_ERROR_SOCIAL_FANSLIST_LIMIT
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- //粉丝列表是被动操作
- func (this *RoleSocial) HandlerFansList(addDel bool, uid uint64, briefInfo *serverproto.CommonPlayerBriefInfo) {
- if addDel {
- this.fansList[uid] = struct{}{}
- if ret, ok := this.dbFansList[briefInfo.Uid]; ok {
- if !ret {
- delete(this.dbFansList, briefInfo.Uid)
- }
- } else {
- this.dbFansList[briefInfo.Uid] = true
- }
- ntfMsg := &serverproto.SCFriendAddNtf{
- BriefInfo: briefInfo,
- }
- this.role.ReplayGate(ntfMsg, true)
- util.InfoF("uid=%v FansList Add target=%v", this.role.GetUUid(), uid)
- } else {
- delete(this.fansList, uid)
- if this.dbFansList[uid] {
- delete(this.dbFansList, uid)
- } else {
- this.dbFansList[uid] = false
- }
- ntfMsg := &serverproto.SCFriendDelNtf{
- DelUid: uid,
- }
- this.role.ReplayGate(ntfMsg, true)
- util.InfoF("uid=%v FansList Del target=%v", this.role.GetUUid(), uid)
- }
- //Task
- TaskMagCheck(this.role, serverproto.TaskType_Friend_SubFan_Num, 0)
- this.SetDirty(true)
- }
- func (this *RoleSocial) HandlerBlackList(addDel bool, uid uint64, briefInfo *serverproto.CommonPlayerBriefInfo) {
- if addDel {
- this.blackList[briefInfo.Uid] = struct{}{}
- if ret, ok := this.dbBlackList[briefInfo.Uid]; ok {
- if !ret {
- delete(this.dbBlackList, briefInfo.Uid)
- }
- } else {
- this.dbBlackList[briefInfo.Uid] = true
- }
- ackMsg := &serverproto.SCFriendBlackAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- BriefInfo: briefInfo,
- }
- this.role.ReplayGate(ackMsg, true)
- util.InfoF("uid=%v BlackList Add target=%v", this.role.GetUUid(), uid)
- } else {
- delete(this.blackList, uid)
- if this.dbBlackList[uid] {
- delete(this.dbBlackList, uid)
- } else {
- this.dbBlackList[uid] = false
- }
- ackMsg := &serverproto.SCFriendBlackAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- BriefInfo: &serverproto.CommonPlayerBriefInfo{
- Uid: uid,
- },
- }
- this.role.ReplayGate(ackMsg, true)
- util.InfoF("uid=%v BlackList Del target=%v", this.role.GetUUid(), uid)
- }
- this.SetDirty(true)
- }
- //获取好友系统列表信息(不包括推荐列表信息)
- func (this *RoleSocial) FriendReq(reqType int32) serverproto.ErrorCode {
- ackMsg := &serverproto.SCFriendAck{
- Type: reqType,
- }
- //todo...
- // 如果是重新登录需要重新获取一次,避免有离线数据
- switch reqType {
- case StateTypeSub: //获取自己的关注列表(好友列表)
- ackMsg.TotalCount = int32(len(this.subList))
- ackMsg.TotalLimit = model.GlobalSocialSubNumLimit
- for key, _ := range this.subList {
- ackMsg.UidList = append(ackMsg.UidList, key)
- }
- case StateTypeFans: //获取自己的粉丝列表(其他玩家关注自己的列表)
- ackMsg.TotalCount = int32(len(this.fansList))
- ackMsg.TotalLimit = model.GlobalSocialFansNumLimit
- for key, _ := range this.fansList {
- ackMsg.UidList = append(ackMsg.UidList, key)
- }
- case StateTypeBlack: //获取黑名单列表
- ackMsg.TotalCount = int32(len(this.blackList))
- ackMsg.TotalLimit = model.GlobalSocialBlackNumLimit
- for key, _ := range this.blackList {
- ackMsg.UidList = append(ackMsg.UidList, key)
- }
- default:
- return serverproto.ErrorCode_ERROR_FAIL
- }
- //Task
- TaskMagCheck(this.role, serverproto.TaskType_Friend_SubFan_Num, 0)
- this.role.ReplayGate(ackMsg, true)
- util.InfoF("uid=%v FriendReq=%v", this.role.GetUUid(), ackMsg)
- return serverproto.ErrorCode_ERROR_OK
- }
- //添加关注(添加好友,这边添加好友是单向的)
- func (this *RoleSocial) FriendAdd(subUid uint64) serverproto.ErrorCode {
- //不能关注自己
- if this.role.GetUUid() == subUid || subUid <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- if this.isInSubList(subUid) {
- return serverproto.ErrorCode_ERROR_SOCIAL_HAS_IN_SUB_LIST
- }
- //预先判定好友数量
- ret := this.CanAddSubList(subUid)
- if ret != serverproto.ErrorCode_ERROR_OK {
- return ret
- }
- selfBriefInfo := &serverproto.CommonPlayerBriefInfo{}
- this.role.GetRoleBriefInfo(selfBriefInfo)
- tmpRole := RoleMag.GetRoleFromUUid(subUid)
- if tmpRole == nil {
- //角色在其他服务器(离线或者在线)
- ssReqMsg := &serverproto.SSFriendAddReq{
- FromUid: selfBriefInfo,
- AddUid: subUid,
- }
- this.role.SendSocial(ssReqMsg)
- return serverproto.ErrorCode_ERROR_OK
- }
- targetRole := tmpRole.(*Role)
- if targetRole.GetRoleSocial() == nil {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- ret = targetRole.GetRoleSocial().CanAddFansList(this.role.GetUUid())
- if ret != serverproto.ErrorCode_ERROR_OK {
- return ret
- }
- targetBriefInfo := &serverproto.CommonPlayerBriefInfo{}
- targetRole.GetRoleBriefInfo(targetBriefInfo)
- //添加到自己的关注列表
- this.HandlerSubList(true, subUid, targetBriefInfo)
- //并添加到对方的粉丝列表
- targetRole.GetRoleSocial().HandlerFansList(true, this.role.GetUUid(), selfBriefInfo)
- return serverproto.ErrorCode_ERROR_OK
- }
- //取消关注
- func (this *RoleSocial) FriendDel(delUid uint64) serverproto.ErrorCode {
- //不能操作自己
- if this.role.GetUUid() == delUid || delUid <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- if !this.isInSubList(delUid) {
- return serverproto.ErrorCode_ERROR_SOCIAL_NOT_IN_SUB_LIST
- }
- this.HandlerSubList(false, delUid, nil)
- tmpTargetRole := RoleMag.GetRoleFromUUid(delUid)
- if tmpTargetRole == nil {
- // 发送给其他服务器,移除粉丝列表中的自己
- ssMsg := &serverproto.SSFriendDelReq{
- FromUid: this.role.GetUUid(),
- DelUid: delUid,
- }
- this.role.SendSocial(ssMsg)
- } else {
- targetRole := tmpTargetRole.(*Role)
- if targetRole.GetRoleSocial() == nil {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- targetRole.GetRoleSocial().HandlerFansList(false, this.role.GetUUid(), nil)
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleSocial) FriendBlack(blackUid uint64) serverproto.ErrorCode {
- if this.role.GetUUid() == blackUid || blackUid <= 0 {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- //移除操作
- if this.IsInBlackList(blackUid) {
- this.HandlerBlackList(false, blackUid, nil)
- } else {
- if len(this.blackList) >= int(model.GlobalSocialBlackNumLimit) {
- return serverproto.ErrorCode_ERROR_SOCIAL_BLACK_LIMIT
- }
- //添加操作
- tmpTargetRole := RoleMag.GetRoleFromUUid(blackUid)
- if tmpTargetRole == nil {
- //发送给其他服务器,获取详细信息
- ssMsg := &serverproto.SSGetRoleBriefInfoReq{
- Type: StateTypeBlack_Add,
- PlayerUidList: []uint64{blackUid},
- }
- this.role.SendDb(ssMsg)
- } else {
- targetRole := tmpTargetRole.(*Role)
- if targetRole.GetRoleSocial() == nil {
- return serverproto.ErrorCode_ERROR_FAIL
- }
- targetBriefInfo := &serverproto.CommonPlayerBriefInfo{}
- targetRole.GetRoleBriefInfo(targetBriefInfo)
- this.HandlerBlackList(true, blackUid, targetBriefInfo)
- }
- }
- return serverproto.ErrorCode_ERROR_OK
- }
- func (this *RoleSocial) FriendRecommend() {
- //先查找自己的粉丝列表
- //再查找
- ackMsg := &serverproto.SCFriendRecommendAck{
- Error: int32(serverproto.ErrorCode_ERROR_OK),
- }
- ssMsg := &serverproto.SSGetRoleBriefInfoReq{
- Type: StateTypeRecommend,
- }
- this.recommendIdx++
- recommendNum := RECOMMEND_NUM
- for key, _ := range this.fansList {
- if this.isInSubList(key) {
- continue
- }
- recommendNum--
- recommendRole := RoleMag.GetRoleFromUUid(key)
- if recommendRole != nil {
- bfInfo := &serverproto.CommonPlayerBriefInfo{
- OnlineState: true,
- }
- recommendRole.(*Role).GetRoleBriefInfo(bfInfo)
- ackMsg.BriefInfoList = append(ackMsg.BriefInfoList, bfInfo)
- } else {
- ssMsg.PlayerUidList = append(ssMsg.PlayerUidList, key)
- }
- if recommendNum <= 0 {
- break
- }
- }
- if recommendNum > 0 {
- ret, uidList := RoleMag.GetFIFOList(this.recommendIdx, int32(recommendNum), this.role, this.fansList)
- if !ret {
- this.recommendIdx = 1
- }
- if len(uidList) > 0 {
- ssMsg.PlayerUidList = append(ssMsg.PlayerUidList, uidList...)
- }
- }
- this.role.ReplayGate(ackMsg, true)
- if len(ssMsg.PlayerUidList) > 0 {
- this.role.SendDb(ssMsg)
- }
- }
- func (this *RoleSocial) FriendSearch(searchName string) serverproto.ErrorCode {
- if len(searchName) <= 0 {
- searchName = ""
- }
- nameLen := utf8.RuneCountInString(searchName)
- if nameLen > 15 {
- return serverproto.ErrorCode_ERROR_RENAME_NAME_LEN_ERROR
- }
- //不能查找自己
- if this.role.GetNickName() == searchName && searchName != "" {
- return serverproto.ErrorCode_ERROR_SOCIAL_SEARCH_SELF
- }
- //先查询数据库,获得玩家的Uid,再通过Uid做进一步处理
- ssMsg := &serverproto.SSGetUidByRoleNameReq{
- SelfUid: this.role.GetUUid(),
- SearchName: searchName,
- Zone: this.role.GetSelectZone(),
- //Zone: int32(service.GetServiceConfig().Node.Zone),
- }
- this.role.SendDb(ssMsg)
- return serverproto.ErrorCode_ERROR_OK
- }
- //互粉好友
- func (this *RoleSocial) GetFriendList() []uint64 {
- if len(this.subList) == 0 || len(this.fansList) == 0 {
- return nil
- }
- var UidList []uint64
- for subUid, _ := range this.subList {
- if _, ok := this.fansList[subUid]; ok {
- UidList = append(UidList, subUid)
- }
- }
- return UidList
- }
|