970 lines
24 KiB
Go
970 lines
24 KiB
Go
package sociaty
|
|
|
|
import (
|
|
"context"
|
|
"go_dreamfactory/comm"
|
|
"go_dreamfactory/lego/core"
|
|
event_v2 "go_dreamfactory/lego/sys/event/v2"
|
|
"go_dreamfactory/lego/sys/log"
|
|
"go_dreamfactory/modules"
|
|
"go_dreamfactory/pb"
|
|
"go_dreamfactory/sys/configure"
|
|
cfg "go_dreamfactory/sys/configure/structs"
|
|
"go_dreamfactory/utils"
|
|
"sort"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"go.mongodb.org/mongo-driver/bson"
|
|
"go.mongodb.org/mongo-driver/bson/primitive"
|
|
"go.mongodb.org/mongo-driver/mongo"
|
|
"go.mongodb.org/mongo-driver/x/bsonx"
|
|
)
|
|
|
|
type Tag string
|
|
|
|
const (
|
|
Log_Job Tag = `%s玩家已经将%s玩家设为了%s` //职位变动
|
|
Log_Quit Tag = "%s玩家已经退出了公会" //退出
|
|
Log_Add Tag = `%s玩家加入了公会` //加入
|
|
Log_Upgrade Tag = "公会已经升为%s级" //升级
|
|
Log_Discharge Tag = "%s玩家已经将%s玩家逐出了公会" //踢出
|
|
)
|
|
|
|
type ModelSociaty struct {
|
|
modules.MCompModel
|
|
module *Sociaty
|
|
service core.IService
|
|
EventApp *event_v2.App
|
|
}
|
|
|
|
type SociatyListen struct {
|
|
event_v2.App
|
|
sociaty *pb.DBSociaty
|
|
}
|
|
|
|
func (this *ModelSociaty) Init(service core.IService, module core.IModule, comp core.IModuleComp, options core.IModuleOptions) (err error) {
|
|
err = this.MCompModel.Init(service, module, comp, options)
|
|
this.TableName = comm.TableSociaty
|
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
|
Keys: bsonx.Doc{{Key: "_id", Value: bsonx.Int32(1)}},
|
|
})
|
|
this.DB.CreateIndex(core.SqlTable(this.TableName), mongo.IndexModel{
|
|
Keys: bsonx.Doc{{Key: "name", Value: bsonx.Int32(1)}},
|
|
})
|
|
this.module = module.(*Sociaty)
|
|
this.service = service
|
|
this.EventApp = event_v2.NewApp()
|
|
this.EventApp.Listen(comm.EventSociatyRankChanged, this.rankDataChanged)
|
|
return
|
|
}
|
|
|
|
// 创建公会
|
|
func (this *ModelSociaty) create(sociaty *pb.DBSociaty) error {
|
|
if sociaty == nil {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyNoFound)
|
|
}
|
|
_id := primitive.NewObjectID().Hex()
|
|
sociaty.Id = _id
|
|
sociaty.Ctime = configure.Now().Unix()
|
|
sociaty.Lv = 1 //默认1级
|
|
if sociaty.Icon == "" {
|
|
sociaty.Icon = "1000" //默认图标
|
|
}
|
|
if sociaty.ApplyLv == 0 {
|
|
sociaty.ApplyLv = 1 //默认玩家入会等级
|
|
}
|
|
return this.AddList(comm.RDS_EMPTY, sociaty.Id, sociaty)
|
|
}
|
|
|
|
// 公会名是否存在
|
|
func (this *ModelSociaty) isNameExist(name string) error {
|
|
var sociaties []*pb.DBSociaty
|
|
if err := this.GetList(comm.RDS_EMPTY, &sociaties); err != nil {
|
|
return err
|
|
}
|
|
for _, s := range sociaties {
|
|
if s.Name == name {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyNameExist)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 公会列表
|
|
func (this *ModelSociaty) list(uid string, filter pb.SociatyListFilter) (list []*pb.DBSociaty) {
|
|
user := this.module.ModuleUser.GetUser(uid)
|
|
|
|
if user == nil {
|
|
return
|
|
}
|
|
|
|
logFields := []log.Field{{Key: "uid", Value: uid}, {Key: "filter", Value: filter}}
|
|
switch filter {
|
|
case pb.SociatyListFilter_ALL: //所有
|
|
if err := this.GetList("", &list); err != nil {
|
|
log.Error("公会列表", logFields...)
|
|
return
|
|
}
|
|
case pb.SociatyListFilter_CONDI: //满足条件
|
|
//玩家等级大于等于公会的申请等级限制
|
|
if err := this.GetList("", &list); err != nil {
|
|
log.Error("公会列表", logFields...)
|
|
return
|
|
}
|
|
var newList []*pb.DBSociaty
|
|
for _, v := range list {
|
|
if user.Lv >= v.ApplyLv {
|
|
newList = append(newList, v)
|
|
}
|
|
}
|
|
return newList
|
|
case pb.SociatyListFilter_NOAPPLY: //无需审批
|
|
filter := bson.M{
|
|
"isApplyCheck": false,
|
|
}
|
|
cur, err := this.DB.Find(comm.TableSociaty, filter)
|
|
for cur.Next(context.TODO()) {
|
|
sociaty := &pb.DBSociaty{}
|
|
if err = cur.Decode(sociaty); err == nil {
|
|
list = append(list, sociaty)
|
|
}
|
|
}
|
|
case pb.SociatyListFilter_APPLYING: //申请中
|
|
if err := this.GetList("", &list); err != nil {
|
|
log.Error("公会列表", logFields...)
|
|
return
|
|
}
|
|
|
|
var newList []*pb.DBSociaty
|
|
for _, v := range list {
|
|
for _, apply := range v.ApplyRecord {
|
|
if apply.Uid == uid {
|
|
newList = append(newList, v)
|
|
}
|
|
}
|
|
}
|
|
return newList
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 搜索公会
|
|
func (this *ModelSociaty) findByName(name string) *pb.DBSociaty {
|
|
filter := bson.M{
|
|
"name": name,
|
|
}
|
|
sr := this.DB.FindOne(comm.TableSociaty, filter)
|
|
sociaty := &pb.DBSociaty{}
|
|
if err := sr.Decode(sociaty); err != nil {
|
|
if err != mongo.ErrNoDocuments {
|
|
return nil
|
|
}
|
|
}
|
|
return sociaty
|
|
}
|
|
|
|
// 获取公会
|
|
func (this *ModelSociaty) getSociaty(sociatyId string) (sociaty *pb.DBSociaty) {
|
|
sociaty = &pb.DBSociaty{}
|
|
if err := this.GetListObj(comm.RDS_EMPTY, sociatyId, sociaty); err != nil {
|
|
log.Error("GetListObj", log.Field{Key: "sociatyId", Value: sociatyId})
|
|
return nil
|
|
}
|
|
if sociaty.Id == "" {
|
|
return nil
|
|
}
|
|
return
|
|
}
|
|
|
|
// 公会是否解散
|
|
func (this *ModelSociaty) isDismiss(sociaty *pb.DBSociaty) bool {
|
|
if sociaty.DismissTime == 0 {
|
|
return false
|
|
}
|
|
if utils.IsInCDHour(sociaty.DismissTime) {
|
|
return false
|
|
} else {
|
|
if err := this.dismiss(sociaty); err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
}
|
|
|
|
// 获取玩家所在的公会
|
|
func (this *ModelSociaty) getUserSociaty(uid string) (sociaty *pb.DBSociaty) {
|
|
var (
|
|
userEx *pb.DBUserExpand
|
|
err error
|
|
)
|
|
if this.module.IsCross() {
|
|
userEx, err = this.module.ModuleUser.GetUserExpand(uid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if userEx.SociatyId != "" {
|
|
sociaty = this.getSociaty(userEx.SociatyId)
|
|
if sociaty != nil {
|
|
//验证是否解散
|
|
if this.isDismiss(sociaty) {
|
|
sociaty.Id = ""
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
userEx, err = this.module.ModuleUser.GetUserExpand(uid)
|
|
if err != nil {
|
|
return
|
|
}
|
|
if userEx.SociatyId != "" {
|
|
sociaty = &pb.DBSociaty{}
|
|
if err = this.module.service.AcrossClusterRpcCall(
|
|
context.Background(),
|
|
this.module.GetCrossTag(),
|
|
comm.Service_Worker,
|
|
string(comm.Rpc_ModuleSociaty),
|
|
pb.RPCGeneralReqA1{Param1: userEx.SociatyId},
|
|
sociaty); err != nil {
|
|
this.module.Errorln(err)
|
|
}
|
|
this.module.Debug("跨服获取公会信息", log.Field{Key: "uid", Value: uid}, log.Field{Key: "sociatyId", Value: sociaty.Id})
|
|
}
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 申请公会
|
|
func (this *ModelSociaty) apply(uid string, sociaty *pb.DBSociaty) (isCheck bool, err error) {
|
|
// 判断公会审批设置
|
|
if sociaty.IsApplyCheck { //需要审核
|
|
isCheck = true
|
|
sociaty.ApplyRecord = append(sociaty.ApplyRecord, &pb.ApplyRecord{
|
|
Uid: uid,
|
|
Ctime: configure.Now().Unix(),
|
|
})
|
|
update := map[string]interface{}{
|
|
"applyRecord": sociaty.ApplyRecord,
|
|
}
|
|
err = this.updateSociaty(sociaty.Id, update)
|
|
} else { //无需审核直接入会
|
|
if err := this.addMember(uid, sociaty); err != nil {
|
|
return isCheck, err
|
|
}
|
|
//初始玩家公会任务
|
|
this.module.modelSociatyTask.initSociatyTask(uid, sociaty.Id)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 设置公会
|
|
func (this *ModelSociaty) setting(sociaty *pb.DBSociaty) error {
|
|
update := map[string]interface{}{
|
|
"icon": sociaty.Icon,
|
|
"notice": sociaty.Notice,
|
|
"isApplyCheck": sociaty.IsApplyCheck,
|
|
"applyLv": sociaty.ApplyLv,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 申请撤销
|
|
func (this *ModelSociaty) applyCancel(uid string, sociaty *pb.DBSociaty) error {
|
|
return this.delFromApplyRecord(uid, sociaty)
|
|
}
|
|
|
|
// 是否已申请
|
|
func (this *ModelSociaty) isApplied(uid string, sociaty *pb.DBSociaty) bool {
|
|
for _, v := range sociaty.ApplyRecord {
|
|
if v.Uid == uid {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 申请列表
|
|
func (this *ModelSociaty) applyList(sociaty *pb.DBSociaty) (list []*pb.SociatyMemberInfo) {
|
|
for _, r := range sociaty.ApplyRecord {
|
|
user := this.module.ModuleUser.GetUser(r.Uid)
|
|
if user == nil {
|
|
continue
|
|
}
|
|
|
|
list = append(list, &pb.SociatyMemberInfo{
|
|
Uid: user.Uid,
|
|
Name: user.Name,
|
|
Avatar: user.Avatar,
|
|
Lv: user.Lv,
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
// 是否公会成员
|
|
func (this *ModelSociaty) isMember(uid string, sociaty *pb.DBSociaty) bool {
|
|
for _, m := range sociaty.Members {
|
|
if m.Uid == uid {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func (this *ModelSociaty) isInJobs(job pb.SociatyJob, jobs ...pb.SociatyJob) bool {
|
|
for _, j := range jobs {
|
|
if j == job {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 是否有执行权限
|
|
func (this *ModelSociaty) isRight(uid string, sociaty *pb.DBSociaty, jobs ...pb.SociatyJob) bool {
|
|
for _, m := range sociaty.Members {
|
|
if m.Uid == uid {
|
|
return this.isInJobs(m.Job, jobs...)
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 更新公会
|
|
func (this *ModelSociaty) updateSociaty(sociatyId string, update map[string]interface{}) error {
|
|
if this.module.IsCross() {
|
|
return this.ChangeList(comm.RDS_EMPTY, sociatyId, update)
|
|
} else {
|
|
req := &SociatyUpdateParam{
|
|
SociatyId: sociatyId,
|
|
Update: update,
|
|
}
|
|
if err := this.module.service.AcrossClusterRpcCall(
|
|
context.Background(),
|
|
this.module.GetCrossTag(),
|
|
comm.Service_Worker,
|
|
string(comm.Rpc_ModuleSociatyUpdate),
|
|
req,
|
|
&pb.EmptyResp{}); err != nil {
|
|
this.module.Errorln(err)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 退出公会
|
|
func (this *ModelSociaty) quit(uid string, sociaty *pb.DBSociaty) error {
|
|
for i := 0; i < len(sociaty.Members); i++ {
|
|
if sociaty.Members[i].Uid == uid {
|
|
sociaty.Members = append(sociaty.Members[:i], sociaty.Members[i+1:]...)
|
|
i--
|
|
}
|
|
}
|
|
update := map[string]interface{}{
|
|
"members": sociaty.Members,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 解散公会
|
|
func (this *ModelSociaty) dismiss(sociaty *pb.DBSociaty) error {
|
|
if err := this.memberClear(sociaty); err != nil {
|
|
return err
|
|
}
|
|
if err := this.DelListlds("", []string{sociaty.Id}); err != nil {
|
|
return err
|
|
}
|
|
//推送
|
|
this.module.SendMsgToUsers(
|
|
string(this.module.GetType()),
|
|
"pdismiss",
|
|
&pb.SociatyPDismissPush{SociatyId: sociaty.Id},
|
|
this.getMemberIds(sociaty)...)
|
|
//发邮件
|
|
this.sendMail("GuildDissolution", []string{sociaty.Name}, this.getMemberIds(sociaty))
|
|
|
|
return nil
|
|
}
|
|
|
|
// 删除请求记录
|
|
func (this *ModelSociaty) delFromApplyRecord(uid string, sociaty *pb.DBSociaty) error {
|
|
for i := 0; i < len(sociaty.ApplyRecord); i++ {
|
|
if sociaty.ApplyRecord[i].Uid == uid {
|
|
sociaty.ApplyRecord = append(sociaty.ApplyRecord[:i], sociaty.ApplyRecord[i+1:]...)
|
|
i--
|
|
}
|
|
}
|
|
update := map[string]interface{}{
|
|
"applyRecord": sociaty.ApplyRecord,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 添加成员
|
|
func (this *ModelSociaty) addMember(uid string, sociaty *pb.DBSociaty) error {
|
|
if int32(len(sociaty.Members)) >= this.getMemberMax(sociaty) {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyMemberCountLimit)
|
|
}
|
|
sociaty.Members = append(sociaty.Members, &pb.SociatyMember{
|
|
Uid: uid,
|
|
Job: pb.SociatyJob_MEMBER,
|
|
Ctime: configure.Now().Unix(),
|
|
})
|
|
update := map[string]interface{}{
|
|
"members": sociaty.Members,
|
|
}
|
|
if err := this.updateSociaty(sociaty.Id, update); err != nil {
|
|
return err
|
|
}
|
|
|
|
// 更新玩家公会
|
|
updateEx := map[string]interface{}{
|
|
"sociatyId": sociaty.Id,
|
|
}
|
|
if err := this.module.ModuleUser.ChangeUserExpand(uid, updateEx); err != nil {
|
|
return err
|
|
}
|
|
|
|
// 记录日志
|
|
this.module.modelSociatyLog.addLog(Log_Add, sociaty.Id, uid)
|
|
return nil
|
|
}
|
|
|
|
// 发邮件给公会成员
|
|
func (this *ModelSociaty) sendMail(confId string, params []string, receiver []string) error {
|
|
if module, err := this.service.GetModule(comm.ModuleMail); err == nil {
|
|
if mail, ok := module.(comm.Imail); ok {
|
|
mail.SendNewMail(&pb.DBMailData{
|
|
Cid: confId,
|
|
Param: params,
|
|
}, receiver...)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 成员列表
|
|
func (this *ModelSociaty) members(sociaty *pb.DBSociaty) (list []*pb.SociatyMemberInfo) {
|
|
for _, m := range sociaty.Members {
|
|
user := this.module.ModuleUser.GetUser(m.Uid)
|
|
if user == nil {
|
|
continue
|
|
}
|
|
list = append(list, &pb.SociatyMemberInfo{
|
|
Uid: user.Uid,
|
|
Name: user.Name,
|
|
Avatar: user.Avatar,
|
|
Lv: user.Lv,
|
|
Job: m.Job,
|
|
OfflineTime: user.Offlinetime,
|
|
})
|
|
}
|
|
return
|
|
}
|
|
|
|
// 成员IDs
|
|
func (this *ModelSociaty) getMemberIds(sociaty *pb.DBSociaty) (ids []string) {
|
|
for _, m := range sociaty.Members {
|
|
ids = append(ids, m.Uid)
|
|
}
|
|
return
|
|
}
|
|
|
|
// 获取成员信息
|
|
func (this *ModelSociaty) getMemberInfo(sociaty *pb.DBSociaty, uid string) *pb.SociatyMember {
|
|
for _, s := range sociaty.Members {
|
|
if s.Uid == uid {
|
|
return s
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 同意
|
|
func (this *ModelSociaty) agree(uid string, sociaty *pb.DBSociaty) error {
|
|
if this.isMember(uid, sociaty) {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyBelongTo)
|
|
}
|
|
|
|
// 判断改用户是否在申请记录中
|
|
var flag bool
|
|
for _, r := range sociaty.GetApplyRecord() {
|
|
if r.Uid == uid {
|
|
flag = true
|
|
break
|
|
}
|
|
}
|
|
if !flag {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyApplyCancel)
|
|
}
|
|
|
|
//删除申请记录
|
|
if err := this.delFromApplyRecord(uid, sociaty); err != nil {
|
|
return err
|
|
}
|
|
|
|
//添加成员
|
|
if err := this.addMember(uid, sociaty); err != nil {
|
|
return err
|
|
}
|
|
|
|
//初始玩家公会任务
|
|
return this.module.modelSociatyTask.initSociatyTask(uid, sociaty.Id)
|
|
}
|
|
|
|
// 拒绝
|
|
func (this *ModelSociaty) refuse(uid string, sociaty *pb.DBSociaty) error {
|
|
return this.delFromApplyRecord(uid, sociaty)
|
|
}
|
|
|
|
// 转让公会
|
|
// targetId 目标玩家ID
|
|
// srcId 玩家ID 会长
|
|
func (this *ModelSociaty) assign(srcId, targetId string, sociaty *pb.DBSociaty) error {
|
|
for _, m := range sociaty.Members {
|
|
if m.Uid == srcId {
|
|
m.Uid = targetId
|
|
} else if m.Uid == targetId {
|
|
m.Uid = srcId
|
|
}
|
|
}
|
|
update := map[string]interface{}{
|
|
"members": sociaty.Members,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 踢出公会
|
|
// targetId 踢出目标
|
|
// 不允许踢出会长
|
|
func (this *ModelSociaty) discharge(targetId string, sociaty *pb.DBSociaty) error {
|
|
for i := 0; i < len(sociaty.Members); i++ {
|
|
if sociaty.Members[i].Uid == targetId {
|
|
if sociaty.Members[i].Job == pb.SociatyJob_PRESIDENT {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyMasterNoDiss)
|
|
}
|
|
sociaty.Members = append(sociaty.Members[:i], sociaty.Members[i+1:]...)
|
|
i--
|
|
}
|
|
}
|
|
update := map[string]interface{}{
|
|
"members": sociaty.Members,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 获取职位数
|
|
func (this *ModelSociaty) getJobCount(job pb.SociatyJob, sociaty *pb.DBSociaty) (count int) {
|
|
for _, m := range sociaty.Members {
|
|
if m.Job == job {
|
|
count++
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// 设置职位
|
|
func (this *ModelSociaty) settingJob(targetId string, job pb.SociatyJob, sociaty *pb.DBSociaty) error {
|
|
for _, m := range sociaty.Members {
|
|
if m.Uid == targetId {
|
|
m.Job = job
|
|
}
|
|
}
|
|
update := map[string]interface{}{
|
|
"members": sociaty.Members,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 获取会长信息
|
|
func (this *ModelSociaty) getMasterInfo(sociaty *pb.DBSociaty) *pb.SociatyMemberInfo {
|
|
for _, m := range sociaty.Members {
|
|
if m.Job == pb.SociatyJob_PRESIDENT {
|
|
user := this.module.ModuleUser.GetUser(m.Uid)
|
|
if user == nil {
|
|
continue
|
|
}
|
|
return &pb.SociatyMemberInfo{
|
|
Uid: user.Uid,
|
|
Name: user.Name,
|
|
Lv: user.Lv,
|
|
Avatar: user.Avatar,
|
|
OfflineTime: user.Offlinetime,
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 弹劾会长
|
|
func (this *ModelSociaty) accuse(sociaty *pb.DBSociaty) error {
|
|
master := this.getMasterInfo(sociaty)
|
|
if master == nil {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyNoMaster)
|
|
}
|
|
|
|
user := this.module.ModuleUser.GetUser(master.Uid)
|
|
if user == nil {
|
|
return comm.NewCustomError(pb.ErrorCode_UserSessionNobeing)
|
|
}
|
|
|
|
globalCnf := this.module.globalConf
|
|
|
|
//会长离线时间
|
|
now := configure.Now().Unix()
|
|
left := now - user.Offlinetime
|
|
if left < int64(globalCnf.GuildInitiateImpeachmentTime*3600) || user.Offlinetime == 0 {
|
|
return comm.NewCustomError(pb.ErrorCode_SociatyNoAccuse)
|
|
} else {
|
|
//更新会长的弹劾倒计时时间
|
|
update := map[string]interface{}{
|
|
"accuseTime": utils.AddHour(int(globalCnf.GuildImpeachmentCountDown)).Unix(),
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
}
|
|
|
|
// 弹劾倒计时判断
|
|
// 会长在截至时间前进入公会终止弹劾,否则进行新会长选举
|
|
// srcMasterId 原会长ID
|
|
func (this *ModelSociaty) extendJob(srcMasterId string, sociaty *pb.DBSociaty) error {
|
|
if sociaty.AccuseTime != 0 {
|
|
//会长在截至时间前进入公会终止弹劾
|
|
now := configure.Now().Unix()
|
|
if now < sociaty.AccuseTime {
|
|
update := map[string]interface{}{
|
|
"accuseTime": 0,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
} else {
|
|
//选举新会长
|
|
if err := this.electNewMaster(srcMasterId, sociaty); err != nil {
|
|
return err
|
|
}
|
|
//会长降为普通成员
|
|
if err := this.settingJob(srcMasterId, pb.SociatyJob_MEMBER, sociaty); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 选举新会长
|
|
func (this *ModelSociaty) electNewMaster(srcMasterId string, sociaty *pb.DBSociaty) error {
|
|
vpIds := []*pb.SociatyMember{} // 副会长
|
|
aIds := []*pb.SociatyMember{} //管理员
|
|
mIds := []*pb.SociatyMember{} //普通成员
|
|
|
|
for _, m := range sociaty.Members {
|
|
if m.Uid != srcMasterId {
|
|
if m.Job == pb.SociatyJob_VICEPRESIDENT {
|
|
vpIds = append(vpIds, m)
|
|
} else if m.Job == pb.SociatyJob_ADMIN {
|
|
aIds = append(aIds, m)
|
|
} else if m.Job == pb.SociatyJob_MEMBER {
|
|
mIds = append(mIds, m)
|
|
}
|
|
}
|
|
}
|
|
|
|
elect := func(data []*pb.SociatyMember) error {
|
|
if len(data) == 1 {
|
|
return this.settingJob(data[0].Uid, pb.SociatyJob_PRESIDENT, sociaty)
|
|
} else if len(data) > 1 {
|
|
//从数组中找到最大的贡献值,并标识数量
|
|
maxNum := data[0]
|
|
maxCount := 0 //最大的贡献值数量
|
|
maxIndex := 0 //最大贡献值的索引
|
|
|
|
for i := 1; i < len(data); i++ {
|
|
if data[i].Contribution > maxNum.Contribution {
|
|
maxNum = data[i]
|
|
maxIndex = i
|
|
} else if data[i].Contribution == maxNum.Contribution {
|
|
maxCount++
|
|
}
|
|
}
|
|
if maxCount >= 1 { //有两个以上的最大值
|
|
//比较时间 升序,先加入公会的人有优先候选权
|
|
sort.SliceStable(data, func(i, j int) bool {
|
|
return data[i].Ctime < data[j].Ctime
|
|
})
|
|
//取第一个值
|
|
return this.settingJob(data[0].Uid, pb.SociatyJob_PRESIDENT, sociaty)
|
|
} else {
|
|
return this.settingJob(data[maxIndex].Uid, pb.SociatyJob_PRESIDENT, sociaty)
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 以下按照职位大小依次调用
|
|
if len(vpIds) > 0 {
|
|
return elect(vpIds)
|
|
}
|
|
|
|
if len(aIds) > 0 {
|
|
return elect(aIds)
|
|
}
|
|
|
|
if len(mIds) > 0 {
|
|
return elect(mIds)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// 签到
|
|
func (this *ModelSociaty) sign(uid string, sociaty *pb.DBSociaty) error {
|
|
|
|
sociaty.SignIds = append(sociaty.SignIds, uid)
|
|
|
|
update := map[string]interface{}{
|
|
"signIds": sociaty.SignIds,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 是否已签到
|
|
// 已签到true 未签到false
|
|
func (this *ModelSociaty) IsSign(uid string, sociaty *pb.DBSociaty) bool {
|
|
if _, ok := utils.Findx(sociaty.SignIds, uid); ok {
|
|
return ok
|
|
}
|
|
return false
|
|
}
|
|
|
|
// 获取玩家任务列表
|
|
func (this *ModelSociaty) getUserTaskList(uid, sociatyId string) (sociatyTask *pb.DBSociatyTask) {
|
|
sociatyTask = &pb.DBSociatyTask{}
|
|
this.GetListObj(sociatyId, uid, sociatyTask)
|
|
return
|
|
}
|
|
|
|
// 更新公会资源 活跃度、经验
|
|
func (this *ModelSociaty) updateResourceFromTask(sociaty *pb.DBSociaty, conf *cfg.GameGuildTaskData) error {
|
|
if conf == nil {
|
|
return errors.New("配置未找到")
|
|
}
|
|
exp := sociaty.Exp //经验
|
|
activity := sociaty.Activity //活跃度
|
|
|
|
for _, v := range conf.SociatyReward {
|
|
if v.T == "guildactive" {
|
|
activity += v.N
|
|
} else if v.T == "guildexp" {
|
|
exp += v.N
|
|
}
|
|
}
|
|
update := map[string]interface{}{
|
|
"exp": exp,
|
|
"activity": activity,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 更新经验
|
|
func (this *ModelSociaty) updateSociatyExp(val int32, sociaty *pb.DBSociaty) error {
|
|
exp := sociaty.Exp //经验
|
|
exp += val
|
|
update := map[string]interface{}{
|
|
"exp": exp,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
// 更新成员贡献值
|
|
// 任务领取时更新
|
|
func (this *ModelSociaty) updateMemberContribution(uid string, val int32, sociaty *pb.DBSociaty) error {
|
|
for _, m := range sociaty.Members {
|
|
if m.Uid == uid {
|
|
m.Contribution += val
|
|
break
|
|
}
|
|
}
|
|
|
|
update := map[string]interface{}{
|
|
"members": sociaty.Members,
|
|
}
|
|
return this.updateSociaty(sociaty.Id, update)
|
|
}
|
|
|
|
func (this *ModelSociaty) sort(list []*pb.DBSociatyRank) []*pb.DBSociatyRank {
|
|
sort.SliceStable(list, func(i, j int) bool {
|
|
if list[i].Lv == list[j].Lv {
|
|
if list[i].Activity == list[j].Activity {
|
|
return list[i].Ctime > list[j].Ctime
|
|
} else {
|
|
return list[i].Activity > list[j].Activity
|
|
}
|
|
}
|
|
return list[i].Lv > list[j].Lv
|
|
})
|
|
return list
|
|
}
|
|
|
|
// 公会等级变化
|
|
// 更新排行榜
|
|
func (this *ModelSociaty) rankDataChanged(event interface{}, next func(event interface{})) {
|
|
var list []*pb.DBSociatyRank
|
|
if err := this.GetList("", &list); err != nil {
|
|
log.Errorf("sociaty list err:%v", err)
|
|
return
|
|
}
|
|
|
|
data := event.(*SociatyListen)
|
|
if data.sociaty == nil {
|
|
return
|
|
}
|
|
|
|
newRank := &pb.DBSociatyRank{
|
|
SociatyId: data.sociaty.Id,
|
|
Name: data.sociaty.Name,
|
|
Lv: data.sociaty.Lv,
|
|
Activity: data.sociaty.Activity,
|
|
Ctime: data.sociaty.Ctime,
|
|
}
|
|
if len(list) == 0 || len(list) > 0 && len(list) < 20 {
|
|
if data != nil {
|
|
this.AddList("", data.sociaty.Id, newRank)
|
|
}
|
|
} else {
|
|
this.AddList("", data.sociaty.Id, newRank)
|
|
if err := this.GetList("", &list); err != nil {
|
|
log.Errorf("sociaty list err:%v", err)
|
|
return
|
|
}
|
|
// 排名
|
|
tmp := this.sort(list)
|
|
//找出20条之后的数据
|
|
lastData := append(tmp[:19], tmp[len(tmp)-1:]...)
|
|
//删除20之后的数据
|
|
delIds := []string{}
|
|
for _, v := range lastData {
|
|
delIds = append(delIds, v.SociatyId)
|
|
}
|
|
this.DelListlds("", delIds)
|
|
}
|
|
}
|
|
|
|
// 排行榜列表(活跃度)
|
|
func (this *ModelSociaty) rank() (rank []*pb.DBSociatyRank) {
|
|
var list []*pb.DBSociaty
|
|
if err := this.GetList("", &list); err != nil {
|
|
this.module.Error("公会列表", log.Field{Key: "err", Value: err.Error()})
|
|
return nil
|
|
}
|
|
|
|
for _, v := range list {
|
|
rank = append(rank, &pb.DBSociatyRank{
|
|
Name: v.Name,
|
|
Lv: v.Lv,
|
|
Activity: v.Activity,
|
|
Ctime: v.Ctime,
|
|
})
|
|
}
|
|
|
|
rank = this.sort(rank)
|
|
|
|
// 只取前20条数据
|
|
if len(rank) > 20 {
|
|
rank = append(rank[:0], rank[19:]...)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
// 等级更新
|
|
func (this *ModelSociaty) changeLv(sociaty *pb.DBSociaty) error {
|
|
ggl, err := this.module.configure.getSociatyLvCfg()
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if ggl == nil {
|
|
return errors.New("sociatyLvConf is nil")
|
|
}
|
|
|
|
curLv := sociaty.Lv
|
|
update := map[string]interface{}{}
|
|
|
|
lv := curLv + 1
|
|
if conf, ok := ggl.GetDataMap()[lv]; ok {
|
|
if sociaty.Exp > conf.Exp {
|
|
update["lv"] = lv
|
|
}
|
|
}
|
|
|
|
if len(update) > 0 {
|
|
if err = this.updateSociaty(sociaty.Id, update); err != nil {
|
|
return err
|
|
}
|
|
// 更新排行榜
|
|
this.EventApp.Dispatch(comm.EventSociatyRankChanged, &SociatyListen{
|
|
sociaty: sociaty,
|
|
})
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// 获取可容纳的最大上限
|
|
func (this *ModelSociaty) getMemberMax(sociaty *pb.DBSociaty) int32 {
|
|
ggl, err := this.module.configure.getSociatyLvCfg()
|
|
if err != nil {
|
|
return 0
|
|
}
|
|
|
|
if ggl == nil {
|
|
return 0
|
|
}
|
|
|
|
if conf, ok := ggl.GetDataMap()[sociaty.Lv]; ok {
|
|
return conf.MemberMax
|
|
}
|
|
return 0
|
|
}
|
|
|
|
// 成员退出清理
|
|
func (this *ModelSociaty) memberClear(sociaty *pb.DBSociaty) error {
|
|
// 邮件接收人
|
|
var receiver []string
|
|
for _, m := range sociaty.Members {
|
|
receiver = append(receiver, m.Uid)
|
|
//清除成员任务
|
|
if err := this.module.modelSociatyTask.deleTask(sociaty.Id, m.Uid); err != nil {
|
|
log.Errorf("删除玩家 uid:%s 公会 sociatyId:%s err:%v", m.Uid, sociaty.Id, err)
|
|
}
|
|
|
|
//清除玩家sociatyId
|
|
update := map[string]interface{}{
|
|
"sociatyId": "", //公会ID置空
|
|
}
|
|
if err := this.module.ModuleUser.ChangeUserExpand(m.Uid, update); err != nil {
|
|
log.Errorf("更新玩家公会ID err:%v", err)
|
|
}
|
|
|
|
//清除公会日志
|
|
if err := this.module.modelSociatyLog.logDelete(sociaty.Id); err != nil {
|
|
log.Errorf("删除公会日志 sociatyId:%s err:%v", sociaty.Id, err)
|
|
}
|
|
}
|
|
//发送邮件
|
|
// if err := this.moduleSociaty.modelSociaty.sendMail(receiver); err != nil {
|
|
// log.Errorf("邮件发送失败 sociatyId: %s err:%v", sociaty.Id, err)
|
|
// }
|
|
return nil
|
|
}
|
|
|
|
// 清理签到数据
|
|
func (s *ModelSociaty) clearSigned(sociaty *pb.DBSociaty) error {
|
|
lastSignCount := len(sociaty.SignIds)
|
|
update := map[string]interface{}{
|
|
"lastSignCount": lastSignCount,
|
|
"signIds": []string{},
|
|
}
|
|
return s.updateSociaty(sociaty.Id, update)
|
|
}
|