aozhiwei 479f77fef9 1
2024-04-08 15:45:29 +08:00

584 lines
14 KiB
Go

package guild
import (
"q5"
"f5"
"main/common"
"main/constant"
"fmt"
"mt"
)
const (
LoadGuildFlag = iota
LoadGuildMemberFlag
LoadGuildReqFlag
LoadGuildLogFlag
)
type guildMgr struct {
idHash map[string]*guild
nameHash map[string]*guild
memberIdHash map[string]*member
usingNameHash map[string]int64
}
func (this *guildMgr) Init() {
this.idHash = make(map[string]*guild)
this.nameHash = make(map[string]*guild)
this.memberIdHash = make(map[string]*member)
this.usingNameHash = make(map[string]int64)
this.loadFromDB()
}
func (this *guildMgr) UnInit() {
}
func (this *guildMgr) loadFromDB() {
this.loadGuild()
this.loadGuildMember()
}
func (this *guildMgr) loadGuild() {
f5.GetSysLog().Info("loadGuild begin")
lastIdx := f5.GetJsStyleDb().SyncBatchLoadFullTable(
constant.FRIEND_DB,
"SELECT * FROM t_guild WHERE idx > %d AND deleted = 0",
func (ds *f5.DataSet) {
p := newGuild()
p.loadFromDb(ds)
this.idHash[p.guildId] = p
this.nameHash[p.guildName] = p
},
func (err error) {
panic(fmt.Sprintf("loadGuild dberror:%s", err))
})
f5.GetSysLog().Info("loadGuild end lastIdx:%d idNum:%d nameNum:%d",
lastIdx,
len(this.idHash),
len(this.nameHash))
}
func (this *guildMgr) loadGuildMember() {
f5.GetSysLog().Info("loadGuildMember begin")
lastIdx := f5.GetJsStyleDb().SyncBatchLoadFullTable(
constant.FRIEND_DB,
"SELECT * FROM t_guild_member WHERE idx > %d AND deleted = 0",
func (ds *f5.DataSet) {
guildId := ds.GetByName("guild_id")
guildJob := q5.ToInt32(ds.GetByName("guild_job"))
memberId := ds.GetByName("member_id")
joinTime := q5.ToInt32(ds.GetByName("join_time"))
g := this.internalGetGuildByGuildId(guildId)
if g != nil {
p := newMember()
p.init(g, guildJob, memberId, joinTime)
g.addMember(p)
this.memberIdHash[memberId] = p
}
},
func (err error) {
panic(fmt.Sprintf("loadGuildMember dberror:%s", err))
})
f5.GetSysLog().Info("loadGuildMember end memberNum:%d",
lastIdx,
len(this.memberIdHash))
}
func (this *guildMgr) isNameTooLong(name string) bool {
return len(name) > 15
}
func (this *guildMgr) GetGuildByGuildId(guildId string) common.Guild {
if p := this.internalGetGuildByGuildId(guildId); p != nil {
return p
} else {
return nil
}
}
func (this *guildMgr) GetGuildByAccountId(accountId string) common.Guild {
if p := this.internalGetGuildByAccountId(accountId); p != nil {
return p
} else {
return nil
}
}
func (this *guildMgr) GetGuildByGuildName(guildName string) common.Guild {
if p := this.internalGetGuildByGuildName(guildName); p != nil {
return p
} else {
return nil
}
}
func (this *guildMgr) internalGetGuildByAccountId(accountId string) *guild {
m := this.internalGetMemberByAccountId(accountId)
if m != nil {
return m.guild
}
return nil
}
func (this *guildMgr) internalGetMemberByAccountId(accountId string) *member {
if m, ok := this.memberIdHash[accountId]; ok {
return m
}
return nil
}
func (this *guildMgr) internalGetGuildByGuildId(guildId string) *guild {
if guild, ok := this.idHash[guildId]; ok {
return guild
}
return nil
}
func (this *guildMgr) internalGetGuildByGuildName(guildName string) *guild {
if guild, ok := this.nameHash[guildName]; ok {
return guild
}
return nil
}
func (this *guildMgr) GetRecommendGuilds(string) []common.Guild {
guilds := []common.Guild{}
return guilds
}
func (this *guildMgr) GetGuildRank() []common.Guild {
guilds := []common.Guild{}
return guilds
}
func (this *guildMgr) addUsingName(name string) {
this.usingNameHash[name] = f5.GetApp().GetNowSeconds();
}
func (this *guildMgr) isUsingName(name string) bool {
if _, ok := this.usingNameHash[name]; ok {
return true
} else {
return false
}
}
func (this* guildMgr) removeUsingName(name string) {
delete(this.usingNameHash, name)
}
func (this *guildMgr) asyncCreateGuildTask(task *f5.AsyncTask,
guildId string, accountId string, avatar int32, name string,
cb func(int32, string, string)) {
if this.internalGetGuildByAccountId(accountId) != nil {
task.SetFail()
cb(3, "You already have a cube", "")
return
}
if this.internalGetGuildByGuildName(name) != nil {
task.SetFail()
cb(4, "Cube name already exists", "")
return
}
if this.isUsingName(name) {
task.SetFail()
cb(4, "Cube name already exists", "")
return
}
this.addUsingName(name)
nowTime := f5.GetApp().GetNowSeconds()
f5.GetJsStyleDb().Insert(
constant.FRIEND_DB,
"t_guild",
[][]string{
{"guild_id", guildId},
{"guild_name", name},
{"owner_id", accountId},
{"creator_id", accountId},
{"badge", q5.ToString(avatar)},
{"max_members", q5.ToString(constant.GuildMaxMembers)},
{"createtime", q5.ToString(nowTime)},
{"modifytime", q5.ToString(nowTime)},
},
func (err error, lastInsertId int64, rowsAffected int64) {
this.removeUsingName(name)
if err != nil {
task.SetFail()
cb(500, "server internal error", "")
return
}
f5.GetJsStyleDb().Upsert(
constant.FRIEND_DB,
"t_guild_member",
[][]string{
{"member_id", accountId},
},
[][]string{
{"guild_id", guildId},
{"guild_job", q5.ToString(constant.GuildMemberLevelLeader)},
{"deleted", q5.ToString(0)},
{"join_time", q5.ToString(nowTime)},
},
[][]string{
{"guild_id", guildId},
{"guild_job", q5.ToString(constant.GuildMemberLevelLeader)},
{"member_id", accountId},
{"join_time", q5.ToString(nowTime)},
{"createtime", q5.ToString(nowTime)},
{"modifytime", q5.ToString(nowTime)},
},
func (err error, lastInsertId int64, rowsAffected int64) {
if err != nil {
task.SetFail()
cb(500, "server internal error", "")
return
}
guild := newGuild()
{
p := newMember()
p.init(guild, constant.GuildMemberLevelLeader,
accountId, int32(nowTime))
this.memberIdHash[accountId] = p
}
this.idHash[guild.guildId] = guild
this.nameHash[guild.guildName] = guild
oldGuild := this.internalGetGuildByAccountId(accountId)
if oldGuild != nil {
task.SetFail()
panic(fmt.Sprintf("asyncCreateGuildTask:%s", ""))
} else {
m := newMember()
m.init(guild, constant.GuildMemberLevelLeader,
accountId, q5.ToInt32(nowTime))
guild.addMember(m)
this.memberIdHash[accountId] = m
task.SetSucc()
cb(0, "", guildId)
}
})
})
}
func (this *guildMgr) AsyncCreateGuild(accountId string, sessionId string, avatar int32, name string,
cb func(int32, string, string)) {
guildId := q5.ToString(f5.GetApp().NewNodeUuid())
f5.NewLockAsyncTask([][]string{
{constant.GUILD_ID_LOCK_KEY, guildId},
{constant.GUILD_NAME_LOCK_KEY, name},
{constant.GUILD_MEMBER_LOCK_KEY, accountId},
},
func (task *f5.LockAsyncTask) {
if len(name) <= 0 {
task.SetFail()
cb(1, "Name cantnot be empty", "")
return
}
if this.isNameTooLong(name) {
task.SetFail()
cb(2, "Name is to long", "")
return
}
if this.GetGuildByAccountId(accountId) != nil {
task.SetFail()
cb(3, "You already have a cube", "")
return
}
if this.GetGuildByGuildName(name) != nil {
task.SetFail()
cb(4, "Cube name already exists", "")
return
}
params := map[string]string{
"c": "Bag",
"a": "createGuildConsume",
"account_id": accountId,
"session_id": sessionId,
}
url := fmt.Sprintf("%s/webapp/index.php", mt.Table.Config.GetById(0).GetGameapiUrl())
rspObj := new(common.HeadRsp)
f5.GetHttpCliMgr().SendJsStyleJsonRspRequest(
url,
params,
&rspObj,
func(rsp f5.HttpCliResponse) {
if rspObj.Errcode != 0 {
task.SetFail()
cb(4, "item not enough", "")
return
}
this.asyncCreateGuildTask(task, guildId, accountId, avatar, name, cb)
})
})
}
func (this *guildMgr) AsyncGetApplyList(lastIdx int64, accountId string,
cb func(int32, string, int64, []string)) {
guild := this.GetGuildByAccountId(accountId)
if guild != nil {
cb(0, "", 0, nil)
return
}
f5.GetJsStyleDb().PageQuery(
constant.FRIEND_DB,
50,
0,
"SELECT * FROM t_guild_apply",
[]string{},
f5.GetDbFilter().Comp(
f5.GetDbFilter().GT("idx", q5.ToString(lastIdx)).And(),
f5.GetDbFilter().EQ("guild_id", guild.GetGuildId()).And(),
f5.GetDbFilter().EQ("account_id", accountId).And(),
f5.GetDbFilter().EQ("status", q5.ToString(constant.GUILD_APPLY_STATUS_NONE)),
),
"",
func (err error, pg *f5.Pagination) {
var lastSinceId int64
if err != nil {
cb(500, "", lastSinceId, []string{})
}
if pg.Rows.Next() {
idx := q5.ToInt64(pg.Rows.GetByName("idx"))
if idx > lastSinceId {
lastSinceId = idx
} else {
panic(fmt.Sprintf("AsyncGetApply idx error:%s %s", idx, lastSinceId))
}
}
})
}
func (this *guildMgr) AsyncApplyJoin(accountId string, guildId string, cb func(int32, string)) {
guild := this.GetGuildByAccountId(accountId)
if guild != nil {
cb(0, "")
return
}
nowTime := f5.GetApp().GetNowSeconds()
f5.GetJsStyleDb().Upsert(
constant.FRIEND_DB,
"t_guild_apply",
[][]string{
{"guild_id", guildId},
{"account_id", accountId},
},
[][]string{
{"status", q5.ToString(constant.GUILD_APPLY_STATUS_NONE)},
{"last_apply_time", q5.ToString(nowTime)},
},
[][]string{
{"guild_id", guildId},
{"account_id", accountId},
{"status", q5.ToString(constant.GUILD_APPLY_STATUS_NONE)},
{"last_apply_time", q5.ToString(nowTime)},
{"createtime", q5.ToString(nowTime)},
{"modifytime", q5.ToString(nowTime)},
},
func (err error, lastInsertId int64, rowsAffected int64) {
if err != nil {
cb(1, "")
return
}
cb(0, "")
})
}
func (this *guildMgr) asyncAcceptApplyTask(task *f5.AsyncTask, guild *guild,
accountId string, targetId string, cb func(int32, string)) {
if !guild.isOwner(accountId) {
task.SetFail()
cb(1, "")
return
}
if this.internalGetMemberByAccountId(targetId) != nil {
task.SetFail()
cb(1, "")
return
}
nowTime := q5.ToInt32(f5.GetApp().GetNowSeconds())
f5.GetJsStyleDb().Update(
constant.FRIEND_DB,
"t_guild_member",
[][]string{
{"member_id", accountId},
},
[][]string{
{"guild_id", guild.guildId},
{"guild_job", q5.ToString(constant.GuildMemberLevelDefault)},
{"deleted", q5.ToString(0)},
{"join_time", q5.ToString(nowTime)},
},
func (err error, lastInsertId int64, rowsAffected int64) {
if err != nil {
task.SetFail()
cb(1, "")
return
}
m := newMember()
m.init(guild, constant.GuildMemberLevelDefault, targetId, nowTime)
guild.addMember(m)
this.memberIdHash[targetId] = m
this.asyncSetApplyStatus(
targetId,
guild.guildId,
constant.GUILD_APPLY_STATUS_ACCEPT,
func (err error, lastInsertId int64, rowsAffected int64) {
task.SetSucc()
})
})
}
func (this *guildMgr) AsyncAcceptApply(accountId string, targetId string, cb func(int32, string)) {
guild := this.internalGetGuildByAccountId(accountId)
if guild == nil {
cb(1, "")
return;
}
f5.NewLockAsyncTask([][]string{
{constant.MEMBER_LOCK_KEY, accountId},
{constant.MEMBER_LOCK_KEY, targetId},
{constant.GUILD_ID_LOCK_KEY, guild.guildId},
},
func (task *f5.AsyncTask) {
this.asyncAcceptApplyTask(task, guild, accountId, targetId, cb)
})
}
func (this *guildMgr) AsyncRejectApply(accountId string, targetId string,
cb func(int32, string)) {
guild := this.internalGetGuildByAccountId(accountId)
if guild == nil {
cb(0, "")
return;
}
this.asyncSetApplyStatus(
targetId,
guild.guildId,
constant.GUILD_APPLY_STATUS_REJECT,
func (err error, lastInsertId int64, rowsAffected int64) {
cb(0, "")
})
}
func (this *guildMgr) AsyncLeave(accountId string, cb func(int32, string)) {
guild := this.internalGetGuildByAccountId(accountId)
if guild == nil {
cb(0, "")
return;
}
}
func (this *guildMgr) AsyncKickout(accountId string, targetId string, cb func(int32, string)) {
guild := this.internalGetGuildByAccountId(accountId)
if guild == nil {
cb(0, "")
return;
}
if !guild.isOwner(accountId) {
cb(0, "")
return;
}
}
func (this *guildMgr) AsyncDisband(accountId string, cb func(int32, string, []string)) {
members := []string{}
keys := [][]string{}
{
guild := this.internalGetGuildByAccountId(accountId)
if guild == nil {
cb(0, "", members)
return
}
if !guild.isOwner(accountId) {
cb(1, "Disband only leader perm", members)
return
}
keys = [][]string{
{constant.GUILD_ID_LOCK_KEY, guild.guildId},
{constant.GUILD_NAME_LOCK_KEY, guild.guildName},
};
guild.traverseMembers(
func (m *member) bool {
q5.AppendSlice(&keys, []string{constant.GUILD_MEMBER_LOCK_KEY, m.memberId})
q5.AppendSlice(&members, m.memberId)
return true
})
}
f5.NewLockAsyncTask(
keys,
func (task *f5.LockAsyncTask) {
guild := this.internalGetGuildByAccountId(accountId)
members := []string{}
if guild == nil {
task.SetSucc()
cb(0, "", members)
return
}
if !guild.isOwner(accountId) {
task.SetFail()
cb(1, "Disband only leader perm", members)
return
}
f5.GetJsStyleDb().Update(
constant.FRIEND_DB,
"t_guild",
[][]string{
{"deleted", "1"},
},
[][]string{
{"guild_id", guild.guildId},
},
func (err error, lastInsertId int64, rowsAffected int64) {
if err != nil {
task.SetFail()
cb(500, "server internal error", members)
return
}
task.SetSucc()
guild.disband()
cb(0, "", members)
return
})
})
}
func (this *guildMgr) AsyncSetNotice(string, string, func(int32, string)) {
}
func (this *guildMgr) AsyncSetAvatar(string, string, func(int32, string)) {
}
func (this *guildMgr) AsyncSetName(string, string, func(int32, string)) {
}
func (this *guildMgr) AsyncSetJoinCond(string, string, func(int32, string)) {
}
func (this *guildMgr) AsyncSearch(string, string, func(int32, string)) {
}
func (this *guildMgr) AsyncGetGuildLogs(string, string, func(int32, string)) {
}
func (this *guildMgr) asyncSetApplyStatus(accountId string, guildId string, status int32,
cb func(error, int64, int64)) {
f5.GetJsStyleDb().Update(
constant.FRIEND_DB,
"t_guild_apply",
[][]string{
{"status", q5.ToString(status)},
{"modifytime", q5.ToString(f5.GetApp().GetNowSeconds())},
},
[][]string{
{"account_id", accountId},
{"guild_id", guildId},
},
cb)
}