diff --git a/database/frienddb.sql b/database/frienddb.sql index 8160fda3..8d8ddfc4 100644 --- a/database/frienddb.sql +++ b/database/frienddb.sql @@ -43,9 +43,6 @@ CREATE TABLE `t_guild` ( `name` varchar(48) NOT NULL, `leader_account_id` varchar(60) NOT NULL, `max_members` int(11) DEFAULT '0', -`level` int(11) DEFAULT '0', -`exp` int(11) DEFAULT '0', -`badge` int(11) DEFAULT '0', `createtime` int(11) NOT NULL DEFAULT '0' COMMENT '创建时间', `modifytime` int(11) NOT NULL DEFAULT '0' COMMENT '修改时间', PRIMARY KEY (`idx`), @@ -56,6 +53,7 @@ drop table if exists t_guild_members; CREATE TABLE `t_guild_members` ( `guild_id` bigint(20) NOT NULL, `account_id` varchar(60) COLLATE utf8_bin NOT NULL, +`level` tinyint 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`), @@ -68,16 +66,15 @@ CREATE TABLE `t_guild_logs` ( `idx` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '自增id', `guild_id` bigint(20) NOT NULL, `account_id` varchar(60) COLLATE utf8_bin NOT NULL, -`log_type` tinyint(4) NOT NULL DEFAULT '0' COMMENT '日志类型', +`log_type` tinyint NOT NULL DEFAULT '0' COMMENT '日志类型', `content` varchar(255) COLLATE utf8_bin NOT NULL DEFAULT '' COMMENT '日志内容', `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 `guild_name` (`guild_id`,`account_id`, log_type), KEY `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` ( `guild_id` bigint(20) NOT NULL, @@ -87,4 +84,4 @@ CREATE TABLE `t_guild_pending_request` ( PRIMARY KEY (`guild_id`,`account_id`), KEY `account_id` (`account_id`), KEY `createtime` (`createtime`) -) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='公会请求申请表' +) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='公会申请表' \ No newline at end of file diff --git a/server/imserver/guild.go b/server/imserver/guild.go index 5356cd2c..d11bc190 100644 --- a/server/imserver/guild.go +++ b/server/imserver/guild.go @@ -9,7 +9,7 @@ type GuildMember struct { } type Guild struct { - ID string + ID int Name string LeaderID string Members []GuildMember @@ -48,39 +48,3 @@ func (g *Guild) RemoveMember(accountId string) error { g.Members = append(g.Members[:index], g.Members[index+1:]...) return nil } - -// PromoteMember 提升成员为干部 -func (g *Guild) PromoteMember(accountId string) error { - if accountId == g.LeaderID { - return errors.New("cannot promote leader") - } - - index := g.findMemberIndex(accountId) - if index == -1 { - return errors.New("member not found") - } - - g.Members[index].Level = 2 - return nil -} - -// DemoteMember 解除成员干部身份 -func (g *Guild) DemoteMember(accountId string) error { - if accountId == g.LeaderID { - return errors.New("cannot demote leader") - } - - index := g.findMemberIndex(accountId) - if index == -1 { - return errors.New("member not found") - } - - g.Members[index].Level = 3 - return nil -} - -// Disband 解散公会 -func (g *Guild) Disband() error { - // 清空成员列表等解散公会 - return nil -} diff --git a/server/imserver/guildmgr.go b/server/imserver/guildmgr.go index 4de386a8..d7640a48 100644 --- a/server/imserver/guildmgr.go +++ b/server/imserver/guildmgr.go @@ -3,34 +3,36 @@ package main import ( "cs" "errors" + "fmt" ) type GuildMgr struct { cs.MsgHandlerImpl - Guilds map[string]*Guild // 公会ID -> 公会列表 - pendingAccountIds map[string][]string // 公会ID -> 申请者账户ID列表 - Logs []string // 公会日志 + Guilds map[int]*Guild // 公会ID -> 公会列表 + pendingAccountIds map[int][]string // 公会ID -> 申请者账户ID列表 + Logs []string // 公会日志 } func NewGuildMgr() *GuildMgr { return &GuildMgr{ - Guilds: make(map[string]*Guild), - pendingAccountIds: make(map[string][]string), + Guilds: make(map[int]*Guild), + pendingAccountIds: make(map[int][]string), Logs: []string{}, } } -// CreateGuild 创建公会 -func (gm *GuildMgr) CreateGuild(name string, leaderID string, maxMembers int) (string, error) { - if maxMembers <= 0 { - return "", errors.New("invalid maxMembers") - } +var guildID = 0 - guildID := "123" +// CreateGuild 创建公会 +func (gm *GuildMgr) CreateGuild(name string, leaderID string, maxMembers int) (int, error) { + if maxMembers <= 0 { + return 0, errors.New("invalid maxMembers") + } if _, exists := gm.Guilds[guildID]; exists { - return "", errors.New("guild already exists") + return 0, errors.New("guild already exists") } + guildID++ newGuild := &Guild{ ID: guildID, @@ -44,37 +46,50 @@ func (gm *GuildMgr) CreateGuild(name string, leaderID string, maxMembers int) (s } // ApplyToGuild 申请加入公会 -func (gm *GuildMgr) ApplyToGuild(guildID string, applicantID string) error { +func (gm *GuildMgr) ApplyToGuild(guildID int, applicantAccountId string) error { if _, exists := gm.Guilds[guildID]; !exists { return errors.New("guild not found") } guild := gm.Guilds[guildID] + // 获取即时人数, 是否需要锁 if len(guild.Members) >= guild.MaxMembers { return errors.New("guild is full") } - gm.pendingAccountIds[guildID] = append(gm.pendingAccountIds[guildID], applicantID) + gm.pendingAccountIds[guildID] = append(gm.pendingAccountIds[guildID], applicantAccountId) return nil } // ApproveApplication 批准申请加入公会 -func (gm *GuildMgr) ApproveApplication(guildID string, applicantID string) error { +func (gm *GuildMgr) ApproveApplication(guildID int, applicantAccountId string) error { guild, exists := gm.Guilds[guildID] if !exists { return errors.New("guild not found") } - applicants, pendingExists := gm.pendingAccountIds[guildID] + for guildId, guild := range gm.Guilds { + for _, member := range guild.Members { + if applicantAccountId == member.AccountId { + errMsg := fmt.Sprintf("Player:%s has joined other guild:%d", applicantAccountId, guildId) + return errors.New(errMsg) + } + } + } + + pendingAccountIds, pendingExists := gm.pendingAccountIds[guildID] if !pendingExists { return errors.New("no pending applications for this guild") } - for i, appID := range applicants { - if appID == applicantID { - newMember := GuildMember{AccountId: applicantID, Username: applicantID, Level: 3} - guild.Members = append(guild.Members, newMember) - gm.pendingAccountIds[guildID] = append(applicants[:i], applicants[i+1:]...) + for i, accountId := range pendingAccountIds { + if accountId == applicantAccountId { + newMember := GuildMember{AccountId: applicantAccountId, Username: applicantAccountId, Level: 3} + err := guild.AddMember(newMember) + if err != nil { + return err + } + gm.pendingAccountIds[guildID] = append(pendingAccountIds[:i], pendingAccountIds[i+1:]...) return nil } } @@ -83,15 +98,15 @@ func (gm *GuildMgr) ApproveApplication(guildID string, applicantID string) error } // RejectApplication 拒绝申请加入公会 -func (gm *GuildMgr) RejectApplication(guildID string, applicantID string) error { - applicants, exists := gm.pendingAccountIds[guildID] +func (gm *GuildMgr) RejectApplication(guildID int, applicantAccountId string) error { + pendingAccountIds, exists := gm.pendingAccountIds[guildID] if !exists { return errors.New("no pending applications for this guild") } - for i, appID := range applicants { - if appID == applicantID { - gm.pendingAccountIds[guildID] = append(applicants[:i], applicants[i+1:]...) + for i, accountId := range pendingAccountIds { + if accountId == applicantAccountId { + gm.pendingAccountIds[guildID] = append(pendingAccountIds[:i], pendingAccountIds[i+1:]...) return nil } } @@ -100,7 +115,7 @@ func (gm *GuildMgr) RejectApplication(guildID string, applicantID string) error } // JoinGuild 加入公会 -func (gm *GuildMgr) JoinGuild(guildID, memberID string) error { +func (gm *GuildMgr) JoinGuild(guildID int, memberID string) error { guild, exists := gm.Guilds[guildID] if !exists { return errors.New("guild not found") @@ -116,7 +131,7 @@ func (gm *GuildMgr) JoinGuild(guildID, memberID string) error { } // LeaveGuild 离开公会 -func (gm *GuildMgr) LeaveGuild(guildID string, memberID string) error { +func (gm *GuildMgr) LeaveGuild(guildID int, memberID string) error { guild, exists := gm.Guilds[guildID] if !exists { return errors.New("guild not found") @@ -133,7 +148,7 @@ func (gm *GuildMgr) LeaveGuild(guildID string, memberID string) error { } // DismissMember 开除成员 -func (gm *GuildMgr) DismissMember(guildID string, memberID string) error { +func (gm *GuildMgr) DismissMember(guildID int, memberID string) error { guild, exists := gm.Guilds[guildID] if !exists { return errors.New("guild not found") @@ -154,7 +169,7 @@ func (gm *GuildMgr) DismissMember(guildID string, memberID string) error { } // PromoteMember 提升成员为干部 -func (gm *GuildMgr) PromoteMember(guildID string, memberID string) error { +func (gm *GuildMgr) PromoteMember(guildID int, memberID string) error { guild, exists := gm.Guilds[guildID] if !exists { return errors.New("guild not found") @@ -175,7 +190,7 @@ func (gm *GuildMgr) PromoteMember(guildID string, memberID string) error { } // DemoteMember 解除成员干部身份 -func (gm *GuildMgr) DemoteMember(guildID string, memberID string) error { +func (gm *GuildMgr) DemoteMember(guildID int, memberID string) error { guild, exists := gm.Guilds[guildID] if !exists { return errors.New("guild not found") @@ -226,6 +241,27 @@ func (gm *GuildMgr) RandomGuilds() []Guild { return nil } +func (gm *GuildMgr) Disband(guildID int, accountId string) error { + guild, exists := gm.Guilds[guildID] + if !exists { + return errors.New("guild not found") + } + + if accountId != guild.LeaderID { + return errors.New("cannot disband guild") + } + + guildName := guild.Name + guild.Members = nil + delete(gm.pendingAccountIds, guildID) + delete(gm.Guilds, guildID) + + // Write log about the guild disbandment + gm.WriteLog("Guild disbanded: " + guildName) + + return nil +} + func containsSubstring(s, substr string) bool { return len(s) >= len(substr) && s[len(s)-len(substr):] == substr } diff --git a/server/imserver/guildmgr_test.go b/server/imserver/guildmgr_test.go index 39ef256e..e0c11c83 100644 --- a/server/imserver/guildmgr_test.go +++ b/server/imserver/guildmgr_test.go @@ -6,13 +6,11 @@ import ( ) func TestGuild(t *testing.T) { - // Test the basic functionality guildMgr := NewGuildMgr() + leaderID := "apple" + memberID := "sony" - leaderID := "leader_account_id" - memberID := "member_account_id" - - guildID, err := guildMgr.CreateGuild("Awesome Guild", leaderID, 10) + guildID, err := guildMgr.CreateGuild("GuildWorld", leaderID, 10) if err != nil { fmt.Println("Error:", err) return