game2006go/server/imserver/friendsmgr.go
2023-09-26 13:16:58 +08:00

366 lines
10 KiB
Go

package main
import (
"cs"
"f5"
"q5"
"sync"
"time"
)
type FriendsMgr struct {
cs.MsgHandlerImpl
mu sync.RWMutex
Users map[string]*User // accountId -> 用户
UserCount int // 用户总数
}
func (fm *FriendsMgr) init() {
fm.Users = make(map[string]*User)
fm.UserCount = 0
fm.loadFromDB()
}
func (fm *FriendsMgr) unInit() {
// 1. Loop struct data
// 2. Struct Data Persist to DB
}
func (fm *FriendsMgr) loadFromDB() {
// 加载好友关系表 列表
fm.loadFriendships()
// 加载黑名单列表
// fm.loadBlacklist()
}
// SearchByAccountId 搜索指定用户
func (fm *FriendsMgr) SearchByAccountId(accountId string, cb func(errCode int32, errMsg string, playerProfile *PlayerProfile)) {
cacheMgr.GetProfileByAccountId(accountId, func(err error, profile *PlayerProfile) {
if err != nil {
cb(ERR_CODE_SEARCH_USER_DB_FAIL, "SearchByAccountId db error", nil)
return
}
cb(0, "OK", profile)
})
}
// SearchUsers 搜索用户
func (fm *FriendsMgr) SearchUsers(accountId, username string, sinceId int64, cb func(errCode int32, errMsg string, lastId int64, listFriend []*PlayerProfile)) {
var profiles = make([]*PlayerProfile, 0, MaxSearchResults)
if len(username) > SearchWord {
cb(ERR_CODE_SEARCH_USERS_SIZE_FULL, "SearchUsers username size full", sinceId, profiles)
return
}
fm.findUsersByUsername(username, sinceId, func(err error, lastId int64, profiles []*PlayerProfile) {
if err != nil {
cb(ERR_CODE_SEARCH_USERS_DB_FAIL, "SearchUsers username db error", sinceId, profiles)
return
}
cb(0, "OK", lastId, profiles)
})
}
// AddFriendRequest 添加好友请求 By default, account1Id is me
func (fm *FriendsMgr) AddFriendRequest(account1Id string, account2Id string, cb func(errCode int32, errMsg string)) {
user1 := fm.GetUser(account1Id)
user2 := fm.GetUser(account2Id)
if user2 == nil {
user2 = fm.LoadUser(account2Id)
}
//found1 := user1.IsInBlacklist(account2Id)
//found2 := user2.IsInBlacklist(account1Id)
//if found1 || found2 {
// cb(ERR_CODE_USER_IN_BLACKLIST, "AddFriendRequest user in blacklist")
// return
//}
// 检查已发送请求
friendship, exists := user1.Friendships[account2Id]
if exists {
if friendship.IsFriendship == 0 {
cb(ERR_CODE_OK, "AddFriendRequest ok")
return
}
if friendship.IsFriendship == 1 {
cb(ERR_CODE_ALREADY_FRIEND, "Already a friend")
return
}
}
// 好友已满
if fm.GetFriendCount(account1Id) >= MaxFriendMembers || fm.GetFriendCount(account2Id) >= MaxFriendMembers {
cb(ERR_CODE_FRIENDSHIP_IS_FULL, "AddFriendRequest friendship is full")
return
}
// 待请求已满
if fm.GetFriendRequestCount(account1Id) >= MaxPendingFriendReqs ||
fm.GetFriendRequestCount(account2Id) >= MaxPendingFriendReqs {
cb(ERR_CODE_PENDING_REQUEST_IS_FULL, "AddFriendRequest pending request is full")
return
}
requestTime := time.Now().Unix()
fm.upsertFriendShip(account1Id, account2Id, FriendshipStatusPending, requestTime, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_FRIENDSHIP_DB_FAIL, "AddFriendRequest update friendship db error")
f5.GetSysLog().Info("AddFriendRequest update friendship db error")
return
}
user1.AddFriendRequest(account2Id, FriendshipStatusPending, requestTime)
user2.AddFriendRequest(account1Id, FriendshipStatusPending, requestTime)
cb(ERR_CODE_OK, "AddFriendRequest ok")
})
}
// AcceptFriendRequest 接受好友请求
func (fm *FriendsMgr) AcceptFriendRequest(account1Id string, account2Id string, cb func(errCode int32, errMsg string)) {
user1 := fm.GetUser(account1Id)
user2 := fm.GetUser(account2Id)
if user2 == nil {
user2 = fm.LoadUser(account2Id)
}
friendship, exists := user1.Friendships[account2Id]
if !exists {
cb(ERR_CODE_NO_IN_REQ, "AcceptFriendRequest user2 no in user1 pending request")
return
}
if friendship.IsFriendship != 0 {
cb(ERR_CODE_ALREADY_FRIEND, "Already a friend")
return
}
if fm.GetFriendCount(account1Id) >= MaxFriendMembers || fm.GetFriendCount(account2Id) >= MaxFriendMembers {
cb(ERR_CODE_USERS_IS_FULL, "AcceptFriendRequest users is full")
return
}
requestTime := time.Now().Unix()
fm.upsertFriendShip(account1Id, account2Id, FriendshipStatusOK, requestTime, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_FRIENDSHIP_DB_FAIL, "AcceptFriendRequest update friendship db error")
return
}
friendship1 := &Friendship{
FriendAccountId: account2Id,
IsFriendship: FriendshipStatusOK,
RequestTime: time.Now().Unix(),
}
user1.Friendships[account2Id] = friendship1
friendship2 := &Friendship{
FriendAccountId: account1Id,
IsFriendship: FriendshipStatusOK,
RequestTime: time.Now().Unix(),
}
user2.Friendships[account1Id] = friendship2
cb(ERR_CODE_OK, "")
})
}
// RejectFriendRequest 拒绝好友请求
func (fm *FriendsMgr) RejectFriendRequest(account1Id string, account2Id string, cb func(errCode int32, errMsg string)) {
user1 := fm.GetUser(account1Id)
user2 := fm.GetUser(account2Id)
if user2 == nil {
user2 = fm.LoadUser(account2Id)
}
if user1 == nil || user2 == nil {
cb(ERR_CODE_USERS_NO_EXISTS, "RejectFriendRequest user no exists")
return
}
friendship, exists := user1.Friendships[account2Id]
if !exists {
cb(ERR_CODE_NO_IN_REQ, "AcceptFriendRequest user2 no in user1 pending request")
return
}
if friendship.IsFriendship == 1 {
cb(ERR_CODE_ALREADY_FRIEND, "Already a friend")
return
}
requestTime := time.Now().Unix()
fm.upsertFriendShip(account2Id, account1Id, FriendshipStatusReject, requestTime, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_PENDING_REQUEST_DB_FAIL, "RejectFriendRequest update pending request db error")
return
}
user1.RemoveFriendRequest(account2Id)
user2.RemoveFriendRequest(account1Id)
cb(ERR_CODE_OK, "")
})
}
// DeleteFriendShip 删除好友
func (fm *FriendsMgr) DeleteFriendShip(account1Id, account2Id string, cb func(errCode int32, errMsg string)) {
user1 := fm.GetUser(account1Id)
user2 := fm.GetUser(account2Id)
if user2 == nil {
user2 = fm.LoadUser(account2Id)
}
if user1 == nil || user2 == nil {
cb(ERR_CODE_USERS_NO_EXISTS, "DeleteFriendShip user no exists")
return
}
friendship, exists := user1.Friendships[account2Id]
if !exists || friendship.IsFriendship != 1 {
cb(ERR_CODE_FRIEND_NO_EXISTS, "DeleteFriendShip user no exists")
return
}
user1.RemoveFriendShip(account2Id)
user2.RemoveFriendShip(account1Id)
updateFields := [][]string{{"is_friendship", q5.ToString(FriendshipStatusDeleted)}}
fm.updateFriendShip(account1Id, account2Id, updateFields, func(err error) {
if err != nil {
f5.GetSysLog().Info("DeleteFriendShip, updateFriendShip accountId:[%s-%s], db error:%s", account1Id, account2Id, err)
cb(ERR_CODE_UPDATE_FRIENDSHIP_DB_FAIL, "DeleteFriendShip update friendship db error")
return
}
cb(ERR_CODE_OK, "")
})
}
// AddBlacklist 加入黑名单
func (fm *FriendsMgr) AddBlacklist(account1Id string, account2Id string, cb func(errCode int32, errMsg string)) {
User1 := fm.GetUser(account1Id)
user2 := fm.GetUser(account2Id)
if User1 == nil || user2 == nil {
cb(ERR_CODE_USERS_NO_EXISTS, "AddBlacklist user no exists")
return
}
user2Blocked := User1.GetBlacklist(account2Id)
if user2Blocked != nil && user2Blocked.IsRemoved != 0 {
cb(ERR_CODE_USER_IN_BLACKLIST, "AddBlacklist user in blacklist")
return
}
if User1.GetBlacklistCount() >= MaxBlockedMembers {
cb(ERR_CODE_BLACKLIST_FULL, "AddBlacklist blacklist is full")
return
}
fm.upsertBlacklist(account1Id, account2Id, BlacklistStatusDefault, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_BLACKLIST_DB_FAIL, err.Error())
return
}
User1.AddBlacklist(&FriendBlackList{
AccountId: account2Id,
IsRemoved: 0,
})
cb(ERR_CODE_OK, "")
})
}
// RemoveBlacklist 移除黑名单
func (fm *FriendsMgr) RemoveBlacklist(account1Id string, account2Id string, cb func(errCode int32, errMsg string)) {
user1 := fm.GetUser(account1Id)
user2 := fm.GetUser(account2Id)
if user1 == nil || user2 == nil {
cb(ERR_CODE_USERS_NO_EXISTS, "RemoveBlacklist user no exists")
return
}
user2Blocked := user1.GetBlacklist(account2Id)
if user2Blocked == nil || user2Blocked.IsRemoved == 1 {
cb(ERR_CODE_USER_NOT_IN_BLACKLIST, "RemoveBlacklist user not in blacklist")
return
}
fm.upsertBlacklist(account1Id, account2Id, BlacklistStatusIsRemoved, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_BLACKLIST_DB_FAIL, err.Error())
return
}
user1.RemoveBlacklist(account2Id)
cb(ERR_CODE_OK, "")
})
}
// GetFriendCount 好友数量
func (fm *FriendsMgr) GetFriendCount(accountId string) int {
user := fm.GetUser(accountId)
return len(user.Friendships)
}
// GetFriendRequestCount 等待请求数量
func (fm *FriendsMgr) GetFriendRequestCount(accountId string) int {
user := fm.GetUser(accountId)
if user != nil {
count := 0
for _, friendship := range user.Friendships {
if friendship.IsFriendship == 0 {
count++
}
}
return count
}
return 0
}
func (fm *FriendsMgr) CleanFriendship(accountID string) {
user := fm.GetUser(accountID)
if user != nil {
user.Friendships = make(map[string]*Friendship, MaxFriendMembers)
}
}
func (fm *FriendsMgr) AddFriendshipToMap(accountID string, friendship *Friendship) {
user := fm.GetUser(accountID)
user.Friendships[friendship.FriendAccountId] = friendship
}
func (fm *FriendsMgr) GetFriendByAccountId(account1Id, account2Id string) *User {
user := fm.GetUser(account1Id)
friendship, exists := user.Friendships[account2Id]
if exists && friendship.IsFriendship == 1 {
return fm.GetUser(account2Id)
}
return nil
}
func (fm *FriendsMgr) AddUser(accountId string, user *User) {
if _, exists := fm.Users[accountId]; !exists {
fm.Users[accountId] = user
//fm.UserCount = len(fm.Users)
fm.UserCount++
}
}
func (fm *FriendsMgr) GetUser(accountId string) *User {
if user, ok := fm.Users[accountId]; ok {
return user
}
return nil
}
func (fm *FriendsMgr) LoadUser(accountId string) *User {
existsUser, exists := fm.Users[accountId]
if !exists {
user := NewUser(accountId)
friendMgr.AddUser(accountId, user)
// 加载我的好友关系表
friendMgr.loadUserFriendships(user, [][]string{
{"account1_id", user.AccountId},
})
friendMgr.loadUserFriendships(user, [][]string{
{"account2_id", user.AccountId},
})
// 加载我的黑名单列表
// friendMgr.loadBlacklist(user)
return user
}
return existsUser
}