This commit is contained in:
aozhiwei 2024-03-22 11:54:17 +08:00
parent 99010501b8
commit 1fcc4cf71b
5 changed files with 58 additions and 641 deletions

View File

@ -0,0 +1,54 @@
package friend
import (
)
type FriendMgr struct {
friendHash map[string]*map[string]int32
blackHash map[string]*map[string]int32
byBlackHash map[string]*map[string]int32
}
func (this *FriendMgr) Init() {
}
func (this *FriendMgr) UnInit() {
}
func (this *FriendMgr) loadFromDB() {
//this.loadFriendships()
//this.loadBlacklist()
}
func (this *FriendMgr) IsFriend(accountId1 string, accountId2 string) bool {
myFriends := this.getFriends(accountId1)
if myFriends != nil {
if _, ok := (*myFriends)[accountId2]; ok {
return ok
}
}
return false
}
func (this *FriendMgr) HasFriend(accountId string) bool {
myFriends := this.getFriends(accountId)
if myFriends != nil {
return len(*myFriends) > 0
}
return false
}
func (this *FriendMgr) GetFriendNum(accountId string) int32 {
myFriends := this.getFriends(accountId)
if myFriends != nil {
return int32(len(*myFriends))
}
return 0
}
func (this *FriendMgr) getFriends(accountId string) *map[string]int32 {
if friends, ok := this.friendHash[accountId]; ok {
return friends
}
return nil
}

View File

