206 lines
5.4 KiB
Go
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}
|
|
}
|