package mail import ( "f1-game/internal/code" "f1-game/internal/data" "f1-game/internal/enum" "f1-game/internal/event" nameLocal "f1-game/internal/name/local" nameRemote "f1-game/internal/name/remote" nameRoute "f1-game/internal/name/route" "f1-game/internal/pb" "f1-game/internal/sessions" "f1-game/internal/types" "f1-game/nodes/game/internal/db" dbMail "f1-game/nodes/game/internal/db/data/mail" "f1-game/nodes/game/player/asset" ao "f1-game/nodes/game/player/asset/origin" ctime "github.com/cherry-game/cherry/extend/time" clog "github.com/cherry-game/cherry/logger" "github.com/cherry-game/cherry/net/parser/pomelo" cproto "github.com/cherry-game/cherry/net/proto" ) type actorMail struct { pomelo.ActorBase } func (p *actorMail) OnInit() { p.Local().Register(nameLocal.Mail_TakeReward, p.takeReward) p.Local().Register(nameLocal.Mail_TakeAllReward, p.takeAllReward) p.Local().Register(nameLocal.Mail_Read, p.read) p.Local().Register(nameLocal.Mail_Delete, p.delete) p.Remote().Register(nameRemote.Mail_OnLogin, p.onLogin) p.Remote().Register(nameRemote.Mail_Send, p.send) p.Remote().Register(nameRemote.Mail_GetList, p.getMailList) } // takeReward 领取邮件奖励 func (p *actorMail) takeReward(session *cproto.Session, req *pb.I64) { playerID := sessions.GetPlayerID(session) if playerID < 1 { p.ResponseCode(session, code.MailRequestDataError) return } var ( mailTable = db.GetMailTable(playerID) mailID = req.Value ) if mailID < 1 { p.ResponseCode(session, code.MailRequestDataError) return } mailEntity, found := mailTable.Get(mailID) if !found { p.ResponseCode(session, code.MailDataNotFound) return } if mailEntity.IsReward { p.ResponseCode(session, code.MailRewardHadTake) return } if len(mailEntity.Rewards) <= 0 { p.ResponseCode(session, code.MailRewardEmpty) return } retAssets, errCode := asset.Service().Adds(playerID, mailEntity.Rewards, ao.MailGet, true) if code.IsFail(errCode) { p.ResponseCode(session, errCode) return } mailEntity.TakeReward() mailTable.Save2Queue() resp := retAssets.ToAssetListProto() p.Response(session, &resp) } // takeAllReward 一键阅读领取奖励 func (p *actorMail) takeAllReward(session *cproto.Session, _ *pb.None) { playerID := sessions.GetPlayerID(session) if playerID < 1 { p.ResponseCode(session, code.MailRequestDataError) return } var ( mailTable = db.GetMailTable(playerID) mailIDs []int64 addRewards types.Assets isChange = false ) // 领取所有邮件 for _, mailEntity := range mailTable.Data { if mailEntity.CanTakeReward() { addRewards.AddAssets(mailEntity.TakeReward()) mailIDs = append(mailIDs, mailEntity.MailID) mailEntity.IsRead = true isChange = true continue } if !mailEntity.IsRead { mailEntity.IsRead = true mailIDs = append(mailIDs, mailEntity.MailID) isChange = true } } if !isChange { p.ResponseCode(session, code.MailRewardEmpty) return } resp := &pb.TakeMailReward{ MailIDs: mailIDs, } if !addRewards.IsEmpty() { returnAssets, _ := asset.Service().Adds(playerID, addRewards, ao.MailGet, true) resp.List = returnAssets.ToProto() } mailTable.Save2Queue() p.Response(session, resp) } // read 邮件设置已读取 func (p *actorMail) read(session *cproto.Session, req *pb.I64) { playerID := sessions.GetPlayerID(session) if playerID < 1 { p.ResponseCode(session, code.MailRequestDataError) return } var ( mailTable = db.GetMailTable(playerID) mailID = req.Value ) if mailID < 1 { p.ResponseCode(session, code.MailRequestDataError) return } mailEntity, found := mailTable.Get(mailID) if !found { p.ResponseCode(session, code.MailDataNotFound) return } if !mailEntity.IsRead { mailEntity.IsRead = true mailTable.Save2Queue() } p.ResponseCode(session, code.OK) } // delete 请求邮件删除 func (p *actorMail) delete(session *cproto.Session, req *pb.I64) { playerID := sessions.GetPlayerID(session) if playerID < 1 { p.ResponseCode(session, code.MailRequestDataError) return } var ( mailTable = db.GetMailTable(playerID) mailID = req.Value delIDList []int64 ) if mailID > 0 { mailEntity, found := mailTable.Get(mailID) if !found { p.ResponseCode(session, code.MailDataNotFound) return } if !mailEntity.IsRead { p.ResponseCode(session, code.MailNotRead) return } if mailEntity.CanTakeReward() { p.ResponseCode(session, code.MailNotClaim) return } if mailTable.Remove(mailEntity.MailID) { delIDList = append(delIDList, mailEntity.MailID) } } else { mailList := mailTable.GetMailWithType(dbMail.DeletableMailFilter) for _, mailEntity := range mailList { if mailTable.Remove(mailEntity.MailID) { delIDList = append(delIDList, mailEntity.MailID) } } } if len(delIDList) > 0 { // 保存 mailTable.Save2Queue() resp := &pb.I64List{ List: delIDList, } sessions.PushPlayer(playerID, nameRoute.PushGameMail_Delete, resp) clog.Debugf("playerID = %d, delMailID = %+v", playerID, delIDList) } p.ResponseCode(session, code.OK) } // onLogin 登录时检查玩家邮件&下发邮件 func (p *actorMail) onLogin(PlayerLogin *event.PlayerLogin) { var ( now = ctime.Now() playerID = PlayerLogin.PlayerID() ) mailTable := db.GetMailTable(playerID) //检测添加群发邮件 p.checkAndAddBulkMail(mailTable) // 推送邮件列表 p.mailListPush(PlayerLogin.Session(), mailTable, &now) } // send 发送邮件 func (p *actorMail) send(req *pb.SendMail) { if req.ToPlayerID < 1 { clog.Warnf("mail to playerID not found. req = %+v", req) return } if req.TemplateID <= 0 { clog.Warnf("mail template not found. req = %+v", req) return } templateRow, found := data.MailTemplate.GetByID(req.TemplateID) if !found { clog.Warnf("mail template not found. req = %+v", req) return } //合并邮件奖励 var addRewards types.Assets if len(req.Rewards) > 0 { addRewards = types.FillAssets(req.Rewards) } else { addRewards = templateRow.Rewards } mailTable := db.GetMailTable(req.ToPlayerID) newMail := &dbMail.Mail{ MailID: mailTable.NewMailID(), FromID: req.FromPlayerID, FromName: req.FromPlayerName, TemplateID: req.TemplateID, TemplateParams: req.TemplateParams, IsReward: false, IsRead: false, SendTime: ctime.Now().ToSecond(), RewardTime: 0, Rewards: addRewards, } newMail.ExpireTime = newMail.SendTime + int64(templateRow.ExpireDays*ctime.SecondsPerDay) //添加邮件 delMailList, isChange := mailTable.Add(newMail, true) // 删除邮件处理 p.delMailSendReward(req.ToPlayerID, delMailList, true) if isChange { // 新邮件推送 pushList := &pb.MailList{} pbNewMail := newMail.ToProto() pushList.List = append(pushList.List, pbNewMail) sessions.PushPlayer(req.ToPlayerID, nameRoute.PushGameMail_New, pushList) } clog.Debugf("playerID = %d, mailNum = %d", req.ToPlayerID, len(mailTable.Data)) clog.Debugf("delMailID = %+v", delMailList) } // 获取邮件列表 func (p *actorMail) getMailList(req *pb.I64) (*pb.MailList, int32) { playerID := req.Value if playerID <= 0 { clog.Warnf("ops get mail list fail, playerID fail.") return nil, code.MailRequestDataError } mailTable := db.GetMailTable(playerID) mails := mailTable.ToProto() mailList := &pb.MailList{ List: mails, } return mailList, code.OK } // checkAndAddBulkMail 检测并添加群发邮件 func (p *actorMail) checkAndAddBulkMail(mailTable *db.MailTable) { mailBulkList := data.MailBulk.List() if len(mailBulkList) < 1 { return } for _, mailBulkRow := range mailBulkList { bulkID := mailBulkRow.BulkID if !mailBulkRow.IsOpen || mailTable.InBulk(bulkID) { continue } templateID := mailBulkRow.TemplateID mailTemplateRow, found := data.MailTemplate.GetByID(templateID) if !found { clog.Warnf("check and add bulk mail fail, template not found. PlayerID= %d, bulkID = %d, templateID = %d", mailTable.PlayerID, bulkID, templateID) continue } //合并群发&邮件模板的奖励内容 var addRewards types.Assets if len(mailTemplateRow.Rewards) > 0 { addRewards.AddAssets(mailTemplateRow.Rewards) } newMail := &dbMail.Mail{ MailID: mailTable.NewMailID(), TemplateID: templateID, IsReward: false, IsRead: false, SendTime: ctime.Now().ToSecond(), RewardTime: 0, Rewards: addRewards, } //计算邮件结束时间 newMail.ExpireTime = newMail.SendTime + int64(mailTemplateRow.ExpireDays*ctime.SecondsPerDay) //添加邮件 var _, isChange = mailTable.Add(newMail, true) if isChange { // 添加已发群发ID mailTable.AddBulkID(bulkID) clog.Infof("add bulk mail success. playerID= %d, bulkID = %d, templateID = %d", mailTable.PlayerID, bulkID, templateID) } } } func (p *actorMail) mailListPush(session *cproto.Session, mailTable *db.MailTable, now *ctime.CherryTime) { // 清理当前玩家过期的邮件 delMailList := mailTable.CheckExpire(now) // 删除邮件发送奖励 p.delMailSendReward(mailTable.PlayerID, delMailList, false) mailList := &pb.MailList{ MailType: enum.MailType_System, List: mailTable.ToProto(), } // 推送邮件列表 sessions.PushWithSession(session, nameRoute.PushGameMail_List, mailList) } func (p *actorMail) delMailSendReward(playerID int64, delMailList []*dbMail.Mail, pushDel bool) { if len(delMailList) < 1 { return } var ( addRewards = types.Assets{} delMailIDList = []int64{} ) for _, mail := range delMailList { if mail.CanTakeReward() { addRewards.AddAssets(mail.Rewards) } delMailIDList = append(delMailIDList, mail.MailID) } // 发送删除邮件奖励 if len(addRewards) > 0 { asset.Service().Adds(playerID, addRewards, ao.MailGet, true) } if pushDel { sessions.PushPlayer(playerID, nameRoute.PushGameMail_Delete, &pb.I64List{ List: delMailIDList, }) } }