@ -1,271 +0,0 @@
package friend
import (
"f5"
"fmt"
"q5"
"strings"
"main/constant"
"main/common"
. "main/global"
)
func (fm *FriendsMgr) upsertFriendShip(account1Id string, account2Id string, isFriendship int, requestTime int64, cb func(error)) {
account1Id, account2Id = SwapAccountIds(account1Id, account2Id)
where := [][]string{
{"account1_id", account1Id},
{"account2_id", account2Id},
}
insertKv := [][]string{
{"account1_id", account1Id},
{"account2_id", account2Id},
{"is_friendship", q5.ToString(isFriendship)},
{"createtime", q5.ToString(requestTime)},
{"modifytime", q5.ToString(requestTime)},
}
updateKv := [][]string{
{"is_friendship", q5.ToString(isFriendship)},
{"modifytime", q5.ToString(requestTime)},
}
f5.GetJsStyleDb().Upsert(
constant.FRIEND_DB,
"t_friend_ships",
where,
updateKv,
insertKv,
func(err error, lastInsertId int64, rowsAffected int64) {
cb(err)
},
)
}
func (fm *FriendsMgr) updateFriendShip(account1Id string, account2Id string, fields [][]string, cb func(error)) {
account1Id, account2Id = SwapAccountIds(account1Id, account2Id)
where := [][]string{
{"account1_id", account1Id},
{"account2_id", account2Id},
}
f5.GetJsStyleDb().Update(
constant.FRIEND_DB,
"t_friend_ships",
fields,
where,
func(err error, lastInsertId int64, rowsAffected int64) {
cb(err)
},
)
}
func (fm *FriendsMgr) upsertBlacklist(account1Id string, account2Id string, isRemoved int, cb func(error)) {
where := [][]string{
{"account_id", account1Id},
}
insertKv := [][]string{
{"account_id", account1Id},
{"blocked_account_id", account2Id},
{"is_removed", q5.ToString(isRemoved)},
}
updateKv := [][]string{
{"is_removed", q5.ToString(isRemoved)},
}
f5.GetJsStyleDb().Upsert(
constant.FRIEND_DB,
"t_friend_blacklist",
where,
updateKv,
insertKv,
func(err error, lastInsertId int64, rowsAffected int64) {
cb(err)
//if err != nil {
// fmt.Printf("error:%v\n", err)
//}
//fmt.Printf("lastInsertId:%d\n", lastInsertId)
//fmt.Printf("rowsAffected:%d\n", rowsAffected)
},
)
}
func (fm *FriendsMgr) findUsersByUsername(username string, sinceId int64, cb func(err error, lastId int64, profiles []*common.PlayerProfile)) {
fields := []string{"idx", "account_id", "name", "head_id", "head_frame", "star_num", "rank", "last_login_time"}
var where [][]string
usernameLike := fmt.Sprintf("%%%s%%", username)
likeWhere := [][]string{
{"name", usernameLike},
}
f5.GetJsStyleDb().SelectLike(
constant.GAME_DB,
"t_user",
fields,
where,
likeWhere,
sinceId,
constant.MaxSearchResults,
func(err error, rows *f5.DataSet) {
if err != nil {
cb(err, 0, nil)
return
}
lastId := sinceId
profiles := make([]*common.PlayerProfile, 0, constant.MaxSearchResults)
for rows.Next() {
autoId := q5.ToInt64(rows.GetByIndex(0))
if autoId > lastId {
lastId = autoId
}
accountId := q5.ToString(rows.GetByIndex(1))
onlineStatus := GetPlayerMgr().GetOnlineStatus(accountId)
profile := &common.PlayerProfile{
AccountId: q5.ToString(rows.GetByIndex(1)),
Username: q5.ToString(rows.GetByIndex(2)),
Avatar: q5.ToInt32(rows.GetByIndex(3)),
AvatarHead: q5.ToInt32(rows.GetByIndex(4)),
Star: q5.ToInt32(rows.GetByIndex(5)),
Rank: q5.ToInt32(rows.GetByIndex(6)),
LastLoginTime: q5.ToInt32(rows.GetByIndex(7)),
OnlineStatus: onlineStatus,
}
profiles = append(profiles, profile)
}
cb(nil, lastId, profiles)
},
)
}
// loadFriendships 加载好友关系表
func (fm *FriendsMgr) loadFriendships() {
fields := []string{"account1_id", "account2_id", "is_friendship", "createtime"}
var where [][]string
f5.GetJsStyleDb().Select(
constant.FRIEND_DB,
"t_friend_ships",
fields,
where,
func(err error, rows *f5.DataSet) {
if err != nil {
panic(err)
}
userMap := make(map[string]*User)
for rows.Next() {
account1Id := q5.ToString(rows.GetByIndex(0))
account2Id := q5.ToString(rows.GetByIndex(1))
isFriendship := q5.ToInt32(rows.GetByIndex(2))
requestTime := q5.ToInt64(rows.GetByIndex(3))
// 检查用户是否已经存在,如果不存在则创建
user1, exists1 := userMap[account1Id]
if !exists1 {
user1 = NewUser(account1Id)
GetFriendMgr().AddUser(account1Id, user1)
userMap[account1Id] = user1
}
user2, exists2 := userMap[account2Id]
if !exists2 {
user2 = NewUser(account2Id)
GetFriendMgr().AddUser(account2Id, user2)
userMap[account2Id] = user2
}
// 创建好友关系并添加到用户对象中
friendship1 := &Friendship{
FriendAccountId: account2Id,
IsFriendship: isFriendship,
RequestTime: requestTime,
}
user1.Friendships[account2Id] = friendship1
friendship2 := &Friendship{
FriendAccountId: account1Id,
IsFriendship: isFriendship,
RequestTime: requestTime,
}
user2.Friendships[account1Id] = friendship2
}
},
)
}
func (fm *FriendsMgr) loadUserFriendships(user *User, where [][]string) {
fields := []string{"account1_id", "account2_id", "is_friendship", "createtime"}
f5.GetJsStyleDb().Select(
constant.FRIEND_DB,
"t_friend_ships",
fields,
where,
func(err error, rows *f5.DataSet) {
if err != nil {
return
}
for rows.Next() {
account1Id := q5.ToString(rows.GetByIndex(0))
account2Id := q5.ToString(rows.GetByIndex(1))
isFriendship := q5.ToInt32(rows.GetByIndex(2))
requestTime := q5.ToInt64(rows.GetByIndex(3))
if user.AccountId == account1Id {
friendship1 := &Friendship{
FriendAccountId: account2Id,
IsFriendship: isFriendship,
RequestTime: requestTime,
}
user.Friendships[account2Id] = friendship1
user2 := NewUser(account2Id)
GetFriendMgr().AddUser(account2Id, user2)
friendship2 := &Friendship{
FriendAccountId: account1Id,
IsFriendship: isFriendship,
RequestTime: requestTime,
}
user2.Friendships[account1Id] = friendship2
GetCacheMgr().LoadUserProfile(account2Id)
}
if user.AccountId == account2Id {
friendUser := NewUser(account1Id)
GetFriendMgr().AddUser(account1Id, friendUser)
friendship := &Friendship{
FriendAccountId: account1Id,
IsFriendship: isFriendship,
RequestTime: requestTime,
}
user.Friendships[account1Id] = friendship
GetCacheMgr().LoadUserProfile(account1Id)
}
}
},
)
}
// loadPendingRequests 加载黑名单列表
func (fm *FriendsMgr) loadBlacklist() {
fields := []string{"account_id", "blocked_account_id"}
where := [][]string{
{"is_removed", "0"},
}
f5.GetJsStyleDb().Select(
constant.FRIEND_DB,
"t_friend_blacklist",
fields,
where,
func(err error, rows *f5.DataSet) {
if err != nil {
return
}
for rows.Next() {
account1Id := q5.ToString(rows.GetByIndex(0))
account2Id := q5.ToString(rows.GetByIndex(1))
friendBlackList := &FriendBlackList{
AccountId: account2Id,
IsRemoved: 0,
}
user := fm.GetUser(account1Id)
user.FriendBlackList[account2Id] = friendBlackList
}
},
)
}
func SwapAccountIds(account1Id, account2Id string) (string, string) {
if strings.Compare(account1Id, account2Id) > 0 {
account1Id, account2Id = account2Id, account1Id
}
return account1Id, account2Id
}

