package model import ( "rocommon/rpc" "rocommon/service" "rocommon/util" "roserver/baseserver/model" dbmodel "roserver/db/model" "roserver/serverproto" "sort" "strconv" "sync" "time" ) type WebMailItemInfo struct { Id int32 Title string Content string RewardList []*serverproto.KeyValueType SendDate time.Time } type MailUpdateMag struct { addMutex sync.RWMutex sendMailList map[int32]*serverproto.WebUpdateMailItem bInit bool mailMaxNum int32 } func newMailUpdateMag() *MailUpdateMag { mag := &MailUpdateMag{ sendMailList: map[int32]*serverproto.WebUpdateMailItem{}, } return mag } func (this *MailUpdateMag) AttachMail2Update(id int, uidList []uint64, title, content string, sendTime uint64, rewardList []*serverproto.KeyValueType) { addMail := &serverproto.WebUpdateMailItem{ Id: int32(id), UidList: uidList, Title: title, Content: content, SendDate: sendTime, RewardList: rewardList, } if len(addMail.UidList) > 0 { //gm个人邮件 addMail.MailType = int32(serverproto.MailType_MailType_GM_Self) } else { //gm全局邮件 addMail.MailType = int32(serverproto.MailType_MailType_GM) } this.addMutex.Lock() //if id != 0 { // this.sendMailList[addMail.Id] = addMail //} else { // this.mailMaxNum++ // addMail.Id = this.mailMaxNum // this.sendMailList[addMail.Id] = addMail //} this.mailMaxNum++ addMail.Id = this.mailMaxNum this.sendMailList[addMail.Id] = addMail this.addMail2Redis(addMail) this.addMutex.Unlock() } func (this *MailUpdateMag) DelMailItem(id int) { this.addMutex.Lock() delete(this.sendMailList, int32(id)) this.addMutex.Unlock() } func (this *MailUpdateMag) GetMailList() []WebMailItemInfo { var mailList []WebMailItemInfo this.addMutex.Lock() for _, val := range this.sendMailList { tmpMail := WebMailItemInfo{ Id: val.Id, Title: val.Title, Content: val.Content, RewardList: val.RewardList, SendDate: util.GetTimeByUint64(val.SendDate), } mailList = append(mailList, tmpMail) } this.addMutex.Unlock() sort.Slice(mailList, func(i, j int) bool { return mailList[i].Id < mailList[j].Id }) return mailList } func (this *MailUpdateMag) Update(ms uint64) { if !this.bInit { if !this.loadMailFromRedis() { return } this.bInit = true } var delMailList []int32 this.addMutex.RLock() nowTime := util.GetTimeMilliseconds() for _, item := range this.sendMailList { //发送邮件 if item.SendDate == 0 || item.SendDate <= nowTime { ssMsg := &serverproto.SSWebGMAddMailNtf{ MailInfo: item, } //发送给全体玩家 if len(item.UidList) <= 0 { this.addMail2RedisForUser(item) } //发送给social,给在线玩家发送邮件,不在线玩家添加到db SendSocial(ssMsg) delete(this.sendMailList, item.Id) delMailList = append(delMailList, item.Id) } } this.addMutex.RUnlock() this.delMail2Redis(delMailList) } const WEB_MAILP_REFIX = "webmail_" const WEB_MAIL_MAXID_FIELD_PREFIX = "webmaxid" func (this *MailUpdateMag) loadMailFromRedis() bool { retList, err := service.GetRedis().HGetAll(WEB_MAILP_REFIX).Result() if err != nil && err != service.NIL { return false } for key, val := range retList { if key == WEB_MAIL_MAXID_FIELD_PREFIX { tmpId, _ := model.Str2Num(val) if tmpId > 0 { this.mailMaxNum = int32(tmpId) } } else { //mailInfo := &serverproto.WebUpdateMailItem{} //err := model.GetDecodeMessage(mailInfo, val) //if err == nil { // this.sendMailList[mailInfo.Id] = mailInfo //} } } globalMaiList, err := service.GetRedis().LRange(dbmodel.RoleGlobalMailListPrefix, 0, -1).Result() if err != nil { return true } for idx := 0; idx < len(globalMaiList); idx++ { gmId, _ := model.Str2Num(globalMaiList[idx]) if gmId <= 0 { continue } if gmId > int(this.mailMaxNum) { this.mailMaxNum = int32(gmId) } } return true } func (this *MailUpdateMag) addMail2Redis(mailInfo *serverproto.WebUpdateMailItem) { if mailInfo.Id <= 0 { return } value := strconv.Itoa(int(mailInfo.Id)) //strconv.Atoi() err, msgStr := model.GetEncodeMessage(mailInfo) if err != nil { return } service.GetRedis().HSet(WEB_MAILP_REFIX, WEB_MAIL_MAXID_FIELD_PREFIX, this.mailMaxNum) _, err = service.GetRedis().HSet(WEB_MAILP_REFIX, value, msgStr).Result() if err != nil { return } } func (this *MailUpdateMag) delMail2Redis(mailIdList []int32) { for idx := 0; idx < len(mailIdList); idx++ { value := strconv.Itoa(int(mailIdList[idx])) service.GetRedis().HDel(WEB_MAILP_REFIX, value) } } func (this *MailUpdateMag) addMail2RedisForUser(mailInfo *serverproto.WebUpdateMailItem) { //放到redis中,玩家上线时获取比玩家记录的id大的所有邮件 value := strconv.Itoa(int(mailInfo.Id)) err, msgStr := model.GetEncodeMessage(mailInfo) if err != nil { return } _, err1 := service.GetRedis().LPush(dbmodel.RoleGlobalMailListPrefix, value).Result() if err1 != nil { util.ErrorF("addMail2RedisForUser err1=%v", err1) return } mailKeyStr := dbmodel.RoleGlobalMailPrefix + value //添加过期时间 _, err2 := service.GetRedis().Set(mailKeyStr, msgStr, time.Hour*24*30).Result() //_, err2 := service.GetRedis().Set(mailKeyStr, msgStr, time.Second*10).Result() if err2 != nil { util.ErrorF("addMail2RedisForUser err2=%v", err2) } } ////////////////////// func SendSocial(msg interface{}) { data, meta, err := rpc.EncodeMessage(msg) if err != nil { util.InfoF("SendSocial EncodeMessage err=%v,msg=%v", err, msg) return } socialNode := model.SelectServiceNode(model.SERVICE_NODE_TYPE_SOCIAL_STR, 0) socialSess := model.GetServiceNode(socialNode) if socialSess == nil { util.InfoF("SendSocial social session not exist socialnode=%v", socialSess) } else { socialSess.Send(&serverproto.ServiceTransmitAck{ MsgId: uint32(meta.ID), MsgData: data, }) } }