game2006go/server/imserver/guildmgr.go
2023-09-19 15:49:25 +08:00

1037 lines
28 KiB
Go

package main
import (
"cs"
"f5"
"fmt"
"math/rand"
"q5"
"sort"
"time"
)
const (
LoadGuildFlag = iota
LoadGuildMemberFlag
LoadGuildReqFlag
LoadGuildLogFlag
)
type GuildMgr struct {
cs.MsgHandlerImpl
guilds map[int64]*Guild // 公会ID -> 公会
guildIds []int64 // 公会列表 guildIds
guildLogs map[int64][]*GuildLog // 公会ID -> []公会日志列表
userGuilds map[string]int64 // accountId -> 公会ID
loadedFlags int64
}
func NewGuildMgr() *GuildMgr {
return &GuildMgr{
guilds: make(map[int64]*Guild),
guildLogs: make(map[int64][]*GuildLog),
userGuilds: make(map[string]int64),
}
}
func (gm *GuildMgr) init() {
gm.guildIds = make([]int64, 0, 200)
gm.loadFromDB()
}
func (gm *GuildMgr) loadFromDB() {
q5.SetBitFlag(&gm.loadedFlags, LoadGuildFlag)
q5.SetBitFlag(&gm.loadedFlags, LoadGuildMemberFlag)
q5.SetBitFlag(&gm.loadedFlags, LoadGuildReqFlag)
q5.SetBitFlag(&gm.loadedFlags, LoadGuildLogFlag)
// 加载公会
gm.loadGuildFromDB()
// 加载公会成员
gm.loadGuildMemberFromDB()
// 加载公会申请者列表
gm.loadPendingReqsFromDB()
// 加载公会日志
gm.loadGuildLogsFromDB()
//for gm.loadedFlags != 0 {
// time.Sleep(time.Millisecond * 1000)
//}
}
// CreateGuild 创建公会
func (gm *GuildMgr) CreateGuild(avatar int32, name *string, leaderId string,
cb func(errCode int32, errMsg string, guild *Guild)) {
if gm.CheckJoinGuild(leaderId) {
cb(ERR_CODE_JOINED_GUILD, "Joined guild", nil)
return
}
guildId := f5.GetApp().NewUuid()
if gm.ExistsGuild(guildId) {
cb(ERR_CODE_CREATE_GUILD_FAIL, "create error ", nil)
return
}
unixSec := time.Now().Unix()
fields := [][]string{
{"guild_id", q5.ToString(guildId)},
{"name", *name},
{"leader_account_id", leaderId},
{"avatar", q5.ToString(avatar)},
{"max_members", q5.ToString(MaxMembers)},
{"createtime", q5.ToString(unixSec)},
{"modifytime", q5.ToString(unixSec)},
}
f5.GetJsStyleDb().Insert(
FRIEND_DB,
"t_guild",
fields,
func(err error, id int64, affectedRows int64) {
if err != nil {
cb(ERR_CODE_CREATE_GUILD_DB_FAIL, "create guild db error ", nil)
return
}
newMember := &GuildMember{AccountId: leaderId, Level: GuildMemberLevelLeader}
gm.upsertGuildMember(guildId, newMember,
func(err error) {
if err != nil {
cb(ERR_CODE_CREATE_GUILD_MEMBER_DB_FAIL, "create guild member db error", nil)
return
}
guild := &Guild{
AutoId: id,
GuildId: guildId,
Name: *name,
LeaderId: leaderId,
Avatar: avatar,
Notice: "",
JoinCond: 0,
JoinCondValue: 0,
TotalStars: 0,
TotalKills: 0,
ChickenDinners: 0,
MaxMembers: MaxMembers,
PendingReqs: make(map[string]int32, MaxPendingReqs),
}
guild.AddMember(newMember)
gm.AddGuild(guildId, guild)
gm.AddUserGuild(leaderId, guildId)
// Add event
prop := make(map[string]string)
prop["auto_id"] = q5.ToString(id)
prop["guild_id"] = q5.ToString(guildId)
prop["guild_name"] = *name
f5.GetTgLog().AddTrackLog(
GAME_ID,
leaderId,
"127.0.0.1",
EVENT_CREATE,
prop,
)
cb(ERR_CODE_OK, "Create OK", guild)
})
})
}
// ApplyToGuild 申请加入公会
func (gm *GuildMgr) ApplyToGuild(guildId int64, applicantAccountId string, cb func(errCode int32, errMsg string)) {
guild := gm.GetGuild(guildId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "ApplyToGuild guild no exists")
return
}
// 是否加入其他公会
if gm.CheckJoinGuild(applicantAccountId) {
cb(ERR_CODE_JOINED_GUILD, "ApplyToGuild joined guild")
return
}
if guild.IsFull() {
cb(ERR_CODE_GUILD_MEMBER_FULL, "ApplyToGuild guild member full")
return
}
// 可直接加入
if guild.JoinCond == JoinCondFree {
gm.JoinGuild(guild, applicantAccountId)
cb(ERR_CODE_OK, "ApplyToGuild OK")
return
}
if guild.JoinCond == JoinCondStar {
profile := cacheMgr.GetPlayerProfile(applicantAccountId)
if profile == nil {
cb(ERR_CODE_GUILD_MEMBER_NO_EXISTS, "applicantAccountId no exists")
return
}
if profile.Star < guild.JoinCondValue {
cb(ERR_CODE_APPLY_GUILD_FAIL, "ApplyToGuild Fail, user star error")
return
}
gm.JoinGuild(guild, applicantAccountId)
cb(ERR_CODE_OK, "ApplyToGuild OK")
return
}
// IF exists, then replace it fields `isJoinGuild` is 0
where := [][]string{
{"guild_id", q5.ToString(guildId)},
{"account_id", applicantAccountId},
}
insertKv := [][]string{
{"guild_id", q5.ToString(guildId)},
{"account_id", applicantAccountId},
{"is_join_guild", q5.ToString(PendingReqIsJoinGuildStatusDefault)},
}
updateKv := [][]string{
{"is_join_guild", q5.ToString(PendingReqIsJoinGuildStatusDefault)},
}
f5.GetJsStyleDb().Upsert(
FRIEND_DB,
"t_guild_pending_request",
where,
updateKv,
insertKv,
func(err error, lastInsertId int64, rowsAffected int64) {
if err != nil || rowsAffected <= 0 {
cb(ERR_CODE_UPDATE_GUILD_PENDING_REQUEST_DB_FAIL, "ApplyToGuild guild pending request db error")
return
}
pendingReq := &PendingReq{
applicantAccountId,
PendingReqIsJoinGuildStatusDefault,
}
guild.AddPendingReq(pendingReq)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guildId)
prop["join_cond"] = q5.ToString(guild.JoinCond)
f5.GetTgLog().AddTrackLog(
GAME_ID,
applicantAccountId,
"127.0.0.1",
EVENT_APPLY,
prop,
)
cb(ERR_CODE_OK, "ApplyToGuild ok")
})
}
// Approve 同意申请者加入公会
func (gm *GuildMgr) Approve(operatorAccountId, accountId string, cb func(errCode int32, errMsg string, guild *Guild)) {
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "Approve guild no exists", nil)
return
}
// 默认为审核加入
if guild.JoinCond != JoinCondDefault {
cb(ERR_CODE_JOINED_GUILD, "Approve joined guild", nil)
return
}
// 公会干部及以上仅可操作
operatorMember := guild.GetMember(operatorAccountId)
err := gm.CheckOperatorPerm(operatorMember, GuildMemberLevelViceLeader)
if err != nil {
cb(ERR_CODE_GUILD_OPERATOR_MEMBER_NO_PERM, "Approve operator member no perm", nil)
return
}
// 是否加入其他公会
if gm.CheckJoinGuild(accountId) {
cb(ERR_CODE_JOINED_GUILD, "Approve joined guild", nil)
return
}
guildId := guild.GuildId
// 是否在申请队列中
pendingReqStatus := guild.GetPendingReqStatus(accountId)
if pendingReqStatus < 0 {
cb(ERR_CODE_GUILD_PENDING_REQUEST_NO_EXISTS, "Approve pending request no exists", nil)
return
}
if guild.IsFull() {
cb(ERR_CODE_GUILD_MEMBER_FULL, "Approve guild member full", nil)
return
}
newMember := &GuildMember{AccountId: accountId, Level: GuildMemberLevelDefault}
gm.upsertGuildMember(guildId, newMember, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, "Approve update guild member db error", nil)
return
}
guild.AddMember(newMember)
gm.AddUserGuild(accountId, guildId)
gm.updatePendingReqs(guildId, accountId, PendingReqIsJoinGuildStatusJoined, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_PENDING_REQUEST_DB_FAIL, "Approve db error", nil)
return
}
logContent := fmt.Sprintf("Approve[operator:%s]", operatorAccountId)
gm.WriteLog(guildId, accountId, LogTypeApprove, logContent)
guild.RemovePendingReq(accountId)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guildId)
prop["applicant_account_id"] = q5.ToString(accountId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_APPROVE,
prop,
)
cb(ERR_CODE_OK, "Approve ok", guild)
})
})
}
// Reject 拒绝申请者加入公会
func (gm *GuildMgr) Reject(operatorAccountId, accountId string, cb func(errCode int32, errMsg string)) {
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "Reject guild no exists")
return
}
// 通常默认为审核加入
if guild.JoinCond != JoinCondDefault {
cb(ERR_CODE_JOINED_GUILD, "Reject joined guild")
return
}
// 公会干部及以上仅可操作
operatorMember := guild.GetMember(operatorAccountId)
err := gm.CheckOperatorPerm(operatorMember, GuildMemberLevelViceLeader)
if err != nil {
cb(ERR_CODE_GUILD_OPERATOR_MEMBER_NO_PERM, "Reject operator member no perm")
return
}
// 是否加入其他公会
if gm.CheckJoinGuild(accountId) {
cb(ERR_CODE_JOINED_GUILD, "Reject joined guild")
return
}
// 是否在申请队列中
pendingReqStatus := guild.GetPendingReqStatus(accountId)
if pendingReqStatus < 0 {
cb(ERR_CODE_GUILD_PENDING_REQUEST_NO_EXISTS, "Reject pending request no exists")
return
}
gm.updatePendingReqs(guild.GuildId, accountId, PendingReqIsJoinGuildStatusReject, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_PENDING_REQUEST_DB_FAIL, "Reject db error")
return
}
guild.RemovePendingReq(accountId)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["reject_account_id"] = q5.ToString(accountId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_REJECT,
prop,
)
cb(ERR_CODE_OK, "Reject ok")
})
}
// JoinGuild 直接加入公会
func (gm *GuildMgr) JoinGuild(guild *Guild, accountId string) {
newMember := GuildMember{AccountId: accountId, Level: GuildMemberLevelDefault}
guildId := guild.GuildId
gm.upsertGuildMember(guildId, &newMember,
func(err error) {
if err != nil {
guild.AddMember(&newMember)
gm.AddUserGuild(accountId, guildId)
user := friendMgr.GetUser(accountId)
cacheMgr.LoadPlayerProfile(user, func(playerProfile *PlayerProfile) {})
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
accountId,
"127.0.0.1",
EVENT_JOIN,
prop,
)
}
})
}
// LeaveGuild 离开公会
func (gm *GuildMgr) LeaveGuild(accountId string, cb func(errCode int32, errMsg string)) {
guild := gm.GetGuildByAccountId(accountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "LeaveGuild guild no exists")
return
}
member := guild.GetMember(accountId)
if member == nil {
cb(ERR_CODE_GUILD_MEMBER_NO_EXISTS, "LeaveGuild member no exists")
return
}
//guildId := guild.GuildId
//guildName := guild.Name
membersCount := guild.GetMembersCount()
// 解散公会
if membersCount <= 1 {
gm.Disband(accountId, cb)
return
}
// 重新选举公长
if accountId == guild.LeaderId {
newLeader := ElectNewGuildLeader(guild)
if newLeader == nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, "error")
return
}
guild.LeaderId = newLeader.AccountId
updateFields := [][]string{
{"leader_account_id", q5.ToString(guild.LeaderId)},
}
gm.updateGuild(guild, updateFields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, err.Error())
return
}
// 新会长
newMemberFields := [][]string{{"level", q5.ToString(newLeader.Level)}}
gm.updateGuildMember(guild, newLeader.AccountId, newMemberFields,
func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
})
})
}
fields := [][]string{{"is_leave_guild", q5.ToString(1)}}
gm.updateGuildMember(guild, member.AccountId, fields,
func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
guild.RemoveMember(accountId)
gm.RemoveUserGuild(accountId)
// Add logs
logContent := fmt.Sprintf("LeaveGuild[%d-%s]", guild.GuildId, accountId)
gm.WriteLog(guild.GuildId, accountId, LogTypeLeave, logContent)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
accountId,
"127.0.0.1",
EVENT_LEAVE,
prop,
)
cb(ERR_CODE_OK, "LeaveGuild OK")
})
}
// DismissMember 开除成员 踢出
func (gm *GuildMgr) DismissMember(operatorAccountId, accountId string, cb func(errCode int32, errMsg string)) {
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "DismissMember guild no exists")
return
}
if accountId == guild.LeaderId || accountId == operatorAccountId {
cb(ERR_CODE_GUILD_BLOCKED_LEADER, "DismissMember Blocked leader")
return
}
// 公会干部及以上仅可操作
operatorMember := guild.GetMember(operatorAccountId)
err := gm.CheckOperatorPerm(operatorMember, GuildMemberLevelViceLeader)
if err != nil {
cb(ERR_CODE_GUILD_OPERATOR_MEMBER_NO_PERM, "DismissMember operator member no perm")
return
}
dismissMember := guild.GetMember(accountId)
if dismissMember == nil {
cb(ERR_CODE_GUILD_MEMBER_NO_EXISTS, "LeaveGuild member no exists")
return
}
if dismissMember.Level <= operatorMember.Level {
cb(ERR_CODE_GUILD_DISMISS_MEMBER_NO_PERM, "Approve dismiss member no perm")
return
}
fields := [][]string{{"is_leave_guild", q5.ToString(1)}}
gm.updateGuildMember(guild, dismissMember.AccountId, fields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
guild.RemoveMember(accountId)
gm.RemoveUserGuild(accountId)
// Add logs
logContent := fmt.Sprintf("DismissMember[%d-%s-%s]", guild.GuildId, operatorAccountId, accountId)
gm.WriteLog(guild.GuildId, accountId, LogTypeDismiss, logContent)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["accountId"] = q5.ToString(accountId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_DISMISS_MEMBER,
prop,
)
cb(ERR_CODE_OK, "DismissMember OK")
})
}
// SetMemberLevel 设置公会成员等级
func (gm *GuildMgr) SetMemberLevel(operatorAccountId, accountId string, level int32, cb func(errCode int32, errMsg string)) {
// 干部, 精英, 副会长
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "PromoteMember guild no exists")
return
}
if accountId == guild.LeaderId || accountId == operatorAccountId {
cb(ERR_CODE_GUILD_BLOCKED_LEADER, "PromoteMember Blocked leader")
return
}
member := guild.GetMember(accountId)
if member == nil {
cb(ERR_CODE_GUILD_MEMBER_NO_EXISTS, "LeaveGuild member no exists")
return
}
beforeLevel := member.Level
if member.Level == level {
cb(ERR_CODE_GUILD_OPERATOR_MEMBER_NO_PERM, "LeaveGuild error")
return
}
fields := [][]string{{"level", q5.ToString(level)}}
gm.updateGuildMember(guild, member.AccountId, fields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
member.Level = level
logContent := fmt.Sprintf("SetMemberLevel[%d-%s-%s-%d-%d]", guild.GuildId, operatorAccountId, accountId, beforeLevel, level)
gm.WriteLog(guild.GuildId, accountId, LogTypePromote, logContent)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["accountId"] = q5.ToString(accountId)
prop["beforeMemberLevel"] = q5.ToString(beforeLevel)
prop["afterMemberLevel"] = q5.ToString(level)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_SET_MEMBER_LEVEL,
prop,
)
cb(ERR_CODE_OK, "SetMemberLevel OK")
})
}
// PromoteMember 提升成员为干部
func (gm *GuildMgr) PromoteMember(operatorAccountId, accountId string, cb func(errCode int32, errMsg string)) {
// 干部, 精英, 副会长
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "PromoteMember guild no exists")
return
}
if accountId == guild.LeaderId || accountId == operatorAccountId {
cb(ERR_CODE_GUILD_BLOCKED_LEADER, "PromoteMember Blocked leader")
return
}
// 仅会长操作
if operatorAccountId != guild.LeaderId {
cb(ERR_CODE_GUILD_NO_LEADER_PERM, "PromoteMember only leader perm")
return
}
member := guild.GetMember(accountId)
if member == nil {
cb(ERR_CODE_GUILD_MEMBER_NO_EXISTS, "LeaveGuild member no exists")
return
}
if member.Level == GuildMemberLevelViceLeader {
cb(ERR_CODE_GUILD_OPERATOR_MEMBER_NO_PERM, "LeaveGuild error")
return
}
fields := [][]string{{"level", q5.ToString(GuildMemberLevelViceLeader)}}
gm.updateGuildMember(guild, member.AccountId, fields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
member.Level = GuildMemberLevelViceLeader
logContent := fmt.Sprintf("PromoteMember[%d-%s-%s]", guild.GuildId, operatorAccountId, accountId)
gm.WriteLog(guild.GuildId, accountId, LogTypePromote, logContent)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["accountId"] = q5.ToString(accountId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_PROMOTE_MEMBER,
prop,
)
cb(ERR_CODE_OK, "PromoteMember OK")
})
}
// DemoteMember 解除成员干部身份
func (gm *GuildMgr) DemoteMember(operatorAccountId, accountId string, cb func(errCode int32, errMsg string)) {
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "DemoteMember guild no exists")
return
}
if accountId == guild.LeaderId || accountId == operatorAccountId {
cb(ERR_CODE_GUILD_BLOCKED_LEADER, "DemoteMember Blocked leader")
return
}
// 仅会长可操作
if operatorAccountId != guild.LeaderId {
cb(ERR_CODE_GUILD_NO_LEADER_PERM, "DemoteMember only leader perm")
return
}
member := guild.GetMember(accountId)
if member == nil {
cb(ERR_CODE_GUILD_MEMBER_NO_EXISTS, "DemoteMember member no exists")
return
}
if member.Level == GuildMemberLevelDefault {
cb(ERR_CODE_GUILD_DEMOTE_MEMBER_OK, "DemoteMember member ok")
return
}
fields := [][]string{{"level", q5.ToString(GuildMemberLevelDefault)}}
gm.updateGuildMember(guild, member.AccountId, fields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
member.Level = GuildMemberLevelDefault
logContent := fmt.Sprintf("DemoteMember[%d-%s-%s]", guild.GuildId, operatorAccountId, accountId)
gm.WriteLog(guild.GuildId, accountId, LogTypeDemote, logContent)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
prop["accountId"] = q5.ToString(accountId)
prop["members_count"] = q5.ToString(guild.GetMembersCount())
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_DEMOTE_MEMBER,
prop,
)
cb(ERR_CODE_OK, "DemoteMember OK")
})
}
// Disband 解散公会
func (gm *GuildMgr) Disband(operatorAccountId string, cb func(errCode int32, errMsg string)) {
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
cb(ERR_CODE_GUILD_NO_EXISTS, "Disband guild no exists")
return
}
// 仅会长可操作
if operatorAccountId != guild.LeaderId {
cb(ERR_CODE_GUILD_NO_LEADER_PERM, "PromoteMember only leader perm")
return
}
guildId := guild.GuildId
guildName := guild.Name
// 解散公会
updateFields := [][]string{
{"is_deleted", q5.ToString(1)},
}
gm.updateGuild(guild, updateFields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, err.Error())
return
}
fields := [][]string{{"is_leave_guild", q5.ToString(1)}}
gm.updateGuildMembers(guildId, fields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_MEMBER_DB_FAIL, err.Error())
return
}
gm.updateAllPendingReqs(guildId, PendingReqIsJoinGuildStatusDisband, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_PENDING_REQUEST_DB_FAIL, err.Error())
return
}
logContent := fmt.Sprintf("GuildDisbanded[%d-%s]", guildId, guildName)
gm.WriteLog(guildId, operatorAccountId, LogTypeDisband, logContent)
// delete user guilds
for _, member := range guild.Members {
delete(gm.userGuilds, member.AccountId)
}
guild.Members = nil
delete(gm.guilds, guildId)
delete(gm.guildLogs, guildId)
gm.RemoveGuild(guildId)
// Add event
prop := make(map[string]string)
prop["guild_id"] = q5.ToString(guild.GuildId)
f5.GetTgLog().AddTrackLog(
GAME_ID,
operatorAccountId,
"127.0.0.1",
EVENT_DISBAND,
prop,
)
cb(ERR_CODE_OK, "Disband ok")
})
})
})
}
func (gm *GuildMgr) CheckGuildAndPermission(operatorAccountId string) (*Guild, bool) {
guild := gm.GetGuildByAccountId(operatorAccountId)
if guild == nil {
return nil, false
}
if operatorAccountId != guild.LeaderId {
return nil, false
}
return guild, true
}
func (gm *GuildMgr) SetAvatar(operatorAccountId string, avatar int32, cb func(errCode int32, errMsg string)) {
guild, ok := gm.CheckGuildAndPermission(operatorAccountId)
if !ok || guild.Avatar == avatar {
cb(ERR_CODE_REQUEST_PARAMS_ERROR, "params is null")
return
}
updateFields := [][]string{
{"avatar", q5.ToString(avatar)},
}
gm.updateGuild(guild, updateFields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, err.Error())
return
}
guild.Avatar = avatar
cb(ERR_CODE_OK, "SetNotice OK")
})
}
func (gm *GuildMgr) SetName(operatorAccountId string, name *string, cb func(errCode int32, errMsg string)) {
guild, ok := gm.CheckGuildAndPermission(operatorAccountId)
if !ok || name == nil || guild.Name == *name {
cb(ERR_CODE_REQUEST_PARAMS_ERROR, "params is null")
return
}
updateFields := [][]string{
{"name", *name},
}
gm.updateGuild(guild, updateFields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, err.Error())
return
}
guild.Name = *name
cb(ERR_CODE_OK, "SetNotice OK")
})
}
// SetNotice 设置公告
func (gm *GuildMgr) SetNotice(operatorAccountId string, notice *string, cb func(errCode int32, errMsg string)) {
guild, ok := gm.CheckGuildAndPermission(operatorAccountId)
if !ok || notice == nil || guild.Notice == *notice {
cb(ERR_CODE_REQUEST_PARAMS_ERROR, "params is null")
return
}
updateFields := [][]string{
{"notice", *notice},
}
gm.updateGuild(guild, updateFields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, err.Error())
return
}
guild.Notice = *notice
cb(ERR_CODE_OK, "SetNotice OK")
})
}
// SetJoinCond 请求设置公会加入条件
func (gm *GuildMgr) SetJoinCond(operatorAccountId string, joinCond, joinCondValue int32, cb func(errCode int32, errMsg string)) {
guild, ok := gm.CheckGuildAndPermission(operatorAccountId)
if !ok {
cb(ERR_CODE_REQUEST_PARAMS_ERROR, "params is null")
return
}
updateFields := [][]string{
{"join_cond", q5.ToString(joinCond)},
{"join_cond_value", q5.ToString(0)},
}
if joinCond == JoinCondStar {
updateFields = [][]string{
{"join_cond", q5.ToString(joinCond)},
{"join_cond_value", q5.ToString(joinCondValue)},
}
} else {
joinCondValue = 0
}
gm.updateGuild(guild, updateFields, func(err error) {
if err != nil {
cb(ERR_CODE_UPDATE_GUILD_DB_FAIL, err.Error())
return
}
guild.JoinCond = joinCond
guild.JoinCondValue = joinCondValue
cb(ERR_CODE_OK, "SetJoinCond OK")
})
}
// WriteLog 记录公会日志
func (gm *GuildMgr) WriteLog(guildId int64, accountId string, logType int32, content string) {
guild := gm.GetGuild(guildId)
if guild == nil {
return
}
_, exists := gm.guildLogs[guildId]
if !exists {
gm.guildLogs[guildId] = make([]*GuildLog, DefaultLogs)
}
log := &GuildLog{
GuildId: guildId,
AccountId: accountId,
LogType: logType,
Content: content,
}
gm.guildLogs[guildId] = append(gm.guildLogs[guildId], log)
gm.insertGuildLog(log)
}
func (gm *GuildMgr) GetLogs(guildID int64) []*GuildLog {
return gm.guildLogs[guildID]
}
// SearchGuild 根据关键字搜索公会
func (gm *GuildMgr) SearchGuild(sinceId int64, name string, cb func(errCode int32, errMsg string, lastId int64, guildIds []int64)) {
gm.findGuildIdsByName(sinceId, name, func(err error, lastId int64, guildIds []int64) {
if err != nil {
cb(ERR_CODE_SEARCH_USERS_DB_FAIL, "SearchUsers username db error", sinceId, guildIds)
return
}
if len(guildIds) <= 0 {
cb(ERR_CODE_SEARCH_NO_RESULT, "SearchGuilds result is empty", lastId, guildIds)
}
cb(0, "OK", lastId, guildIds)
})
}
// RandomGuilds 随机10个公会
func (gm *GuildMgr) RandomGuilds() []*Guild {
count := len(gm.guilds)
var results []*Guild
if count <= RandomGuildCount {
for _, guildId := range gm.guildIds {
results = append(results, gm.guilds[guildId])
}
return results
}
for i := 0; i < RandomGuildCount; i++ {
j := rand.Intn(len(gm.guildIds))
gm.guildIds[i], gm.guildIds[j] = gm.guildIds[j], gm.guildIds[i]
}
for i := 0; i < RandomGuildCount; i++ {
randGuildId := gm.guildIds[i]
results = append(results, gm.guilds[randGuildId])
}
return results
}
func (gm *GuildMgr) CheckOperatorPerm(operatorMember *GuildMember, level int32) error {
if operatorMember == nil || operatorMember.Level > level {
return fmt.Errorf("CheckOperatorPerm: no permission[%s-%d]", operatorMember.AccountId, operatorMember.Level)
}
return nil
}
func (gm *GuildMgr) ExistsGuild(guildId int64) bool {
_, ok := gm.guilds[guildId]
return ok
}
func (gm *GuildMgr) AddUserGuild(accountId string, guildId int64) {
gm.userGuilds[accountId] = guildId
}
func (gm *GuildMgr) RemoveUserGuild(accountId string) {
delete(gm.userGuilds, accountId)
}
func (gm *GuildMgr) AddGuild(guildId int64, guild *Guild) {
if _, exists := gm.guilds[guildId]; !exists {
gm.guilds[guildId] = guild
gm.guildIds = append(gm.guildIds, guildId)
}
}
func (gm *GuildMgr) GetGuild(guildId int64) *Guild {
if guild, exists := gm.guilds[guildId]; exists {
return guild
}
return nil
}
func (gm *GuildMgr) GetGuildByAccountId(accountId string) *Guild {
if guildId, exists := gm.userGuilds[accountId]; exists {
if guild, exists2 := gm.guilds[guildId]; exists2 {
return guild
}
}
return nil
}
func (gm *GuildMgr) GetGuildIdByAccountId(accountId string) int64 {
if guildId, exists := gm.userGuilds[accountId]; exists {
return guildId
}
return -1
}
func (gm *GuildMgr) CheckJoinGuild(accountId string) bool {
_, exists := gm.userGuilds[accountId]
return exists
}
func (gm *GuildMgr) loadGuildIds() {
gm.guildIds = make([]int64, 0, len(gm.guilds))
for guildId := range gm.guilds {
gm.guildIds = append(gm.guildIds, guildId)
}
}
func (gm *GuildMgr) RemoveGuild(guildId int64) {
guildIndex := -1
for i, gId := range gm.guildIds {
if gId == guildId {
guildIndex = i
}
}
if guildIndex < 0 {
return
}
copy(gm.guildIds[guildIndex:], gm.guildIds[guildIndex+1:])
gm.guildIds[len(gm.guildIds)-1] = 0
gm.guildIds = gm.guildIds[:len(gm.guildIds)-1]
}
func (gm *GuildMgr) GetGuildLogs(guildId int64) []*GuildLog {
if logs, exists := gm.guildLogs[guildId]; exists {
return logs
}
return nil
}
func ElectNewGuildLeader(guild *Guild) *GuildMember {
sort.Slice(guild.Members, func(i, j int) bool {
return guild.Members[i].Level < guild.Members[j].Level
})
// 找到级别最低的成员
lowestLevel := guild.Members[0].Level
var potentialLeaders []*GuildMember
for _, member := range guild.Members {
if member.Level == lowestLevel {
potentialLeaders = append(potentialLeaders, member)
} else {
break
}
}
newLeader := potentialLeaders[rand.Intn(len(potentialLeaders))]
newLeader.Level = GuildMemberLevelLeader
return newLeader
//newLeader.Level = GuildMemberLevelLeader
//return newLeader.AccountId
}