942 lines
23 KiB
Go
942 lines
23 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
"time"
|
|
|
|
"github.com/globalsign/mgo/bson"
|
|
"mongo.games.com/goserver/core/basic"
|
|
"mongo.games.com/goserver/core/i18n"
|
|
"mongo.games.com/goserver/core/logger"
|
|
"mongo.games.com/goserver/core/module"
|
|
"mongo.games.com/goserver/core/task"
|
|
|
|
"mongo.games.com/game/common"
|
|
"mongo.games.com/game/model"
|
|
"mongo.games.com/game/mq"
|
|
hallproto "mongo.games.com/game/protocol/gamehall"
|
|
"mongo.games.com/game/protocol/rankmatch"
|
|
"mongo.games.com/game/srvdata"
|
|
"mongo.games.com/game/worldsrv/internal"
|
|
)
|
|
|
|
var RankMgrSingleton = &RankMatchMgr{
|
|
seasons: make(map[string]*RankSeasonId),
|
|
playerSeasons: make(map[int32]*PlayerRankSeason),
|
|
}
|
|
|
|
// RankSeasonId 赛季配置
|
|
type RankSeasonId struct {
|
|
Dirty bool
|
|
*model.RankSeasonId
|
|
}
|
|
|
|
// PlayerRankSeason 玩家排位信息
|
|
type PlayerRankSeason struct {
|
|
Dirty bool
|
|
*model.PlayerRankSeason
|
|
}
|
|
|
|
func (this *PlayerRankSeason) sendEmailAward(rankType int32) {
|
|
lv, _ := RankMgrSingleton.GetPlayerRankLV(rankType, this.SnId)
|
|
|
|
for _, item := range RankMgrSingleton.GetRankAwardList(rankType) {
|
|
if lv >= item.Lv {
|
|
var has bool
|
|
for _, v := range this.RankType[rankType].Awards {
|
|
if v.Id == item.Id {
|
|
has = true
|
|
break
|
|
}
|
|
}
|
|
if !has {
|
|
this.RankType[rankType].Awards = append(this.RankType[rankType].Awards, &model.RankAward{
|
|
Id: item.Id,
|
|
Ts: time.Now().Unix(),
|
|
})
|
|
|
|
var coin int64
|
|
var diamond int64
|
|
var otherParams []int32
|
|
for _, v := range item.Awards {
|
|
switch v.Id {
|
|
case 1: // 金币
|
|
coin = int64(v.Num)
|
|
case 2: // 钻石
|
|
diamond = int64(v.Num)
|
|
default:
|
|
// 道具
|
|
otherParams = []int32{v.Id, v.Num}
|
|
}
|
|
}
|
|
|
|
// 邮件发送奖励
|
|
var newMsg *model.Message
|
|
index := item.Id
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
var rankName []string
|
|
for _, v := range []string{"zh", "vi", "en", "kh"} {
|
|
rankName = append(rankName, i18n.Tr(v, fmt.Sprintf("RankReward_%d_%d", rankType, index)))
|
|
}
|
|
title := i18n.Tr("languages", "RankAwardTitle", rankName)
|
|
content := i18n.Tr("languages", "RankAward")
|
|
|
|
newMsg = model.NewMessage("", 0, "", this.SnId, model.MSGTYPE_RANK_REWARD,
|
|
title, content, coin, diamond, model.MSGSTATE_UNREAD, time.Now().Unix(), 0, "", otherParams, this.Platform, model.HallTienlen, nil)
|
|
|
|
return model.InsertMessage(this.Platform, newMsg)
|
|
}), task.CompleteNotifyWrapper(func(data interface{}, t task.Task) {
|
|
if data == nil {
|
|
p := PlayerMgrSington.GetPlayerBySnId(this.SnId)
|
|
if p != nil {
|
|
p.AddMessage(newMsg)
|
|
}
|
|
}
|
|
}), "AddMailByItem").StartByFixExecutor("SendMail")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// CheckNewSeason 检查赛季继承
|
|
func (this *PlayerRankSeason) CheckNewSeason() {
|
|
var n int
|
|
var f func()
|
|
f = func() {
|
|
cfg := RankMgrSingleton.GetSeasonConfig(this.Platform)
|
|
if cfg.SeasonId > this.SeasonId {
|
|
this.Dirty = true
|
|
this.SeasonId++
|
|
// 领取的奖励发邮件
|
|
for k := range this.RankType {
|
|
this.sendEmailAward(k)
|
|
}
|
|
|
|
old, err := json.Marshal(this.RankType)
|
|
if err != nil {
|
|
logger.Logger.Errorf("json.Marshal(this.RankType) err: %v", err)
|
|
return
|
|
}
|
|
this.LastRankType = make(map[int32]*model.PlayerRankInfo)
|
|
if err = json.Unmarshal(old, &this.LastRankType); err != nil {
|
|
logger.Logger.Errorf("json.Unmarshal(old,&this.LastRankType) err: %v", err)
|
|
return
|
|
}
|
|
for k, v := range this.RankType {
|
|
this.RankType[k].Score = RankMgrSingleton.NewSeasonScore(v.Score)
|
|
this.RankType[k].LastScore = this.RankType[k].Score
|
|
this.RankType[k].Awards = nil
|
|
}
|
|
|
|
f()
|
|
n++
|
|
if n > 1000 { // 防止死循环
|
|
return
|
|
}
|
|
}
|
|
}
|
|
f()
|
|
|
|
// 通知积分变更
|
|
if this.Dirty {
|
|
if p := PlayerMgrSington.GetPlayerBySnId(this.SnId); p != nil {
|
|
p.SendRankSeason()
|
|
}
|
|
for k := range this.RankType {
|
|
this.rankLog(k)
|
|
this.CheckShowRed(k)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *PlayerRankSeason) Update(rankScore map[int32]int64) {
|
|
this.CheckNewSeason()
|
|
|
|
for k, v := range this.RankType {
|
|
if v != nil && v.Score != rankScore[k] {
|
|
v.LastScore = v.Score
|
|
v.Score = rankScore[k]
|
|
this.Dirty = true
|
|
this.CheckShowRed(k)
|
|
this.rankLog(k)
|
|
}
|
|
}
|
|
|
|
for k, v := range rankScore {
|
|
info := this.RankType[k]
|
|
if info == nil {
|
|
info = &model.PlayerRankInfo{
|
|
Score: v,
|
|
}
|
|
this.RankType[k] = info
|
|
this.Dirty = true
|
|
this.CheckShowRed(k)
|
|
this.rankLog(k)
|
|
}
|
|
}
|
|
|
|
if this.Dirty {
|
|
if p := PlayerMgrSington.GetPlayerBySnId(this.SnId); p != nil {
|
|
p.SendRankSeason()
|
|
}
|
|
}
|
|
}
|
|
|
|
// CheckShowRed 检查是否显示红点
|
|
func (this *PlayerRankSeason) CheckShowRed(rankType int32) {
|
|
lv, _ := RankMgrSingleton.GetPlayerRankLV(rankType, this.SnId)
|
|
info := this.RankType[rankType]
|
|
var has bool // 有未领取的
|
|
here:
|
|
for _, item := range RankMgrSingleton.GetRankAwardList(rankType) {
|
|
if lv >= item.Lv { // 可领取
|
|
if info == nil {
|
|
has = true
|
|
break
|
|
}
|
|
if len(info.Awards) == 0 {
|
|
has = true
|
|
break
|
|
}
|
|
for _, v := range info.Awards {
|
|
if v != nil && v.Id == item.Id { // 领过了
|
|
continue here
|
|
}
|
|
}
|
|
has = true
|
|
break
|
|
}
|
|
}
|
|
p := PlayerMgrSington.GetPlayerBySnId(this.SnId)
|
|
if p != nil {
|
|
if has {
|
|
p.SendShowRed(hallproto.ShowRedCode_RankReward, rankType, 1)
|
|
} else {
|
|
p.SendShowRed(hallproto.ShowRedCode_RankReward, rankType, 0)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (this *PlayerRankSeason) rankLog(rankType int32) {
|
|
p := PlayerMgrSington.GetPlayerBySnId(this.SnId)
|
|
if p == nil {
|
|
return
|
|
}
|
|
lv, score := RankMgrSingleton.GetPlayerRankLV(rankType, this.SnId)
|
|
// 排行榜
|
|
log := &model.PlayerRankScore{
|
|
Platform: this.Platform,
|
|
SnId: this.SnId,
|
|
RankType: rankType,
|
|
SeasonId: this.SeasonId,
|
|
Lv: lv,
|
|
Score: score,
|
|
Name: p.Name,
|
|
Sex: p.Sex,
|
|
HeadUrl: p.HeadUrl,
|
|
Coin: p.Coin,
|
|
UpdateTs: time.Now().Unix(),
|
|
ModId: p.PlayerData.GetRoleId(),
|
|
}
|
|
mq.Write(log)
|
|
}
|
|
|
|
type RankMatchMgr struct {
|
|
common.BaseClockSinker
|
|
failSeason []string
|
|
seasons map[string]*RankSeasonId // 当前赛季 key平台id
|
|
playerSeasons map[int32]*PlayerRankSeason // 玩家排位信息 key玩家id
|
|
}
|
|
|
|
// 从数据库读取赛季配置
|
|
func (r *RankMatchMgr) load(platform string) {
|
|
var ret *model.RankSeasonId
|
|
var err error
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
ret, err = model.FindOneRankSeasonId(platform)
|
|
if err != nil {
|
|
logger.Logger.Errorf("RankMatchMgr.Load err: %v", err)
|
|
return err
|
|
}
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
if err == nil {
|
|
if ret.SeasonId > 0 {
|
|
r.SetSeasonConfig(&RankSeasonId{
|
|
Dirty: false,
|
|
RankSeasonId: ret,
|
|
})
|
|
} else {
|
|
season := r.fromFile(platform)
|
|
if season != nil {
|
|
season.Dirty = true
|
|
r.SetSeasonConfig(season)
|
|
}
|
|
}
|
|
r.saveRankSeason(platform, true, true)
|
|
} else {
|
|
r.failSeason = append(r.failSeason, platform)
|
|
}
|
|
})).StartByFixExecutor(fmt.Sprintf("platform%s", platform))
|
|
}
|
|
|
|
var ErrTimeStr = errors.New("time str err")
|
|
|
|
func (r *RankMatchMgr) strToTime(s string) (time.Time, error) {
|
|
t := time.Time{}
|
|
ls := strings.Split(s, "/")
|
|
if len(ls) != 3 {
|
|
return t, ErrTimeStr
|
|
}
|
|
|
|
s = ls[0] + fmt.Sprintf("/%02s", ls[1]) + fmt.Sprintf("/%02s", ls[2])
|
|
if len(s) != 10 {
|
|
return t, ErrTimeStr
|
|
}
|
|
|
|
return time.ParseInLocation("2006/01/02", s, time.Local)
|
|
}
|
|
|
|
// fromFile 从文件中读取赛季配置
|
|
func (r *RankMatchMgr) fromFile(platform string) *RankSeasonId {
|
|
now := time.Now().Unix()
|
|
for _, v := range srvdata.PBDB_RankCycleMgr.Datas.Arr {
|
|
st, err := r.strToTime(v.Start)
|
|
if err != nil {
|
|
logger.Logger.Errorf("RankMatchMgr.fromFile start time err:%v", err)
|
|
continue
|
|
}
|
|
et, err := r.strToTime(v.End)
|
|
if err != nil {
|
|
logger.Logger.Errorf("RankMatchMgr.fromFile end time err:%v", err)
|
|
continue
|
|
}
|
|
if now >= st.Unix() && now < et.AddDate(0, 0, 1).Unix() {
|
|
return &RankSeasonId{
|
|
Dirty: false,
|
|
RankSeasonId: &model.RankSeasonId{
|
|
Platform: platform,
|
|
SeasonId: v.Id,
|
|
StartTs: st.Unix(),
|
|
EndTs: et.Unix(),
|
|
UpdateTs: now,
|
|
},
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// saveRankSeason 保存赛季配置
|
|
func (r *RankMatchMgr) saveRankSeason(platform string, isSync bool, force bool) {
|
|
ret, ok := r.seasons[platform]
|
|
if !ok || ret == nil || (!ret.Dirty && !force) {
|
|
return
|
|
}
|
|
|
|
//todo 需要拷贝一份数据再保存吗
|
|
|
|
var res bool
|
|
f := func() {
|
|
res = model.UpsertRankSeasonId(ret.RankSeasonId)
|
|
}
|
|
cf := func() {
|
|
if res {
|
|
ret.Dirty = false
|
|
}
|
|
}
|
|
|
|
if isSync {
|
|
f()
|
|
cf()
|
|
return
|
|
}
|
|
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
f()
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
cf()
|
|
})).StartByFixExecutor(fmt.Sprintf("platform%s", platform))
|
|
}
|
|
|
|
// checkNewSeason 是否新赛季
|
|
func (r *RankMatchMgr) checkNewSeason(platform string) bool {
|
|
newSeason := r.fromFile(platform)
|
|
oldSeason := r.GetSeasonConfig(platform)
|
|
var oldId, newId int32
|
|
if oldSeason != nil {
|
|
oldId = oldSeason.SeasonId
|
|
}
|
|
if newSeason != nil {
|
|
newId = newSeason.SeasonId
|
|
}
|
|
|
|
if newId > 0 && oldId != newId {
|
|
// 新赛季
|
|
newSeason.Dirty = true
|
|
r.SetSeasonConfig(newSeason)
|
|
|
|
// 玩家段位继承
|
|
for _, v := range r.playerSeasons {
|
|
v.CheckNewSeason()
|
|
}
|
|
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// GetSeasonConfig 获取当前赛季配置
|
|
func (r *RankMatchMgr) GetSeasonConfig(platform string) *RankSeasonId {
|
|
return r.seasons[platform]
|
|
}
|
|
|
|
// SetSeasonConfig 设置当前赛季配置
|
|
func (r *RankMatchMgr) SetSeasonConfig(config *RankSeasonId) {
|
|
if config == nil {
|
|
return
|
|
}
|
|
r.seasons[config.Platform] = config
|
|
|
|
r.checkNewSeason(config.Platform)
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetPlayerSeason(snid int32) *PlayerRankSeason {
|
|
ret := r.playerSeasons[snid]
|
|
if ret == nil {
|
|
return nil
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetPlayerRankScore(snid int32) map[int32]int64 {
|
|
ret := make(map[int32]int64)
|
|
if rank := r.GetPlayerSeason(snid); rank != nil && rank.PlayerRankSeason != nil {
|
|
for k, v := range rank.RankType {
|
|
if v != nil {
|
|
ret[k] = v.Score
|
|
}
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetPlayerRankScoreInt64(snid int32) map[int64]int64 {
|
|
ret := make(map[int64]int64)
|
|
if rank := r.GetPlayerSeason(snid); rank != nil && rank.PlayerRankSeason != nil {
|
|
for k, v := range rank.RankType {
|
|
if v != nil {
|
|
ret[int64(k)] = v.Score
|
|
}
|
|
}
|
|
}
|
|
return ret
|
|
}
|
|
|
|
func (r *RankMatchMgr) CheckShowRed(snid int32) {
|
|
p := r.GetPlayerSeason(snid)
|
|
if p == nil {
|
|
return
|
|
}
|
|
for k := range p.RankType {
|
|
p.CheckShowRed(k)
|
|
}
|
|
}
|
|
|
|
func (r *RankMatchMgr) UpdatePlayerSeason(snid int32, rankScore map[int32]int64) {
|
|
season := r.GetPlayerSeason(snid)
|
|
if season != nil {
|
|
season.Update(rankScore)
|
|
}
|
|
}
|
|
|
|
func (r *RankMatchMgr) UpdateRobotSeason(platform string, snid int32, rankType int32, score int64,
|
|
name string, sex int32, headUrl string, coin int64, roleId int32) {
|
|
|
|
log := &model.PlayerRankScore{
|
|
Platform: platform,
|
|
SnId: snid,
|
|
RankType: rankType,
|
|
SeasonId: r.GetSeasonConfig(platform).SeasonId,
|
|
Lv: srvdata.RankLevelMgr.GetRankLevel(rankType, score),
|
|
Score: score,
|
|
Name: name,
|
|
Sex: sex,
|
|
HeadUrl: headUrl,
|
|
Coin: coin,
|
|
IsRobot: true,
|
|
UpdateTs: time.Now().Unix(),
|
|
ModId: roleId,
|
|
}
|
|
mq.Write(log)
|
|
}
|
|
|
|
func (r *RankMatchMgr) SetPlayerSeason(config *PlayerRankSeason) {
|
|
if config == nil {
|
|
return
|
|
}
|
|
|
|
r.playerSeasons[config.SnId] = config
|
|
// 段位继承
|
|
config.CheckNewSeason()
|
|
}
|
|
|
|
func (r *RankMatchMgr) ModuleName() string {
|
|
return "RankMatchMgr"
|
|
}
|
|
|
|
func (r *RankMatchMgr) Init() {
|
|
for _, platform := range PlatformMgrSingleton.GetPlatforms() {
|
|
if platform.IdStr == DefaultPlatform {
|
|
continue
|
|
}
|
|
r.load(platform.IdStr)
|
|
}
|
|
}
|
|
|
|
func (r *RankMatchMgr) Update() {
|
|
// 数据库查询失败重新查询
|
|
if len(r.failSeason) > 0 {
|
|
ls := r.failSeason
|
|
r.failSeason = make([]string, 0)
|
|
for _, v := range ls {
|
|
r.load(v)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (r *RankMatchMgr) Shutdown() {
|
|
for _, platform := range PlatformMgrSingleton.GetPlatforms() {
|
|
if platform.IdStr == DefaultPlatform {
|
|
continue
|
|
}
|
|
r.saveRankSeason(platform.IdStr, true, true)
|
|
}
|
|
|
|
module.UnregisteModule(r)
|
|
}
|
|
|
|
// NewSeasonScore 赛季继承积分
|
|
func (r *RankMatchMgr) NewSeasonScore(old int64) int64 {
|
|
return srvdata.RankLevelMgr.GetNewScore(old)
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetPlayerRankLV(rankType, snid int32) (int32, int64) {
|
|
if rankType <= 0 {
|
|
return 0, 0
|
|
}
|
|
|
|
rank := r.GetPlayerSeason(snid)
|
|
if rank == nil || rank.RankType == nil || rank.RankType[rankType] == nil {
|
|
return 0, 0
|
|
}
|
|
|
|
score := rank.RankType[rankType].Score
|
|
|
|
return srvdata.RankLevelMgr.GetRankLevel(rankType, score), score
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetPlayerLastRankLV(rankType, snid int32) (int32, int64) {
|
|
if rankType <= 0 {
|
|
return 0, 0
|
|
}
|
|
|
|
rank := r.GetPlayerSeason(snid)
|
|
if rank == nil || rank.LastRankType == nil || rank.LastRankType[rankType] == nil {
|
|
return 0, 0
|
|
}
|
|
|
|
score := rank.LastRankType[rankType].Score
|
|
|
|
return srvdata.RankLevelMgr.GetRankLevel(rankType, score), score
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetRankList(rankType int32) []*rankmatch.RankItem {
|
|
var list []*rankmatch.RankItem
|
|
|
|
// todo 优化
|
|
for _, v := range srvdata.PBDB_RankLevelMgr.Datas.Arr {
|
|
if rankType < v.GetRankType() {
|
|
continue
|
|
}
|
|
if rankType > v.GetRankType() {
|
|
break
|
|
}
|
|
|
|
list = append(list, &rankmatch.RankItem{
|
|
Id: v.Id,
|
|
Lv: v.Level,
|
|
})
|
|
}
|
|
sort.Slice(list, func(i, j int) bool {
|
|
return list[i].Lv > list[j].Lv
|
|
})
|
|
return list
|
|
}
|
|
|
|
func (r *RankMatchMgr) getRankScore(rankType int32, lv int32) int64 {
|
|
for _, v := range srvdata.PBDB_RankLevelMgr.Datas.Arr {
|
|
if rankType < v.GetRankType() {
|
|
continue
|
|
}
|
|
if rankType > v.GetRankType() {
|
|
break
|
|
}
|
|
if v.Level == lv {
|
|
return v.Score
|
|
}
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func (r *RankMatchMgr) GetRankAwardList(rankType int32) []*rankmatch.AwardItem {
|
|
var list []*rankmatch.AwardItem
|
|
|
|
for _, v := range srvdata.PBDB_RankRewardMgr.Datas.Arr {
|
|
if rankType < v.GetRankType() {
|
|
continue
|
|
}
|
|
if rankType > v.GetRankType() {
|
|
break
|
|
}
|
|
|
|
item := &rankmatch.AwardItem{
|
|
Id: v.Id,
|
|
Lv: v.Level,
|
|
Score: r.getRankScore(rankType, v.Level),
|
|
}
|
|
item.Awards = []*rankmatch.Award{}
|
|
if v.Award1Num > 0 {
|
|
item.Awards = append(item.Awards, &rankmatch.Award{
|
|
Id: v.Award1Id,
|
|
Num: v.Award1Num,
|
|
})
|
|
}
|
|
if v.Award2Num > 0 {
|
|
item.Awards = append(item.Awards, &rankmatch.Award{
|
|
Id: v.Award2Id,
|
|
Num: v.Award2Num,
|
|
})
|
|
}
|
|
if v.Award3Num > 0 {
|
|
item.Awards = append(item.Awards, &rankmatch.Award{
|
|
Id: v.Award3Id,
|
|
Num: v.Award3Num,
|
|
})
|
|
}
|
|
list = append(list, item)
|
|
}
|
|
sort.Slice(list, func(i, j int) bool {
|
|
return list[i].Lv > list[j].Lv
|
|
})
|
|
return list
|
|
}
|
|
|
|
//========================implement ClockSinker ==============================
|
|
|
|
func (r *RankMatchMgr) InterestClockEvent() int {
|
|
return 1 << common.ClockEventDay
|
|
}
|
|
|
|
func (r *RankMatchMgr) OnDayTimer() {
|
|
logger.Logger.Info("(this *RankMatchMgr) OnDayTimer")
|
|
//排行榜发奖
|
|
//r.RankAward()
|
|
for _, platform := range PlatformMgrSingleton.GetPlatforms() {
|
|
if platform.IdStr == DefaultPlatform {
|
|
continue
|
|
}
|
|
// 检查新赛季
|
|
r.checkNewSeason(platform.IdStr)
|
|
// 保存赛季配置
|
|
r.saveRankSeason(platform.IdStr, false, false)
|
|
}
|
|
}
|
|
|
|
//========================implement IPlayerLoad ==============================
|
|
|
|
func (r *RankMatchMgr) Load(platform string, snid int32, player any) *internal.PlayerLoadReplay {
|
|
args := &model.FindPlayerRankSeasonArgs{
|
|
Platform: platform,
|
|
Id: []int32{snid},
|
|
}
|
|
ret, err := model.FindPlayerRankSeason(args)
|
|
return &internal.PlayerLoadReplay{
|
|
Platform: platform,
|
|
Snid: snid,
|
|
Err: err,
|
|
Data: ret.List,
|
|
}
|
|
}
|
|
|
|
func (r *RankMatchMgr) Callback(player any, ret *internal.PlayerLoadReplay) {
|
|
if ret == nil {
|
|
return
|
|
}
|
|
if ret.Err != nil || ret.Data == nil {
|
|
logger.Logger.Errorf("RankMatchMgr load player rankseason err:%v", ret.Err)
|
|
return
|
|
}
|
|
|
|
ls := ret.Data.([]*model.PlayerRankSeason)
|
|
if len(ls) == 0 {
|
|
// 初始化
|
|
s := r.GetSeasonConfig(ret.Platform)
|
|
if s == nil {
|
|
return
|
|
}
|
|
r.SetPlayerSeason(&PlayerRankSeason{
|
|
Dirty: true,
|
|
PlayerRankSeason: model.NewPlayerRankSeason(&model.NewPlayerRankSeasonArgs{
|
|
Platform: ret.Platform,
|
|
SnId: ret.Snid,
|
|
SeasonId: s.SeasonId,
|
|
}),
|
|
})
|
|
} else {
|
|
r.SetPlayerSeason(&PlayerRankSeason{
|
|
Dirty: false,
|
|
PlayerRankSeason: ls[0],
|
|
})
|
|
}
|
|
}
|
|
|
|
// 排行榜发奖
|
|
func (r *RankMatchMgr) RankAward() {
|
|
logger.Logger.Trace("排行榜开始发奖!!!!")
|
|
for _, v := range PlatformMgrSingleton.GetPlatforms() {
|
|
platform := v.IdStr
|
|
rankConfig := PlatformMgrSingleton.GetConfig(platform).RankTypeConfig
|
|
if rankConfig == nil {
|
|
continue
|
|
}
|
|
for _, info := range rankConfig.Info {
|
|
if info.TurnOff == 0 {
|
|
continue
|
|
}
|
|
now := time.Now()
|
|
//获取排行榜数据 进行发奖
|
|
if info.RankType == 2 {
|
|
//判断是不是周一
|
|
if now.Weekday() != time.Monday {
|
|
continue
|
|
}
|
|
}
|
|
if info.RankType == 3 {
|
|
//判断是不是每月1号
|
|
if now.Day() != 1 {
|
|
continue
|
|
}
|
|
}
|
|
rankAward := info.Award
|
|
if rankAward == nil {
|
|
continue
|
|
}
|
|
var players []*model.PlayerBaseInfo
|
|
if info.RankType == model.RankType_Coin {
|
|
list, err := model.FindPlayerCoinList(&model.FindPlayerCoinListArgs{
|
|
Platform: platform,
|
|
})
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
for _, vv := range list.List {
|
|
player := PlayerMgrSington.GetPlayerBySnId(vv.SnId)
|
|
if player != nil {
|
|
players = append(players, &model.PlayerBaseInfo{
|
|
SnId: player.SnId,
|
|
LastChannel: player.LastChannel,
|
|
})
|
|
} else {
|
|
baseInfo := model.GetPlayerBaseInfo(platform, vv.SnId)
|
|
players = append(players, baseInfo)
|
|
}
|
|
}
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
if err != nil {
|
|
logger.Logger.Errorf("RankMatchMgr OnDayTimer FindPlayerPermitList err:%v", err)
|
|
return
|
|
}
|
|
rankId := int32(1)
|
|
for k, player := range players {
|
|
if player == nil {
|
|
logger.Logger.Errorf("RankMatchMgr OnDayTimer FindPlayerPermitList player is nil %v", list.List[k].SnId)
|
|
continue
|
|
}
|
|
var items []int32
|
|
for _, award := range rankAward {
|
|
if award.RankLevelId == rankId {
|
|
for _, itemInfo := range award.Item {
|
|
items = append(items, itemInfo.ItemId)
|
|
items = append(items, int32(itemInfo.ItemNum))
|
|
}
|
|
break
|
|
}
|
|
}
|
|
if len(items) == 0 {
|
|
break
|
|
}
|
|
// 发邮件
|
|
var newMsg *model.Message
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
title := i18n.Tr("languages", "PermitAwardTitle")
|
|
content := i18n.Tr("languages", "PermitAward", []int{int(rankId), int(rankId), int(rankId), int(rankId)})
|
|
newMsg = model.NewMessage("", 0, "", player.SnId, model.MSGTYPE_RANK_REWARD,
|
|
title, content, 0, 0, model.MSGSTATE_UNREAD, time.Now().Unix(), 0, "", items, platform, model.HallTienlen, nil)
|
|
err := model.InsertMessage(platform, newMsg)
|
|
if err != nil {
|
|
logger.Logger.Errorf("发送邮件失败 snid:%v err:%v", player.SnId, err)
|
|
return err
|
|
}
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
p := PlayerMgrSington.GetPlayerBySnId(player.SnId)
|
|
if p != nil {
|
|
p.AddMessage(newMsg)
|
|
}
|
|
})).Start()
|
|
rankId += 1
|
|
}
|
|
})).StartByExecutor("PlayerCoin_Award")
|
|
} else if info.RankType == model.RankType_WinCoin {
|
|
//从数据库读取前一天的数据
|
|
startTime, endTime := StartEndTs()
|
|
logger.Logger.Tracef("-----------------排行榜发奖 startTime = %d, endTime = %d------------------", startTime, endTime)
|
|
ret, err := model.FindWinCoinListTienlen(&model.FindWinCoinListArgs{
|
|
Platform: platform,
|
|
StartTs: startTime,
|
|
EndTs: endTime,
|
|
})
|
|
if err != nil {
|
|
return
|
|
}
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
for _, vv := range ret.List {
|
|
player := PlayerMgrSington.GetPlayerBySnId(vv.SnId)
|
|
if player != nil {
|
|
players = append(players, &model.PlayerBaseInfo{
|
|
SnId: player.SnId,
|
|
LastChannel: player.LastChannel,
|
|
})
|
|
} else {
|
|
baseInfo := model.GetPlayerBaseInfo(platform, vv.SnId)
|
|
players = append(players, baseInfo)
|
|
}
|
|
}
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
if err != nil {
|
|
logger.Logger.Errorf("RankMatchMgr OnDayTimer FindWinCoinListTienlen err:%v", err)
|
|
return
|
|
}
|
|
rankId := int32(1)
|
|
for k, player := range players {
|
|
if player == nil {
|
|
logger.Logger.Errorf("RankMatchMgr OnDayTimer FindWinCoinListTienlen player is nil %v", ret.List[k].SnId)
|
|
continue
|
|
}
|
|
var items []int32
|
|
for _, award := range rankAward {
|
|
if award.RankLevelId == rankId {
|
|
for _, itemInfo := range award.Item {
|
|
items = append(items, itemInfo.ItemId)
|
|
items = append(items, int32(itemInfo.ItemNum))
|
|
}
|
|
break
|
|
}
|
|
}
|
|
if len(items) == 0 {
|
|
break
|
|
}
|
|
// 发邮件
|
|
var newMsg *model.Message
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
title := i18n.Tr("languages", "PermitAwardTitle")
|
|
content := i18n.Tr("languages", "PermitAward", []int{int(rankId), int(rankId), int(rankId), int(rankId)})
|
|
newMsg = model.NewMessage("", 0, "", player.SnId, model.MSGTYPE_RANK_REWARD,
|
|
title, content, 0, 0, model.MSGSTATE_UNREAD, time.Now().Unix(), 0, "", items, platform, model.HallTienlen, nil)
|
|
err := model.InsertMessage(platform, newMsg)
|
|
if err != nil {
|
|
logger.Logger.Errorf("发送邮件失败 snid:%v err:%v", player.SnId, err)
|
|
return err
|
|
}
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
p := PlayerMgrSington.GetPlayerBySnId(player.SnId)
|
|
if p != nil {
|
|
p.AddMessage(newMsg)
|
|
}
|
|
})).Start()
|
|
rankId += 1
|
|
}
|
|
})).StartByExecutor("WinCoin_Award")
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func StartEndTs() (startTs int64, endTs int64) {
|
|
now := time.Now()
|
|
year, month, day := now.Date()
|
|
lastTs := time.Date(year, month, day, model.GameParamData.WinCoinUpdateTime, 0, 0, 0, now.Location())
|
|
if now.Before(lastTs) {
|
|
lastTs = lastTs.AddDate(0, 0, -1)
|
|
}
|
|
endTs = lastTs.Unix()
|
|
return endTs - 24*int64(time.Hour.Seconds()), endTs
|
|
}
|
|
|
|
func (r *RankMatchMgr) LoadAfter(platform string, snid int32) *internal.PlayerLoadReplay {
|
|
return nil
|
|
}
|
|
|
|
func (r *RankMatchMgr) CallbackAfter(ret *internal.PlayerLoadReplay) {
|
|
}
|
|
|
|
func (r *RankMatchMgr) Save(platform string, snid int32, isSync, force bool) {
|
|
ret, ok := r.playerSeasons[snid]
|
|
if !ok || ret == nil || (!ret.Dirty && !force) {
|
|
return
|
|
}
|
|
|
|
var res bool
|
|
f := func() {
|
|
if ret.Id == "" {
|
|
ret.Id = bson.NewObjectId()
|
|
}
|
|
res = model.UpsertPlayerRankSeason(ret.PlayerRankSeason)
|
|
}
|
|
cf := func() {
|
|
if res {
|
|
ret.Dirty = false
|
|
}
|
|
}
|
|
|
|
if isSync {
|
|
f()
|
|
cf()
|
|
return
|
|
}
|
|
|
|
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
|
|
f()
|
|
return nil
|
|
}), task.CompleteNotifyWrapper(func(i interface{}, t task.Task) {
|
|
cf()
|
|
})).StartByFixExecutor(fmt.Sprintf("platform%s", ret.Platform))
|
|
}
|
|
|
|
func (r *RankMatchMgr) Release(platform string, snid int32) {
|
|
delete(r.playerSeasons, snid)
|
|
}
|
|
|
|
func init() {
|
|
module.RegisteModule(RankMgrSingleton, time.Minute, 0)
|
|
common.ClockMgrSingleton.RegisterSinker(RankMgrSingleton)
|
|
internal.RegisterPlayerLoad(RankMgrSingleton)
|
|
}
|