233 lines
6.7 KiB
Go
233 lines
6.7 KiB
Go
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}
|
||
}
|