From 651f9ba3128bd889736b2fa3ba0a877ba07a6ee9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=AE=B7=E5=8B=87?= Date: Mon, 21 Aug 2023 16:43:48 +0800 Subject: [PATCH] =?UTF-8?q?=E5=85=AC=E4=BC=9A=E5=8A=A0=E8=BD=BD=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=BA=93=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- database/frienddb.sql | 34 ++++-- server/imserver/app.go | 8 +- server/imserver/export.go | 3 + server/imserver/friendsmgr.go | 6 ++ server/imserver/guild.go | 8 +- server/imserver/guildmgr.go | 193 +++++++++++++++++++++++++--------- server/imserver/playermgr.go | 2 +- 7 files changed, 184 insertions(+), 70 deletions(-) diff --git a/database/frienddb.sql b/database/frienddb.sql index 9ee45af7..47498d37 100644 --- a/database/frienddb.sql +++ b/database/frienddb.sql @@ -36,29 +36,43 @@ PRIMARY KEY (`idx`), UNIQUE KEY `friend_req` (`sender_account_id`,`receiver_account_id`) ) COMMENT "等待验证的好友请求"; +CREATE TABLE `t_friend_blocked` ( +`idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id', +`account_id` varchar(60) COLLATE utf8_bin NOT NULL, +`blocked_account_id` varchar(60) COLLATE utf8_bin NOT NULL, +`createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', +`modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', +PRIMARY KEY (`idx`), +UNIQUE KEY `blocked_friend` (`account_id`,`blocked_account_id`) +) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='好友黑名单'; + -- 公会相关 -- drop table if exists t_guild; CREATE TABLE `t_guild` ( `idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id', +`guild_id` bigint(20) NOT NULL DEFAULT '0' COMMENT '公会id', `name` varchar(48) NOT NULL, `leader_account_id` varchar(60) NOT NULL, `max_members` int(11) DEFAULT '0', `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', PRIMARY KEY (`idx`), -UNIQUE KEY `guild_name` (`name`,`leader_account_id`) +UNIQUE KEY `idx_guild_id` (`guild_id`), +KEY `idx_guild_name` (name), +KEY `idx_guild_leader` (leader_account_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='公会表'; drop table if exists `t_guild_members`; CREATE TABLE `t_guild_members` ( +`idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id', `guild_id` bigint(20) NOT NULL, `account_id` varchar(60) COLLATE utf8_bin NOT NULL, `level` tinyint(4) DEFAULT '0' COMMENT '成员阶级1会长,2干部,3群众', `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', -PRIMARY KEY (`guild_id`,`account_id`), -KEY `idx_account_id` (`account_id`), -KEY `createtime` (`createtime`) +PRIMARY KEY (`idx`), +UNIQUE KEY `idx_guild_members` (`guild_id`,`account_id`), +KEY `idx_account_id` (`account_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='公会成员表'; drop table if exists `t_guild_logs`; @@ -71,17 +85,19 @@ CREATE TABLE `t_guild_logs` ( `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', PRIMARY KEY (`idx`), -KEY `guild_name` (`guild_id`,`account_id`, log_type), -KEY `createtime` (`createtime`) +KEY `idx_guild_log` (`guild_id`,log_type, `account_id`), +KEY `idx_createtime` (`createtime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='公会日志表'; drop table if exists `t_guild_pending_request`; CREATE TABLE `t_guild_pending_request` ( +`idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id', `guild_id` bigint(20) NOT NULL, `account_id` varchar(60) COLLATE utf8_bin NOT NULL, `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', -PRIMARY KEY (`guild_id`,`account_id`), -KEY `account_id` (`account_id`), -KEY `createtime` (`createtime`) +PRIMARY KEY (`idx`), +UNIQUE KEY `idx_guild_pending_request`(`guild_id`,`account_id`), +KEY `idx_account_id` (`account_id`), +KEY `idx_createtime` (`createtime`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='公会申请表' \ No newline at end of file diff --git a/server/imserver/app.go b/server/imserver/app.go index d9090a93..303ed2af 100644 --- a/server/imserver/app.go +++ b/server/imserver/app.go @@ -2,10 +2,10 @@ package main import ( "cs" - "ss" "f5" "mt" "q5" + "ss" ) type App struct { @@ -24,6 +24,7 @@ func (this *App) Init() { handlerMgr.init() playerMgr.init() friendMgr.init() + guildMgr.init() wspListener.init() httpListener.init() } @@ -73,9 +74,8 @@ func (this *App) addNetMsg(hdr *f5.MsgHdr) { f5.GetApp().NotifyLoopCond() } - func (this *App) registerDataSources() { - f5.GetGoStyleDb().RegisterDataSource( + f5.GetJsStyleDb().RegisterDataSource( GAME_DB, mt.Table.GameDb.GetById(0).GetHost(), mt.Table.GameDb.GetById(0).GetPort(), @@ -83,7 +83,7 @@ func (this *App) registerDataSources() { mt.Table.GameDb.GetById(0).GetPasswd(), mt.Table.GameDb.GetById(0).GetDatabase(), 30) - f5.GetGoStyleDb().RegisterDataSource( + f5.GetJsStyleDb().RegisterDataSource( FRIEND_DB, mt.Table.FriendDb.GetById(0).GetHost(), mt.Table.FriendDb.GetById(0).GetPort(), diff --git a/server/imserver/export.go b/server/imserver/export.go index a7566f3c..05a0c3b4 100644 --- a/server/imserver/export.go +++ b/server/imserver/export.go @@ -6,3 +6,6 @@ var playerMgr = new(PlayerMgr) var handlerMgr = new(HandlerMgr) var httpListener = new(HttpListener) var friendMgr = new(FriendsMgr) + +// var guildMgr = new(GuildMgr) +var guildMgr = NewGuildMgr() diff --git a/server/imserver/friendsmgr.go b/server/imserver/friendsmgr.go index 97660c94..4e0a4bec 100644 --- a/server/imserver/friendsmgr.go +++ b/server/imserver/friendsmgr.go @@ -8,16 +8,19 @@ import ( "mt" "q5" "strings" + "sync" "time" ) const ( FriendMemberCount = 200 PendingReqCount = 20 + BlockedUserCount = 50 ) type FriendsMgr struct { cs.MsgHandlerImpl + mu sync.RWMutex users map[string]*User // AccountId -> 用户 searchCaches map[string]SearchCache // SearchKeyword -> 好友搜索结果 []*User friendships map[string][]*Friendship // AccountId -> 好友关系列表 []*Friendship @@ -251,6 +254,9 @@ func (fm *FriendsMgr) rejectFriendRequest(account1Id string, account2Id string) // deleteFriendShip 删除好友 func (fm *FriendsMgr) deleteFriendShip(account1ID, account2ID string) error { + fm.mu.Lock() + defer fm.mu.Unlock() + user1Friendships := fm.friendships[account1ID] user2Friendships := fm.friendships[account2ID] diff --git a/server/imserver/guild.go b/server/imserver/guild.go index 4b21c4b8..4c644771 100644 --- a/server/imserver/guild.go +++ b/server/imserver/guild.go @@ -8,14 +8,14 @@ type GuildMember struct { } type Guild struct { - ID int + GuildId int64 Name string LeaderID string Members []GuildMember MaxMembers int } type GuildLog struct { - GuildId int + GuildId int64 AccountId string LogType uint16 Content string @@ -41,11 +41,11 @@ func (g *Guild) GetMember(accountId string) (*GuildMember, error) { } // AddMember 添加成员 -func (g *Guild) AddMember(member GuildMember) error { +func (g *Guild) AddMember(member *GuildMember) error { if len(g.Members) >= g.MaxMembers { return errors.New("guild is full") } - g.Members = append(g.Members, member) + g.Members = append(g.Members, *member) return nil } diff --git a/server/imserver/guildmgr.go b/server/imserver/guildmgr.go index 2d2e168a..db573c30 100644 --- a/server/imserver/guildmgr.go +++ b/server/imserver/guildmgr.go @@ -3,67 +3,117 @@ package main import ( "cs" "errors" + "f5" "fmt" "math/rand" + "q5" ) type GuildMgr struct { cs.MsgHandlerImpl - Guilds map[int]*Guild // 公会ID -> 公会列表 - PendingAccountIds map[int][]string // 公会ID -> 申请者账户ID列表 - Logs map[int][]*GuildLog // 公会ID -> 公会日志 + Guilds map[int64]*Guild // 公会ID -> 公会列表 + PendingAccountIds map[int64][]string // 公会ID -> 申请者账户ID列表 + Logs map[int64][]*GuildLog // 公会ID -> 公会日志 } func NewGuildMgr() *GuildMgr { return &GuildMgr{ - Guilds: make(map[int]*Guild), - PendingAccountIds: make(map[int][]string), - Logs: make(map[int][]*GuildLog), + Guilds: make(map[int64]*Guild), + PendingAccountIds: make(map[int64][]string), + Logs: make(map[int64][]*GuildLog), } } -var guildID = 0 +func (gm *GuildMgr) init() { + // 加载公会 + gm.loadGuildFromDB() + // 加载公会成员 + gm.loadGuildMemberFromDB() +} + +func (gm *GuildMgr) loadGuildFromDB() { + fields := []string{"guild_id", "name", "leader_account_id", "max_members"} + f5.GetJsStyleDb().Select( + FRIEND_DB, + "t_guild", + fields, + [][]string{}, + gm.loadGuildFromDBResult, + ) +} + +func (gm *GuildMgr) loadGuildFromDBResult(err error, rows *f5.DataSet) { + if err != nil { + fmt.Printf("loadGuildFromDBResult err:%v \n", err) + return + } + for rows.Next() { + var ( + guildId int64 + name string + leaderAccountId string + maxMembers int + ) + guildId = q5.ToInt64(*rows.GetByIndex(0)) + name = q5.ToString(*rows.GetByIndex(1)) + leaderAccountId = q5.ToString(*rows.GetByIndex(2)) + maxMembers = int(q5.ToInt32(*rows.GetByIndex(3))) + + newGuild := &Guild{ + GuildId: guildId, + Name: name, + LeaderID: leaderAccountId, + MaxMembers: maxMembers, + } + // push to gm.guilds + gm.Guilds[guildId] = newGuild + } + + fmt.Printf("loadGuildFromDB %v, len:%d\n", gm.Guilds, len(gm.Guilds)) + fmt.Printf("loadGuildFromDB Finished") +} // CreateGuild 创建公会 -func (gm *GuildMgr) CreateGuild(name string, leaderID string, maxMembers int) (int, error) { +func (gm *GuildMgr) CreateGuild(name string, leaderID string, maxMembers int) (int64, error) { + guildId := f5.GetApp().NewUuid() + if maxMembers <= 0 { return 0, errors.New("invalid maxMembers") } - if _, exists := gm.Guilds[guildID]; exists { + if _, exists := gm.Guilds[guildId]; exists { return 0, errors.New("guild already exists") } - guildID++ newGuild := &Guild{ - ID: guildID, + GuildId: guildId, Name: name, LeaderID: leaderID, MaxMembers: maxMembers, } - gm.Guilds[guildID] = newGuild - return guildID, nil + gm.Guilds[guildId] = newGuild + return guildId, nil } // ApplyToGuild 申请加入公会 -func (gm *GuildMgr) ApplyToGuild(guildID int, applicantAccountId string) error { - if _, exists := gm.Guilds[guildID]; !exists { +func (gm *GuildMgr) ApplyToGuild(guildId int64, applicantAccountId string) error { + if _, exists := gm.Guilds[guildId]; !exists { return errors.New("guild not found") } - guild := gm.Guilds[guildID] + guild := gm.Guilds[guildId] if len(guild.Members) >= guild.MaxMembers { return errors.New("guild is full") } - gm.PendingAccountIds[guildID] = append(gm.PendingAccountIds[guildID], applicantAccountId) + gm.PendingAccountIds[guildId] = append(gm.PendingAccountIds[guildId], applicantAccountId) return nil } // ApproveApplication 批准申请加入公会 -func (gm *GuildMgr) ApproveApplication(guildID int, applicantAccountId string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) ApproveApplication(guildId int64, applicantAccountId string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -77,7 +127,7 @@ func (gm *GuildMgr) ApproveApplication(guildID int, applicantAccountId string) e } } - pendingAccountIds, pendingExists := gm.PendingAccountIds[guildID] + pendingAccountIds, pendingExists := gm.PendingAccountIds[guildId] if !pendingExists { return errors.New("no pending applications for this guild") } @@ -85,11 +135,11 @@ func (gm *GuildMgr) ApproveApplication(guildID int, applicantAccountId string) e for i, accountId := range pendingAccountIds { if accountId == applicantAccountId { newMember := GuildMember{AccountId: applicantAccountId, Level: 3} - err := guild.AddMember(newMember) + err := guild.AddMember(&newMember) if err != nil { return err } - gm.PendingAccountIds[guildID] = append(pendingAccountIds[:i], pendingAccountIds[i+1:]...) + gm.PendingAccountIds[guildId] = append(pendingAccountIds[:i], pendingAccountIds[i+1:]...) return nil } } @@ -98,15 +148,15 @@ func (gm *GuildMgr) ApproveApplication(guildID int, applicantAccountId string) e } // RejectApplication 拒绝申请加入公会 -func (gm *GuildMgr) RejectApplication(guildID int, applicantAccountId string) error { - pendingAccountIds, exists := gm.PendingAccountIds[guildID] +func (gm *GuildMgr) RejectApplication(guildId int64, applicantAccountId string) error { + pendingAccountIds, exists := gm.PendingAccountIds[guildId] if !exists { return errors.New("no pending applications for this guild") } for i, accountId := range pendingAccountIds { if accountId == applicantAccountId { - gm.PendingAccountIds[guildID] = append(pendingAccountIds[:i], pendingAccountIds[i+1:]...) + gm.PendingAccountIds[guildId] = append(pendingAccountIds[:i], pendingAccountIds[i+1:]...) return nil } } @@ -115,8 +165,8 @@ func (gm *GuildMgr) RejectApplication(guildID int, applicantAccountId string) er } // JoinGuild 可直接加入公会 -func (gm *GuildMgr) JoinGuild(guildID int, memberID string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) JoinGuild(guildId int64, memberID string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -131,8 +181,8 @@ func (gm *GuildMgr) JoinGuild(guildID int, memberID string) error { } // LeaveGuild 离开公会 -func (gm *GuildMgr) LeaveGuild(guildID int, memberID string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) LeaveGuild(guildId int64, memberID string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -151,8 +201,8 @@ func (gm *GuildMgr) LeaveGuild(guildID int, memberID string) error { } // DismissMember 开除成员 踢出 -func (gm *GuildMgr) DismissMember(guildID int, operatorAccountId, memberID string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) DismissMember(guildId int64, operatorAccountId, memberID string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -183,8 +233,8 @@ func (gm *GuildMgr) DismissMember(guildID int, operatorAccountId, memberID strin } // PromoteMember 提升成员为干部 -func (gm *GuildMgr) PromoteMember(guildID int, memberID string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) PromoteMember(guildId int64, memberID string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -204,8 +254,8 @@ func (gm *GuildMgr) PromoteMember(guildID int, memberID string) error { } // DemoteMember 解除成员干部身份 -func (gm *GuildMgr) DemoteMember(guildID int, memberID string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) DemoteMember(guildId int64, memberID string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -225,23 +275,23 @@ func (gm *GuildMgr) DemoteMember(guildID int, memberID string) error { } // WriteLog 记录公会日志 -func (gm *GuildMgr) WriteLog(guildID int, accountId string, logType uint16, content string) { - _, exists := gm.Logs[guildID] +func (gm *GuildMgr) WriteLog(guildId int64, accountId string, logType uint16, content string) { + _, exists := gm.Logs[guildId] if !exists { - gm.Logs[guildID] = make([]*GuildLog, 0) + gm.Logs[guildId] = make([]*GuildLog, 0) } log := &GuildLog{ - GuildId: guildID, + GuildId: guildId, AccountId: accountId, LogType: logType, Content: content, } - gm.Logs[guildID] = append(gm.Logs[guildID], log) + gm.Logs[guildId] = append(gm.Logs[guildId], log) } // Disband 解散公会 -func (gm *GuildMgr) Disband(guildID int, accountId string) error { - guild, exists := gm.Guilds[guildID] +func (gm *GuildMgr) Disband(guildId int64, accountId string) error { + guild, exists := gm.Guilds[guildId] if !exists { return errors.New("guild not found") } @@ -253,16 +303,16 @@ func (gm *GuildMgr) Disband(guildID int, accountId string) error { guildName := guild.Name guild.Members = nil - gm.Guilds[guildID] = nil - gm.PendingAccountIds[guildID] = nil - gm.Logs[guildID] = nil + gm.Guilds[guildId] = nil + gm.PendingAccountIds[guildId] = nil + gm.Logs[guildId] = nil // 确保在删除之前没有其他地方引用了公会对象的指针, 以避免空指针异常 - delete(gm.Guilds, guildID) - delete(gm.PendingAccountIds, guildID) - delete(gm.Logs, guildID) + delete(gm.Guilds, guildId) + delete(gm.PendingAccountIds, guildId) + delete(gm.Logs, guildId) - gm.WriteLog(guildID, accountId, 1, "Guild disbanded: "+guildName) + gm.WriteLog(guildId, accountId, 1, "Guild disbanded: "+guildName) return nil } @@ -288,8 +338,8 @@ func (gm *GuildMgr) RandomGuilds() []Guild { // shuffle 从count50,返回一个slice []int, 包含10个元素 randIndices := rand.Perm(count)[:randomGuildNum] var results []Guild - for _, idx := range randIndices { - results = append(results, *gm.Guilds[idx]) + for _, randId := range randIndices { + results = append(results, *gm.Guilds[q5.ToInt64(randId)]) } return results } @@ -312,7 +362,7 @@ func (gm *GuildMgr) Info(accountId string) (*Guild, []string, []*GuildLog) { pendingAccountIds := make([]string, 10) guildLogs := make([]*GuildLog, 10) if guild != nil { - guildId := guild.ID + guildId := guild.GuildId pendingAccountIds = gm.PendingAccountIds[guildId] guildLogs = gm.Logs[guildId] } @@ -323,3 +373,42 @@ func (gm *GuildMgr) Info(accountId string) (*Guild, []string, []*GuildLog) { func containsSubstring(s, substr string) bool { return len(s) >= len(substr) && s[len(s)-len(substr):] == substr } + +func (gm *GuildMgr) loadGuildMemberFromDB() { + fields := []string{"guild_id", "account_id", "level"} + f5.GetJsStyleDb().Select( + FRIEND_DB, + "t_guild_members", + fields, + [][]string{}, + gm.loadGuildMemberFromDBResult, + ) +} + +func (gm *GuildMgr) loadGuildMemberFromDBResult(err error, rows *f5.DataSet) { + if err != nil { + fmt.Printf("loadGuildFromDBResult err:%v \n", err) + return + } + for rows.Next() { + var ( + guildId int64 + accountId string + level int + ) + guildId = q5.ToInt64(*rows.GetByIndex(0)) + accountId = q5.ToString(*rows.GetByIndex(1)) + level = int(q5.ToInt32(*rows.GetByIndex(2))) + + guildMember := &GuildMember{ + AccountId: accountId, + Level: level, + } + if guild, ok := gm.Guilds[guildId]; ok { + err := guild.AddMember(guildMember) + if err != nil { + f5.GetSysLog().Info("Guild:%d member is full\n", guildId) + } + } + } +} diff --git a/server/imserver/playermgr.go b/server/imserver/playermgr.go index 25794b3c..02d17a26 100644 --- a/server/imserver/playermgr.go +++ b/server/imserver/playermgr.go @@ -59,7 +59,7 @@ func (this *PlayerMgr) init() { "t_user", [][]string{ []string{"account_id", "100"}}, - func (err error, row *[]*string) { + func(err error, row *f5.DataSet) { fmt.Println(row) }) }