View File

@ -1,368 +0,0 @@
package friend
import (
"cs"
"f5"
"q5"
"sync"
"time"
"main/constant"
"main/common"
. "main/global"
)
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 *common.PlayerProfile)) {
GetCacheMgr().GetProfileByAccountId(accountId, func(err error, profile *common.PlayerProfile) {
if err != nil {
cb(constant.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 []*common.PlayerProfile)) {
var profiles = make([]*common.PlayerProfile, 0, constant.MaxSearchResults)
if len(username) > constant.SearchWord {
cb(constant.ERR_CODE_SEARCH_USERS_SIZE_FULL, "SearchUsers username size full", sinceId, profiles)
return
}
fm.findUsersByUsername(username, sinceId, func(err error, lastId int64, profiles []*common.PlayerProfile) {
if err != nil {
cb(constant.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(constant.ERR_CODE_OK, "AddFriendRequest ok")
return
}
if friendship.IsFriendship == 1 {
cb(constant.ERR_CODE_ALREADY_FRIEND, "Already a friend")
return
}
}
// 好友已满
if fm.GetFriendCount(account1Id) >= constant.MaxFriendMembers || fm.GetFriendCount(account2Id) >= constant.MaxFriendMembers {
cb(constant.ERR_CODE_FRIENDSHIP_IS_FULL, "AddFriendRequest friendship is full")
return
}
// 待请求已满
if fm.GetFriendRequestCount(account1Id) >= constant.MaxPendingFriendReqs ||
fm.GetFriendRequestCount(account2Id) >= constant.MaxPendingFriendReqs {
cb(constant.ERR_CODE_PENDING_REQUEST_IS_FULL, "AddFriendRequest pending request is full")
return
}
requestTime := time.Now().Unix()
fm.upsertFriendShip(account1Id, account2Id, constant.FriendshipStatusPending, requestTime, func(err error) {
if err != nil {
cb(constant.ERR_CODE_UPDATE_FRIENDSHIP_DB_FAIL, "AddFriendRequest update friendship db error")
f5.GetSysLog().Info("AddFriendRequest update friendship db error")
return
}
user1.AddFriendRequest(account2Id, constant.FriendshipStatusPending, requestTime)
user2.AddFriendRequest(account1Id, constant.FriendshipStatusPending, requestTime)
cb(constant.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(constant.ERR_CODE_NO_IN_REQ, "AcceptFriendRequest user2 no in user1 pending request")
return
}
if friendship.IsFriendship != 0 {
cb(constant.ERR_CODE_ALREADY_FRIEND, "Already a friend")
return
}
if fm.GetFriendCount(account1Id) >= constant.MaxFriendMembers || fm.GetFriendCount(account2Id) >= constant.MaxFriendMembers {
cb(constant.ERR_CODE_USERS_IS_FULL, "AcceptFriendRequest users is full")
return
}
requestTime := time.Now().Unix()
fm.upsertFriendShip(account1Id, account2Id, constant.FriendshipStatusOK, requestTime, func(err error) {
if err != nil {
cb(constant.ERR_CODE_UPDATE_FRIENDSHIP_DB_FAIL, "AcceptFriendRequest update friendship db error")
return
}
friendship1 := &Friendship{
FriendAccountId: account2Id,
IsFriendship: constant.FriendshipStatusOK,
RequestTime: time.Now().Unix(),
}
user1.Friendships[account2Id] = friendship1
friendship2 := &Friendship{
FriendAccountId: account1Id,
IsFriendship: constant.FriendshipStatusOK,
RequestTime: time.Now().Unix(),
}
user2.Friendships[account1Id] = friendship2
cb(constant.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(constant.ERR_CODE_USERS_NO_EXISTS, "RejectFriendRequest user no exists")
return
}
friendship, exists := user1.Friendships[account2Id]
if !exists {
cb(constant.ERR_CODE_NO_IN_REQ, "AcceptFriendRequest user2 no in user1 pending request")
return
}
if friendship.IsFriendship == 1 {
cb(constant.ERR_CODE_ALREADY_FRIEND, "Already a friend")
return
}
requestTime := time.Now().Unix()
fm.upsertFriendShip(account2Id, account1Id, constant.FriendshipStatusReject, requestTime, func(err error) {
if err != nil {
cb(constant.ERR_CODE_UPDATE_PENDING_REQUEST_DB_FAIL, "RejectFriendRequest update pending request db error")
return
}
user1.RemoveFriendRequest(account2Id)
user2.RemoveFriendRequest(account1Id)
cb(constant.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(constant.ERR_CODE_USERS_NO_EXISTS, "DeleteFriendShip user no exists")
return
}
friendship, exists := user1.Friendships[account2Id]
if !exists || friendship.IsFriendship != 1 {
cb(constant.ERR_CODE_FRIEND_NO_EXISTS, "DeleteFriendShip user no exists")
return
}
user1.RemoveFriendShip(account2Id)
user2.RemoveFriendShip(account1Id)
updateFields := [][]string{{"is_friendship", q5.ToString(constant.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(constant.ERR_CODE_UPDATE_FRIENDSHIP_DB_FAIL, "DeleteFriendShip update friendship db error")
return
}
cb(constant.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(constant.ERR_CODE_USERS_NO_EXISTS, "AddBlacklist user no exists")
return
}
user2Blocked := User1.GetBlacklist(account2Id)
if user2Blocked != nil && user2Blocked.IsRemoved != 0 {
cb(constant.ERR_CODE_USER_IN_BLACKLIST, "AddBlacklist user in blacklist")
return
}
if User1.GetBlacklistCount() >= constant.MaxBlockedMembers {
cb(constant.ERR_CODE_BLACKLIST_FULL, "AddBlacklist blacklist is full")
return
}
fm.upsertBlacklist(account1Id, account2Id, constant.BlacklistStatusDefault, func(err error) {
if err != nil {
cb(constant.ERR_CODE_UPDATE_BLACKLIST_DB_FAIL, err.Error())
return
}
User1.AddBlacklist(&FriendBlackList{
AccountId: account2Id,
IsRemoved: 0,
})
cb(constant.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(constant.ERR_CODE_USERS_NO_EXISTS, "RemoveBlacklist user no exists")
return
}
user2Blocked := user1.GetBlacklist(account2Id)
if user2Blocked == nil || user2Blocked.IsRemoved == 1 {
cb(constant.ERR_CODE_USER_NOT_IN_BLACKLIST, "RemoveBlacklist user not in blacklist")
return
}
fm.upsertBlacklist(account1Id, account2Id, constant.BlacklistStatusIsRemoved, func(err error) {
if err != nil {
cb(constant.ERR_CODE_UPDATE_BLACKLIST_DB_FAIL, err.Error())
return
}
user1.RemoveBlacklist(account2Id)
cb(constant.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, constant.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)
GetFriendMgr().AddUser(accountId, user)
// 加载我的好友关系表
GetFriendMgr().LoadUserFriendships(user, [][]string{
{"account1_id", user.AccountId},
})
GetFriendMgr().LoadUserFriendships(user, [][]string{
{"account2_id", user.AccountId},
})
// 加载我的黑名单列表
// friendMgr.loadBlacklist(user)
return user
}
return existsUser
}

View File

@ -110,7 +110,9 @@ func (this *matchMgr) execMatch(m *matchingInfo) {
func (this *matchMgr) onMatchOk(m *matchingInfo) {
f5.GetTimer().DeleteRunningTimer()
f5.GetTimer().Delete(m.matchOk.matchTimerWp)
if !m.matchOk.matchTimerWp.Expired() {
f5.GetTimer().Delete(m.matchOk.matchTimerWp)
}
m.team.setMatchOk(m.matchOk.team)
m.matchOk.team.setMatchOk(m.team)

View File

@ -205,7 +205,7 @@ func (this *team) GetMemberNum() int32 {
}
func (this *team) chooseNextLeader() {
nextLeader := this.owner
var nextLeader common.Player
for _, m := range this.memberIdHash {
if nextLeader == nil {
nextLeader = m