game2006go/server/imserver/friendsmgr.go
2023-08-15 14:46:12 +08:00

233 lines
6.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package main
import (
"cs"
"f5"
"mt"
"q5"
"strings"
)
type FriendsMgr struct {
cs.MsgHandlerImpl
users map[string]*User
friendships map[string][]*Friendship
pendingReqs map[string]map[string]bool
}
func (fm *FriendsMgr) init() {
// init gameDB
gameDBStore := q5.NewMysql(
mt.Table.GameDb.GetById(0).GetHost(),
mt.Table.GameDb.GetById(0).GetPort(),
mt.Table.GameDb.GetById(0).GetUser(),
mt.Table.GameDb.GetById(0).GetPasswd(),
mt.Table.GameDb.GetById(0).GetDatabase(),
)
gameDBStore.Open()
fm.loadUsersFromDB(gameDBStore)
// init friendDB
friendDBStore := q5.NewMysql(
mt.Table.FriendDb.GetById(0).GetHost(),
mt.Table.FriendDb.GetById(0).GetPort(),
mt.Table.FriendDb.GetById(0).GetUser(),
mt.Table.FriendDb.GetById(0).GetPasswd(),
mt.Table.FriendDb.GetById(0).GetDatabase(),
)
friendDBStore.Open()
// 加载好友关系表 列表
fm.loadFriendshipsFromDB(friendDBStore)
// 加载等待验证好友请求 列表
fm.loadPendingRequestsFromDB(friendDBStore)
}
func (fm *FriendsMgr) unInit() {
// 1. Loop struct data
// 2. Struct Data Persist to DB
}
func (fm *FriendsMgr) CMSearchFriends(hdr *f5.MsgHdr, msg *cs.CMSearchFriend) {
searchKeyword := msg.GetSearchKeyword()
listFriend := &cs.SMSearchFriend{}
lowercaseQuery := strings.ToLower(searchKeyword)
for _, user := range fm.users {
if strings.Contains(strings.ToLower(user.UserName), lowercaseQuery) {
friend := &cs.MFFriend{
AccountId: &user.AccountId,
Username: &user.UserName,
}
listFriend.Friends = append(listFriend.Friends, friend)
}
}
f5.GetSysLog().Info("CMSearchFriends search result:%d\n", len(listFriend.Friends))
// By default, Search result save to redis..., key: search keyword, value: serialization(search result), expired: 2days
wspListener.sendProxyMsg(hdr.Conn, hdr.SocketHandle, listFriend)
}
// CMAddFriendRequest 发送好友请求
func (fm *FriendsMgr) CMAddFriendRequest(hdr *f5.MsgHdr, msg *cs.CMAddFriendRequest) {
response := &cs.SMAddFriendRequest{}
user1Id := msg.GetAccountId()
user2Id := msg.GetAccount2Id()
// Check if users exist
_, exists1 := fm.users[user1Id]
_, exists2 := fm.users[user2Id]
if !exists1 || !exists2 {
reason := "users not exist"
response.Reason = &reason
wspListener.sendProxyMsg(hdr.Conn, hdr.SocketHandle, response)
f5.GetSysLog().Info("CMAddFriendRequest: reason:%s, params: %s or %s\n", reason, user1Id, user2Id)
return
}
// 为 user2 创建等待验证好友请求 记录由userid1 申请的
if fm.pendingReqs[user2Id] == nil {
fm.pendingReqs[user2Id] = make(map[string]bool)
}
fm.pendingReqs[user2Id][user1Id] = true
status := "pending"
response.Status = &status
wspListener.sendProxyMsg(hdr.Conn, hdr.SocketHandle, response)
}
// CMAcceptFriendRequest 接受好友请求
func (fm *FriendsMgr) CMAcceptFriendRequest(hdr *f5.MsgHdr, msg *cs.CMAcceptFriendRequest) {
response := &cs.SMAcceptFriendRequest{}
user1Id := msg.GetAccountId()
user2Id := msg.GetAccount2Id()
if !fm.pendingReqs[user1Id][user2Id] {
reason := "no pending friend request from user1 to user2"
response.Reason = &reason
wspListener.sendProxyMsg(hdr.Conn, hdr.SocketHandle, response)
f5.GetSysLog().Info("CMAcceptFriendRequest: reason:%s, params: %s or %s\n", reason, user1Id, user2Id)
return
}
// Create a new friendship
friendship := &Friendship{
User1: fm.users[user1Id],
User2: fm.users[user2Id],
}
fm.friendships[user1Id] = append(fm.friendships[user1Id], friendship)
fm.friendships[user2Id] = append(fm.friendships[user2Id], friendship)
// step1. delete db record
// step2. add friend history to db
delete(fm.pendingReqs[user1Id], user2Id)
if len(fm.pendingReqs[user1Id]) == 0 {
delete(fm.pendingReqs, user1Id)
}
status := "approved"
response.Status = &status
wspListener.sendProxyMsg(hdr.Conn, hdr.SocketHandle, response)
}
// CMListFriend 我的好友列表
func (fm *FriendsMgr) CMListFriend(hdr *f5.MsgHdr, msg *cs.CMListFriend) {
myAccountId := msg.GetAccountId()
listFriend := &cs.SMListFriend{}
for _, friendship := range fm.friendships[myAccountId] {
if friendship.User1.AccountId != myAccountId {
friend := &cs.MFFriend{
AccountId: &friendship.User1.AccountId,
Username: &friendship.User1.UserName,
}
listFriend.Friends = append(listFriend.Friends, friend)
} else {
friend := &cs.MFFriend{
AccountId: &friendship.User2.AccountId,
Username: &friendship.User2.UserName,
}
listFriend.Friends = append(listFriend.Friends, friend)
}
}
f5.GetSysLog().Info("CMListFriend friends count:%d\n", len(listFriend.Friends))
wspListener.sendProxyMsg(hdr.Conn, hdr.SocketHandle, listFriend)
}
func (fm *FriendsMgr) loadUsersFromDB(conn *q5.Mysql) {
// Load DB users to struct FriendsMgr.user
rows, err := conn.Query("select account_id, name from t_user")
if err != nil {
f5.GetSysLog().Info("mysql error", err)
return
}
fm.users = make(map[string]*User)
for rows.Next() {
user := &User{}
err := rows.Scan(&user.AccountId, &user.UserName)
if err != nil {
continue
}
fm.users[user.AccountId] = user
}
}
func (fm *FriendsMgr) loadFriendshipsFromDB(conn *q5.Mysql) {
// Load DB t_friend_ships to struct FriendsMgr.friendship
rows, err := conn.Query("select account1_id, account2_id from t_friend_ships;")
if err != nil {
f5.GetSysLog().Info("mysql error", err)
return
}
fm.friendships = make(map[string][]*Friendship)
for rows.Next() {
user1 := &User{}
user2 := &User{}
err := rows.Scan(&user1.AccountId, &user2.AccountId)
if err != nil {
continue
}
friendship := &Friendship{}
friendship.User1 = user1
friendship.User2 = user2
fm.addFriendshipToMap(user1.AccountId, friendship)
fm.addFriendshipToMap(user2.AccountId, friendship)
}
}
func (fm *FriendsMgr) loadPendingRequestsFromDB(conn *q5.Mysql) {
rows, err := conn.Query("select sender_account_id, receiver_account_id from t_pending_friend_requests;")
if err != nil {
f5.GetSysLog().Info("mysql error", err)
return
}
pendingReqs := make(map[string]map[string]bool)
for rows.Next() {
var senderAccountId, receiverAccountId string
if err := rows.Scan(&senderAccountId, &receiverAccountId); err != nil {
continue
}
if pendingReqs[senderAccountId] == nil {
pendingReqs[senderAccountId] = make(map[string]bool)
}
pendingReqs[senderAccountId][receiverAccountId] = true
}
if err := rows.Err(); err != nil {
return
}
fm.pendingReqs = pendingReqs
}
func (fm *FriendsMgr) addFriendshipToMap(accountID string, friendship *Friendship) {
if fm.friendships[accountID] == nil {
fm.friendships[accountID] = []*Friendship{friendship}
} else {
fm.friendships[accountID] = append(fm.friendships[accountID], friendship)
}
}
func (fm *FriendsMgr) RegisterUser(accountId string, username string) {
fm.users[accountId] = &User{AccountId: accountId, UserName: username}
}