package friend import ( "bet24.com/log" "bet24.com/servers/common" cash "bet24.com/servers/micros/money/proto" notification "bet24.com/servers/micros/notification/proto" task "bet24.com/servers/micros/task/proto" userlabel "bet24.com/servers/micros/userlabel/proto" userservices "bet24.com/servers/micros/userservices/proto" "encoding/json" "sync" ) type user_friend struct { lock *sync.RWMutex UserID int GiveTimes int // 今天剩余赠送礼物次数 FriendList []*FriendItem // 好友列表 ApplyList []*FriendBase // 申请列表(自己申请的) VerifyList []*FriendBase // 审核列表(谁来申请的) RoomInviteHistory []*RoomInviteInfo // 私人场房间邀请 potentialList []PotentialFriend // 潜在好友列表 blackList []BlackItem // 黑名单 } func newUserFriend(userId int) *user_friend { u := new(user_friend) u.lock = &sync.RWMutex{} u.UserID = userId // 获取好友列表 u.GiveTimes, u.FriendList = getList(u.UserID) go func(u *user_friend) { for _, v := range u.FriendList { if mgr.isOnline(v.FriendID) { v.GameStatus = GameStatus_Online } } //获取审核列表(谁来申请的) u.VerifyList = getVerifyList(u.UserID) for _, v := range u.VerifyList { if mgr.isOnline(v.FriendID) { v.GameStatus = GameStatus_Online } } //获取申请列表(自己申请的) u.ApplyList = getApplyList(u.UserID) for _, v := range u.ApplyList { if mgr.isOnline(v.FriendID) { v.GameStatus = GameStatus_Online } } // 获取房间邀请 u.roomInviteLoadFromRedis() u.potentialList = getPotentialFriendList(u.UserID) // 黑名单 u.blackList = trans_GetBlackList(u.UserID) }(u) return u } func (u *user_friend) refreshGift() { dayIndex := common.GetDayIndex(common.GetTimeStamp()) giveTimes := 0 for j := 0; j < len(u.FriendList); j++ { //领取 if common.GetDayIndex(u.FriendList[j].GiftTime) < dayIndex && u.FriendList[j].IsGift == GIFT_STATUS_RECEIVED { u.FriendList[j].IsGift = GIFT_STATUS_NOT } //赠送 if common.GetDayIndex(u.FriendList[j].GiveTime) >= dayIndex { if u.FriendList[j].IsGive == GIVE_STATUS_HAVE { u.FriendList[j].IsGive = GIVE_STATUS_NOT } giveTimes++ } } //计算剩余赠送次数 u.GiveTimes = MAX_GIVETIMES - giveTimes } func (u *user_friend) friendApply(toUserId int) int { //已经是我的好友? for _, v := range u.FriendList { if v.FriendID == toUserId { return ALREADY_A_FRIEND } } //已经申请过 for _, v := range u.ApplyList { if v.FriendID == toUserId { return ADD_TO_EXAMINE } } //待审核 for _, v := range u.VerifyList { if v.FriendID == toUserId { return ADD_TO_EXAMINE } } // 在黑名单中,返回成功,无限期等待 if exist := trans_IsBlack(u.UserID, toUserId); exist { return ADD_SUCCESS } // 检查自己的好友栏是否上限 myFriendCount := mgr.getMaxFriendCount(u.UserID) if len(u.FriendList) >= myFriendCount.Base+myFriendCount.Extra { return FRIEND_LIMIT } //还不是我的好友 apply(u.UserID, toUserId) // 刷新自己的申请列表 mgr.refreshFriends(u.UserID, false, true, false, u.UserID, "apply") // TODO: 通知数据库要申请好友 go mgr.refreshFriends(toUserId, false, false, true, u.UserID, "apply") // 触发任务 task.DoTaskAction(u.UserID, task.TaskAction_addfriend, 1, task.TaskScope{}) return ADD_SUCCESS } func (u *user_friend) delFriend(toUserId int) ([]*FriendItem, bool) { ret := false for i := 0; i < len(u.FriendList); i++ { if u.FriendList[i].FriendID == toUserId { //从好友列表中删除 u.FriendList = append(u.FriendList[:i], u.FriendList[i+1:]...) //TODO: go 通知数据库删除好友 go func(toUserId int) { //数据库删除 del(u.UserID, toUserId) mgr.refreshFriends(toUserId, true, false, false, u.UserID, "delete") }(toUserId) i-- // return u.FriendList ret = true } } //还不是我的好友, 直接返回 return u.FriendList, ret } func (u *user_friend) friendHandleApply(toUserId, apply int) []*FriendItem { // 检查自己的好友栏是否上限 myFriendCount := mgr.getMaxFriendCount(u.UserID) if len(u.FriendList) >= myFriendCount.Base+myFriendCount.Extra { // 不需要拒绝也不需要提示,请求继续保留在审核列表中 return nil } //删除申请列表中的数据 for i := 0; i < len(u.VerifyList); i++ { if u.VerifyList[i].FriendID == toUserId { u.VerifyList = append(u.VerifyList[:i], u.VerifyList[i+1:]...) break } } //TODO:通知数据库更新好友申请数据等 deal(u.UserID, toUserId, apply) //已经在我的好友列表 for _, v := range u.FriendList { if v.FriendID == toUserId { return u.FriendList } } //不同意申请,不需要更新好友列表 // 1=同意 2=拒绝 if apply != 1 { //通知对方 go mgr.refreshFriends(toUserId, false, true, false, u.UserID, "reject") return u.FriendList } //同意申请 //刷新自己的好友列表 mgr.refreshFriends(u.UserID, true, false, true, u.UserID, "agree") //通知对方 go mgr.refreshFriends(toUserId, true, true, false, u.UserID, "agree") // 8=交际类(好友模块)(用户标签) go userlabel.TriggerEvent(u.UserID, userlabel.Type_Friend, userlabel.Scope{Num: 1}) go userlabel.TriggerEvent(toUserId, userlabel.Type_Friend, userlabel.Scope{Num: 1}) return u.FriendList } func (u *user_friend) friendGiveGift(toUserId int) int { // 没有赠送次数了 if u.GiveTimes <= 0 { return 12 } dayIndex := common.GetDayIndex(common.GetTimeStamp()) for _, v := range u.FriendList { if v.FriendID != toUserId { continue } //今天已经赠送过了 if common.GetDayIndex(v.GiveTime) >= dayIndex { return 1 } //TODO: 通知数据库向对方赠送礼物,记录赠送时间 go giveGift(u.UserID, toUserId) v.IsGive = GIVE_STATUS_HAVE v.GiveTime = common.GetTimeStamp() u.GiveTimes-- // 通知对方 mgr.notifyGift(u.UserID, toUserId) return 1 } return 0 } func (u *user_friend) friendGetGift(toUserId int, ipAddress string) int { dayIndex := common.GetDayIndex(common.GetTimeStamp()) for _, v := range u.FriendList { if v.FriendID != toUserId { continue } //是否有可领取 if v.IsGift != GIFT_STATUS_HAVE { return 0 } //今天是否已经领取过 if common.GetDayIndex(v.GiftTime) >= dayIndex { return 0 } //更新礼物状态 v.IsGift = GIFT_STATUS_RECEIVED //TODO: 数据库操作获取礼物,目前只有金币 go func() { //TODO: 数据库操作 getGift(u.UserID, toUserId) //TODO:送礼物 cash.GiveMoney(u.UserID, GIVE_GOLD, common.LOGTYPE_FRIEND, "好友模块", "赠送金币", ipAddress) }() return 1 } return 0 } func (u *user_friend) setUserStatus(toUserId int, status string) { for _, v := range u.FriendList { if v.FriendID == toUserId { v.GameStatus = status buf, _ := json.Marshal(notification.NotificationFriend{ NotifyId: Friend_Notify_Status, UserId: toUserId, Data: status, }) //发送通知 go notification.AddNotification(u.UserID, notification.Notification_Friend, string(buf)) return } } } // 返回 0=不是好友 1=好友 2=已申请(自己申请的,待对方审核) 3=待审核(对方申请的,待自己审核) 4=黑名单 func (u *user_friend) ifFriend(friendId int) int { for _, v := range u.FriendList { if v.FriendID == friendId { return FriendShip_Friend } } for _, v := range u.ApplyList { if v.FriendID == friendId { return FriendShip_AlreadyApplied } } for _, v := range u.VerifyList { if v.FriendID == friendId { return FriendShip_ToBeReviewed } } for _, v := range u.blackList { if v.UserId == friendId { return FriendShip_Black } } return FriendShip_Normal } const max_potential_count = 50 func (u *user_friend) getPotentialFriendList() string { // 清理并补充数据 for i := 0; i < len(u.potentialList); { pf := &u.potentialList[i] if u.ifFriend(pf.UserId) != 0 { u.potentialList = append(u.potentialList[:i], u.potentialList[i+1:]...) go deletePotentialFriend(u.UserID, pf.UserId) continue } i++ // 补充数据 if pf.NickName == "" { usr := userservices.GetUserInfo(pf.UserId) if usr != nil { pf.NickName = usr.NickName pf.FaceID = usr.FaceId pf.FriendID = pf.UserId pf.FaceUrl = usr.FaceUrl pf.Decorations = usr.Decorations } } } d, _ := json.Marshal(u.potentialList) return string(d) } func (u *user_friend) addPotentialFriend(userId int, memo string) { if u.ifFriend(userId) != 0 { log.Release("user_friend.addPotentialFriend already friend") return } // 列表已存在 for _, v := range u.potentialList { if v.UserId == userId { return } } pf := PotentialFriend{ UserId: userId, MetTime: common.GetTimeStamp(), Memo: memo, } u.potentialList = append([]PotentialFriend{pf}, u.potentialList...) go addPotentialFriend(u.UserID, userId, pf.MetTime, memo) if len(u.potentialList) <= max_potential_count { return } for i := max_potential_count; i < len(u.potentialList); i++ { go deletePotentialFriend(u.UserID, u.potentialList[i].UserId) } u.potentialList = u.potentialList[:max_potential_count] } func (u *user_friend) removePotentialFriend(userId int) { for i := 0; i < len(u.potentialList); i++ { if u.potentialList[i].UserId == userId { u.potentialList = append(u.potentialList[:i], u.potentialList[i+1:]...) go deletePotentialFriend(u.UserID, userId) return } } } // 获取黑名单列表 func (u *user_friend) getBlackList() []BlackItem { return u.blackList } // 添加黑名单 func (u *user_friend) addBlack(userId int) (retCode int, message string) { if u.UserID == userId { retCode, message = 14, "Can't add myself as blacklist" return } // 已经在黑名单 for _, v := range u.blackList { if v.UserId == userId { retCode, message = 11, "already blacklisted" return } } // 用户信息 info := userservices.GetUserInfo(userId) if info == nil { retCode, message = 12, "Invalid user information" return } // 添加黑名单 u.blackList = append(u.blackList, BlackItem{ UserId: userId, Crdate: common.GetNowTimeStr(), }) // 删除好友 u.delFriend(userId) // 添加黑名单 go trans_AddBlack(u.UserID, userId, common.GetNowTimeStr()) retCode, message = 1, "success" return } // 删除黑名单 func (u *user_friend) delBlack(userId int) (retCode int, message string) { for i := 0; i < len(u.blackList); i++ { if u.blackList[i].UserId != userId { continue } // 删除 u.blackList = append(u.blackList[:i], u.blackList[i+1:]...) // 数据库删除 go trans_DelBlack(u.UserID, userId) retCode, message = 1, "success" return } retCode, message = 11, "Failed to delete blacklist" return } func (u *user_friend) isBlackListUser(userId int) bool { for _, v := range u.blackList { if v.UserId == userId { return true } } return false } func (u *user_friend) isBlackListUserIn(userIds []int) bool { for _, v1 := range userIds { for _, v := range u.blackList { if v.UserId == v1 { return true } } } return false }