game2006go/server/imserver/friendsmgr.go
2023-08-15 14:05:51 +08:00

206 lines
5.4 KiB
Go

package main
import (
"cs"
"errors"
"f5"
"fmt"
"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) searchFriends(usernameKeyword string) []*User {
var results []*User
lowercaseQuery := strings.ToLower(usernameKeyword)
for _, user := range fm.users {
if strings.Contains(strings.ToLower(user.UserName), lowercaseQuery) {
results = append(results, user)
}
}
// Search result save to cached, key: keyword, value: serialization(result), expired: 2days
return results
}
// AddFriendRequest 发送好友请求
func (fm *FriendsMgr) addFriendRequest(user1ID, user2ID string) error {
// Check if users exist
_, exists1 := fm.users[user1ID]
_, exists2 := fm.users[user2ID]
if !exists1 || !exists2 {
return errors.New("users not exist")
}
if fm.pendingReqs[user2ID] == nil {
fm.pendingReqs[user2ID] = make(map[string]bool)
}
fm.pendingReqs[user2ID][user1ID] = true
return nil
}
// AcceptFriendRequest 接受好友请求
func (fm *FriendsMgr) acceptFriendRequest(user1ID, user2ID string) error {
if !fm.pendingReqs[user1ID][user2ID] {
return errors.New("no pending friend request from user1 to user2")
}
// 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)
delete(fm.pendingReqs[user1ID], user2ID)
if len(fm.pendingReqs[user1ID]) == 0 {
delete(fm.pendingReqs, user1ID)
}
return nil
}
// 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)
}
}
fmt.Printf("my 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}
}