Compare commits

...

28 Commits

Author SHA1 Message Date
sk 1f24dd29b6 no message 2024-12-17 10:35:21 +08:00
sk 4b29c43709 modify:.gitignore 2024-12-17 10:34:55 +08:00
sk 4e59c6600c 道具记录记录gamedif 2024-12-16 17:51:21 +08:00
sk 442801fc9a 游戏记录添加游戏组首次游戏时间和游戏次数 2024-12-16 16:33:41 +08:00
sk 490576b1dc 游戏记录添加gamedif 2024-12-16 15:47:26 +08:00
sk 2c48adeca7 Merge branch 'develop' into sk 2024-12-16 15:33:06 +08:00
sk bcbc162549 解决冲突 2024-12-16 11:17:11 +08:00
by 4d65851083 后台补单BUG修改 2024-12-16 10:16:55 +08:00
by 8b40eb3c49 后台补单BUG修改 2024-12-16 10:10:45 +08:00
by d791c4d02c 后台补单BUG修改 2024-12-16 10:03:36 +08:00
by d6bfa73d70 充值增加log 2024-12-13 17:55:37 +08:00
by a4ebed8fc9 充值增加log 2024-12-13 17:54:41 +08:00
by db24cf0620 充值增加log 2024-12-13 17:53:13 +08:00
by 7d6ee4c3bd 充值增加log 2024-12-13 17:51:59 +08:00
by 5c64d97728 报错修改 2024-12-13 17:42:45 +08:00
sk 5ca1048b18 Merge branch 'release' into develop 2024-12-13 11:16:09 +08:00
sk 9c3f3ea191 fix:机器人服务房间管理器房间删除 2024-12-13 11:15:43 +08:00
sk cab63a8bf9 add:游戏记录上报数据添加唯一id 2024-12-12 16:08:22 +08:00
sk 500fed59dd modify:游戏记录上报 2024-12-12 16:03:11 +08:00
sk bf636de73a fix:机器人离场金币 2024-12-12 09:34:13 +08:00
sk 95650519e8 fix:etcd配置 2024-12-12 08:43:43 +08:00
sk 8021f554f2 Merge branch 'release' into develop 2024-12-12 08:42:06 +08:00
sk acd3f4f676 机器人添加状态日志 2024-12-11 17:17:23 +08:00
sk 13e03f7428 fix:金币存钱罐跨天重置 2024-12-11 16:10:39 +08:00
tomas 1ca0213301 fix idx 2024-12-11 09:09:16 +08:00
tomas 0c3b7ebed3 fix index 2024-12-11 09:09:15 +08:00
sk 43c3d3571b Merge branch 'develop' into sk 2024-12-10 10:40:27 +08:00
sk 779d8a64a4 拉霸缓存游戏记录 2024-12-09 16:51:53 +08:00
50 changed files with 413 additions and 401 deletions

4
.gitignore vendored
View File

@ -46,4 +46,6 @@ tools/xlsx2binary/agc.go
/robot/robot /robot/robot
/ranksrv/ranksrv /ranksrv/ranksrv
/schedulesrv/schedulesrv /schedulesrv/schedulesrv
/machine/machine /machine/machine
/statistics/statistics
/statistics/task/task*

View File

@ -1,8 +1,8 @@
@echo off @echo off
xcopy ..\data\* .\data\ /s /e /y /exclude:..\shell\exclude.txt xcopy ..\data\* .\data\ /s /e /y /exclude:..\exclude.txt
for /f %%i in (../shell/programs.txt) do ( for /f %%i in (../programs.txt) do (
echo go build %%i echo go build %%i
go build -o ./%%i/%%i.exe ../%%i/ go build -o ./%%i/%%i.exe ../%%i/
) )

View File

@ -898,3 +898,7 @@ var GuideIdToGainWay = map[int]int{
GuideIdNewPlayer: GainWayGuide, GuideIdNewPlayer: GainWayGuide,
GuideIdCustom: GainWayGuide2, GuideIdCustom: GainWayGuide2,
} }
func GetGameDifKey(gamedif string) string {
return fmt.Sprintf("gamedif-%v", gamedif)
}

View File

@ -64,10 +64,10 @@ func (svc *DbShopLogSvc) UpdateDbShopState(args *model.DbShopLogArgs, ret *bool)
logger.Logger.Error("UpdateDbShopState == nil") logger.Logger.Error("UpdateDbShopState == nil")
return nil return nil
} }
logger.Logger.Trace("DbShopLogSvc.UpdateDbShopState") logger.Logger.Info("DbShopLogSvc.UpdateDbShopState", args.Log.LogId)
err = clog.UpdateId(args.Log.LogId, bson.M{"$set": bson.M{"state": args.Log.State}}) err = clog.UpdateId(args.Log.LogId, bson.M{"$set": bson.M{"state": args.Log.State}})
if err != nil { if err != nil {
logger.Logger.Error("DbShopLogSvc.UpdateDbShopState error:", err) logger.Logger.Error("DbShopLogSvc.UpdateDbShopState error:", err, "LogId = ", args.Log.LogId)
return nil return nil
} }
*ret = true *ret = true

View File

@ -33,6 +33,7 @@ func GameDetailedLogsCollection(plt string) *mongo.Collection {
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true}) c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true})
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"time", "cycleid"}, Background: true, Sparse: true}) c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"time", "cycleid"}, Background: true, Sparse: true})
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"-time", "cycleid"}, Background: true, Sparse: true}) c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"-time", "cycleid"}, Background: true, Sparse: true})
c_gamedetailed.EnsureIndex(mgo.Index{Key: []string{"gamedif"}, Background: true, Sparse: true})
} }
return c_gamedetailed return c_gamedetailed
} }

View File

@ -44,6 +44,7 @@ func GamePlayerListLogsCollection(plt string) *mongo.Collection {
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"-ts", "cycleid"}, Background: true, Sparse: true}) c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"-ts", "cycleid"}, Background: true, Sparse: true})
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"cycleid"}, Background: true, Sparse: true}) c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"cycleid"}, Background: true, Sparse: true})
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true}) c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"ts", "cycleid"}, Background: true, Sparse: true})
c_gameplayerlistlog.EnsureIndex(mgo.Index{Key: []string{"gamedif"}, Background: true, Sparse: true})
} }
return c_gameplayerlistlog return c_gameplayerlistlog
} }

View File

@ -30,6 +30,7 @@ func ItemLogsCollection(plt string) *mongo.Collection {
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"typeid", "roomconfigid"}, Background: true, Sparse: true}) c_itemlog.EnsureIndex(mgo.Index{Key: []string{"typeid", "roomconfigid"}, Background: true, Sparse: true})
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"ts"}, Background: true, Sparse: true}) c_itemlog.EnsureIndex(mgo.Index{Key: []string{"ts"}, Background: true, Sparse: true})
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"-ts"}, Background: true, Sparse: true}) c_itemlog.EnsureIndex(mgo.Index{Key: []string{"-ts"}, Background: true, Sparse: true})
c_itemlog.EnsureIndex(mgo.Index{Key: []string{"gamedif"}, Background: true, Sparse: true})
} }
return c_itemlog return c_itemlog
} }

View File

@ -42,8 +42,8 @@ const (
ETCDKEY_MACHINE = "/game/machine_config" //娃娃机配置 ETCDKEY_MACHINE = "/game/machine_config" //娃娃机配置
ETCDKEY_MatchAudience = "/game/match_audience" //比赛观众 ETCDKEY_MatchAudience = "/game/match_audience" //比赛观众
ETCDKEY_Spirit = "/game/spirit" // 小精灵配置 ETCDKEY_Spirit = "/game/spirit" // 小精灵配置
ETCDKEY_RoomType = "/game/room_type" // 房间类型配置 ETCDKEY_RoomType = "/game/room_type/" // 房间类型配置
ETCDKEY_RoomConfig = "/game/room_config" // 房间配置 ETCDKEY_RoomConfig = "/game/room_config/" // 房间配置
ETCDKEY_RoomConfigSystem = "/game/room_system" // 系统房间配置 ETCDKEY_RoomConfigSystem = "/game/room_system" // 系统房间配置
ETCDKEY_ClientUpgrade = "/game/client_upgrade" // 客户端升级奖励配置 ETCDKEY_ClientUpgrade = "/game/client_upgrade" // 客户端升级奖励配置
ETCDKEY_PopUpWindow = "/game/PopUpWindowConfig" //弹窗配置 ETCDKEY_PopUpWindow = "/game/PopUpWindowConfig" //弹窗配置

View File

@ -945,8 +945,6 @@ func AvengersCheckAndSaveLog(sceneEx *AvengersSceneData, playerEx *AvengersPlaye
LogId: logid, LogId: logid,
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -44,13 +44,16 @@ func (this *Scene) SaveGameDetailedLog(param *SaveGameDetailedParam) *SaveGameDe
f := func(plt string) { f := func(plt string) {
log := &model.GameDetailedLog{ log := &model.GameDetailedLog{
Id: bson.NewObjectId(), Id: bson.NewObjectId(),
LogId: param.LogId,
GameId: this.GameId,
Platform: plt, Platform: plt,
LogId: param.LogId,
GameDif: this.GetDBGameFree().GetGameDif(),
GameId: this.GetDBGameFree().GetGameId(),
GameClass: this.GetDBGameFree().GetGameClass(),
GameMode: this.GetDBGameFree().GetGameMode(),
GameType: this.GetDBGameFree().GetGameType(),
GameFreeId: this.GetDBGameFree().GetId(),
MatchId: this.GetMatch().GetMatchSortId(), MatchId: this.GetMatch().GetMatchSortId(),
SceneId: this.SceneId, SceneId: this.SceneId,
GameMode: this.GameMode,
GameFreeid: this.GetGameFreeId(),
PlayerCount: int32(len(this.Players)), PlayerCount: int32(len(this.Players)),
GameTiming: int32(param.GameTime), GameTiming: int32(param.GameTime),
GameBaseBet: this.GetBaseScore(), GameBaseBet: this.GetBaseScore(),
@ -98,8 +101,6 @@ type SaveGamePlayerListLogParam struct {
Platform string // 平台 Platform string // 平台
Snid int32 // 玩家id Snid int32 // 玩家id
PlayerName string // 玩家名字 PlayerName string // 玩家名字
Channel string // 渠道
ChannelId string // 推广渠道
TotalIn int64 // 总投入 TotalIn int64 // 总投入
TotalOut int64 // 总产出(税前) TotalOut int64 // 总产出(税前)
TaxCoin int64 // 总税收 TaxCoin int64 // 总税收
@ -155,33 +156,35 @@ func (this *Scene) SaveGamePlayerListLog(param *SaveGamePlayerListLogParam) *Sav
now := time.Now() now := time.Now()
log := &model.GamePlayerListLog{ log := &model.GamePlayerListLog{
LogId: bson.NewObjectId(), LogId: bson.NewObjectId(),
Platform: param.Platform,
GameDif: this.GetDBGameFree().GetGameDif(),
GameId: this.GetDBGameFree().GetGameId(),
GameClass: this.GetDBGameFree().GetGameClass(),
GameMode: this.GetDBGameFree().GetGameMode(),
GameType: this.GetDBGameFree().GetGameType(),
GameFreeId: this.GetGameFreeId(),
BaseScore: baseScore,
GameDetailedLogId: param.LogId,
Channel: p.Channel,
ChannelId: p.ChannelId,
RoomType: this.SceneMode,
Ts: now.Unix(),
Time: now,
CycleId: this.CycleID,
SnId: p.SnId, SnId: p.SnId,
Name: param.PlayerName, Name: param.PlayerName,
GameId: this.GameId,
BaseScore: baseScore,
TaxCoin: param.TaxCoin,
Platform: param.Platform,
Channel: param.Channel,
SceneId: this.SceneId, SceneId: this.SceneId,
GameMode: this.GameMode,
GameFreeid: this.GetGameFreeId(),
GameDetailedLogId: param.LogId,
IsFirstGame: param.IsFirstGame,
BetAmount: param.BetAmount,
WinAmountNoAnyTax: param.WinAmountNoAnyTax,
TotalIn: param.TotalIn,
TotalOut: param.TotalOut,
Time: now,
RoomType: this.SceneMode,
GameDif: this.GetDBGameFree().GetGameDif(),
GameClass: this.GetDBGameFree().GetGameClass(),
MatchId: this.GetMatch().GetMatchSortId(), MatchId: this.GetMatch().GetMatchSortId(),
MatchType: int64(this.GetMatch().GetMatchType()), MatchType: int64(this.GetMatch().GetMatchType()),
Ts: now.Unix(), WinAmountNoAnyTax: param.WinAmountNoAnyTax,
TaxCoin: param.TaxCoin,
BetAmount: param.BetAmount,
IsFirstGame: param.IsFirstGame,
TotalIn: param.TotalIn,
TotalOut: param.TotalOut,
IsFree: param.IsFree, IsFree: param.IsFree,
WinSmallGame: param.WinSmallGame, WinSmallGame: param.WinSmallGame,
WinTotal: param.WinTotal, WinTotal: param.WinTotal,
CycleId: this.CycleID,
} }
if param.OnlyLog { if param.OnlyLog {
ret.Log = append(ret.Log, log) ret.Log = append(ret.Log, log)
@ -223,10 +226,11 @@ func (s *SaveGameDetailedCopy) Save() {
} }
} }
// LabaLog 拉霸缓存游戏记录 // LabaLog 拉霸缓存游戏记录,为了统计游戏时长
type LabaLog struct { type LabaLog struct {
PlayerListLog *SaveGamePlayerListLogCopy PlayerListLog *SaveGamePlayerListLogCopy
GameDetailLog *SaveGameDetailedCopy GameDetailLog *SaveGameDetailedCopy
CacheTime time.Time // 缓存时间
} }
// Cache 临时缓存 // Cache 临时缓存
@ -238,13 +242,31 @@ func (l *LabaLog) Cache(s *Scene, detailLog *SaveGameDetailedParam, playerListLo
playerListLog.OnlyLog = true playerListLog.OnlyLog = true
l.GameDetailLog = s.SaveGameDetailedLog(detailLog) l.GameDetailLog = s.SaveGameDetailedLog(detailLog)
l.PlayerListLog = s.SaveGamePlayerListLog(playerListLog) l.PlayerListLog = s.SaveGamePlayerListLog(playerListLog)
l.CacheTime = time.Now()
} }
// Save 保存 // Save 保存
func (l *LabaLog) Save(f func(log *LabaLog)) { func (l *LabaLog) Save(second int32) {
f(l) if second <= 0 {
l.PlayerListLog.Save() second = int32(time.Now().Sub(l.CacheTime).Seconds())
l.GameDetailLog.Save() }
if l.PlayerListLog != nil {
if l.PlayerListLog.UpLog != nil {
for _, v := range l.PlayerListLog.UpLog.Log {
v.GamingTime = second
}
}
l.PlayerListLog.Save()
}
if l.GameDetailLog != nil {
for _, v := range l.GameDetailLog.Log {
v.GameTiming = second
}
l.GameDetailLog.Save()
}
l.Clear() l.Clear()
} }
@ -252,4 +274,5 @@ func (l *LabaLog) Save(f func(log *LabaLog)) {
func (l *LabaLog) Clear() { func (l *LabaLog) Clear() {
l.PlayerListLog = nil l.PlayerListLog = nil
l.GameDetailLog = nil l.GameDetailLog = nil
l.CacheTime = time.Time{}
} }

View File

@ -7,6 +7,7 @@ import (
"math/rand" "math/rand"
"time" "time"
"go.mongodb.org/mongo-driver/bson/primitive"
rawproto "google.golang.org/protobuf/proto" rawproto "google.golang.org/protobuf/proto"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/netlib"
@ -637,19 +638,19 @@ type ReportGameEventOnly struct {
func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEventOnly { func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEventOnly {
// 记录玩家 首次参与该场次的游戏时间 游戏次数 // 记录玩家 首次参与该场次的游戏时间 游戏次数
var gameFirstTime, gameFreeFirstTime time.Time var gameFirstTime, gameFreeFirstTime, gamedifFirstTime time.Time
var gameTimes, gameFreeTimes int64 var gameTimes, gameFreeTimes, gamedifTimes int64
data, ok := this.GDatas[this.scene.KeyGamefreeId] data, ok := this.GDatas[this.scene.KeyGamefreeId]
if ok { if ok {
gameFirstTime = data.FirstTime gameFreeFirstTime = data.FirstTime
gameTimes = data.Statics.GameTimes gameFreeTimes = data.Statics.GameTimes
} }
// 记录玩家 首次参与该游戏时间 游戏次数(不区分场次) // 记录玩家 首次参与该游戏时间 游戏次数(不区分场次)
dataGame, ok := this.GDatas[this.scene.KeyGameId] dataGame, ok := this.GDatas[this.scene.KeyGameId]
if ok { if ok {
gameFreeFirstTime = dataGame.FirstTime gameFirstTime = dataGame.FirstTime
gameFreeTimes = dataGame.Statics.GameTimes gameTimes = dataGame.Statics.GameTimes
} }
isNew := int32(0) isNew := int32(0)
@ -658,7 +659,7 @@ func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEven
isNew = 1 isNew = 1
} }
if param.GameTime < 0 { if param.GameTime <= 0 {
param.GameTime = int64(time.Now().Sub(this.scene.GameNowTime).Seconds()) param.GameTime = int64(time.Now().Sub(this.scene.GameNowTime).Seconds())
} }
if param.GameTime < 0 { if param.GameTime < 0 {
@ -668,30 +669,32 @@ func (this *Player) ReportGameEvent(param *ReportGameEventParam) *ReportGameEven
var ret ReportGameEventOnly var ret ReportGameEventOnly
ret.Param = param ret.Param = param
log := &model.PlayerGameRecEvent{ log := &model.PlayerGameRecEvent{
Platform: this.Platform, Id: primitive.NewObjectID().Hex(),
RecordId: this.scene.GetRecordId(), RecordId: this.scene.GetRecordId(),
SnId: this.GetSnId(), SnId: this.GetSnId(),
Channel: this.Channel, Channel: this.Channel,
ChannelId: this.ChannelId, Platform: this.Platform,
City: this.City, OS: this.DeviceOS,
OS: this.DeviceOS, GameId: this.scene.GameId,
GameId: this.scene.GameId, ModeId: this.scene.GameMode,
ModeId: this.scene.GameMode, Tax: param.Tax,
Tax: param.Tax, Amount: param.Change,
Amount: param.Change, CreateTime: time.Now().Unix(),
CreateTime: this.CreateTime.Unix(), CreateDayTime: tCreateDay.Unix(),
CreateDayTime: tCreateDay.Unix(), Out: param.Out,
Out: param.Out, In: param.In,
In: param.In, IsNew: isNew,
IsNew: isNew, GameFreeID: this.scene.GetGameFreeId(),
GameFreeID: this.scene.GetGameFreeId(), GamingTime: int32(param.GameTime),
GamingTime: int32(param.GameTime), GameDif: this.scene.GetDBGameFree().GetGameDif(),
FirstTime: gameFirstTime.Unix(), FirstGameDifTime: gamedifFirstTime.Unix(),
PlayTimes: gameTimes, GameDifTimes: gamedifTimes,
FirstGameTime: gameFreeFirstTime.Unix(), FirstTime: gameFreeFirstTime.Unix(),
PlayGameTimes: gameFreeTimes, PlayTimes: gameFreeTimes,
LastLoginTime: this.LastLoginTime.Unix(), FirstGameTime: gameFirstTime.Unix(),
DeviceId: this.DeviceId, PlayGameTimes: gameTimes,
LastLoginTime: this.LastLoginTime.Unix(),
ChannelId: this.ChannelId,
} }
if param.OnlyLog { if param.OnlyLog {
ret.Log = append(ret.Log, log) ret.Log = append(ret.Log, log)

View File

@ -2057,6 +2057,7 @@ func (this *Scene) IsControl(hasRobotGaming bool) bool {
// Statistics 玩家游戏数据统计 // Statistics 玩家游戏数据统计
// 包含水池统计,黑白名单统计,新手调控统计,个人水池统计 // 包含水池统计,黑白名单统计,新手调控统计,个人水池统计
// 拉霸游戏数据统计,一次下注记录一次 StaticsLaba
func (this *Scene) Statistics(param *StaticParam) { func (this *Scene) Statistics(param *StaticParam) {
if param == nil { if param == nil {
return return
@ -2110,6 +2111,7 @@ func (this *Scene) Statistics(param *StaticParam) {
var statics []*model.PlayerGameStatics var statics []*model.PlayerGameStatics
keyGameId := strconv.Itoa(this.GetGameId()) keyGameId := strconv.Itoa(this.GetGameId())
keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId())) keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId()))
keyGameDif := common.GetGameDifKey(this.GetDBGameFree().GetGameDif())
// 当天数据统计 // 当天数据统计
// 按场次分 // 按场次分
if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok { if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok {
@ -2127,6 +2129,14 @@ func (this *Scene) Statistics(param *StaticParam) {
p.TodayGameData.CtrlData[keyGameId] = data p.TodayGameData.CtrlData[keyGameId] = data
statics = append(statics, data) statics = append(statics, data)
} }
// 按游戏组分
if data, ok := p.TodayGameData.CtrlData[keyGameDif]; ok {
statics = append(statics, data)
} else {
data = model.NewPlayerGameStatics()
p.TodayGameData.CtrlData[keyGameDif] = data
statics = append(statics, data)
}
// 按场次分 // 按场次分
if data, ok := p.GDatas[keyGameFreeId]; ok { if data, ok := p.GDatas[keyGameFreeId]; ok {
if data.FirstTime.IsZero() { if data.FirstTime.IsZero() {
@ -2149,6 +2159,27 @@ func (this *Scene) Statistics(param *StaticParam) {
p.GDatas[keyGameId] = data p.GDatas[keyGameId] = data
statics = append(statics, &data.Statics) statics = append(statics, &data.Statics)
} }
//按游戏组分
getMinTime := func() time.Time {
var minTime = time.Now()
for _, v := range srvdata.GameFreeMgr.GetGameId(this.GetDBGameFree().GetGameDif()) {
vv := p.GDatas[strconv.Itoa(int(v))]
if vv != nil && vv.FirstTime.Before(minTime) {
minTime = vv.FirstTime
}
}
return minTime
}
if data, ok := p.GDatas[keyGameDif]; ok {
if data.FirstTime.IsZero() {
data.FirstTime = getMinTime()
}
statics = append(statics, &data.Statics)
} else {
data = &model.PlayerGameInfo{FirstTime: getMinTime()}
p.GDatas[keyGameDif] = data
statics = append(statics, &data.Statics)
}
// 新手输赢统计 // 新手输赢统计
if !model.GameParamData.CloseNovice && !common.InSliceInt(model.GameParamData.CloseNoviceGame, int(this.GameId)) && isControl && wbLevel == 0 && isNovice { if !model.GameParamData.CloseNovice && !common.InSliceInt(model.GameParamData.CloseNoviceGame, int(this.GameId)) && isControl && wbLevel == 0 && isNovice {
@ -2319,6 +2350,7 @@ func (this *Scene) StaticsLaba(param *StaticLabaParam) {
var statics []*model.PlayerGameStatics var statics []*model.PlayerGameStatics
keyGameId := strconv.Itoa(this.GetGameId()) keyGameId := strconv.Itoa(this.GetGameId())
keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId())) keyGameFreeId := strconv.Itoa(int(this.GetGameFreeId()))
keyGameDif := common.GetGameDifKey(this.GetDBGameFree().GetGameDif())
// 当天数据统计 // 当天数据统计
// 按场次分 // 按场次分
if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok { if data, ok := p.TodayGameData.CtrlData[keyGameFreeId]; ok {
@ -2336,6 +2368,14 @@ func (this *Scene) StaticsLaba(param *StaticLabaParam) {
p.TodayGameData.CtrlData[keyGameId] = data p.TodayGameData.CtrlData[keyGameId] = data
statics = append(statics, data) statics = append(statics, data)
} }
// 按游戏组
if data, ok := p.TodayGameData.CtrlData[keyGameDif]; ok {
statics = append(statics, data)
} else {
data = model.NewPlayerGameStatics()
p.TodayGameData.CtrlData[keyGameDif] = data
statics = append(statics, data)
}
// 按场次分 // 按场次分
if data, ok := p.GDatas[keyGameFreeId]; ok { if data, ok := p.GDatas[keyGameFreeId]; ok {
if data.FirstTime.IsZero() { if data.FirstTime.IsZero() {
@ -2358,6 +2398,27 @@ func (this *Scene) StaticsLaba(param *StaticLabaParam) {
p.GDatas[keyGameId] = data p.GDatas[keyGameId] = data
statics = append(statics, &data.Statics) statics = append(statics, &data.Statics)
} }
// 按游戏组
getMinTime := func() time.Time {
var minTime = time.Now()
for _, v := range srvdata.GameFreeMgr.GetGameId(this.GetDBGameFree().GetGameDif()) {
vv := p.GDatas[strconv.Itoa(int(v))]
if vv != nil && vv.FirstTime.Before(minTime) {
minTime = vv.FirstTime
}
}
return minTime
}
if data, ok := p.GDatas[keyGameDif]; ok {
if data.FirstTime.IsZero() {
data.FirstTime = getMinTime()
}
statics = append(statics, &data.Statics)
} else {
data = &model.PlayerGameInfo{FirstTime: getMinTime()}
p.GDatas[keyGameDif] = data
statics = append(statics, &data.Statics)
}
for _, data := range statics { for _, data := range statics {
if data != nil { if data != nil {

View File

@ -1035,8 +1035,6 @@ func CaiShenCheckAndSaveLog(sceneEx *CaiShenSceneData, playerEx *CaiShenPlayerDa
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -1315,8 +1315,6 @@ func (this *SceneStateBilled) OnEnter(s *base.Scene) {
Platform: o_player.Platform, Platform: o_player.Platform,
Snid: o_player.UserId, Snid: o_player.UserId,
PlayerName: "", PlayerName: "",
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: o_player.GainTaxCoin, TaxCoin: o_player.GainTaxCoin,

View File

@ -795,8 +795,6 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -904,8 +904,6 @@ func EasterIslandCheckAndSaveLog(sceneEx *EasterIslandSceneData, playerEx *Easte
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -267,8 +267,6 @@ func (this *FishingPlayerData) SaveDetailedLog(s *base.Scene) {
Platform: this.Platform, Platform: this.Platform,
Snid: this.SnId, Snid: this.SnId,
PlayerName: this.Name, PlayerName: this.Name,
Channel: this.Channel,
ChannelId: this.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: int64(this.sTaxCoin), TaxCoin: int64(this.sTaxCoin),

View File

@ -537,8 +537,6 @@ func FortuneDragonAndSaveLog(sceneEx *FortuneDragonSceneData, playerEx *FortuneD
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -548,8 +548,6 @@ func FortuneMouseAndSaveLog(sceneEx *FortuneMouseSceneData, playerEx *FortuneMou
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -548,8 +548,6 @@ func FortuneOxAndSaveLog(sceneEx *FortuneOxSceneData, playerEx *FortuneOxPlayerD
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -535,8 +535,6 @@ func FortuneRabbitAndSaveLog(sceneEx *FortuneRabbitSceneData, playerEx *FortuneR
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -548,8 +548,6 @@ func FortuneTigerAndSaveLog(sceneEx *FortuneTigerSceneData, playerEx *FortuneTig
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -345,8 +345,6 @@ func (s *FruitsSceneData) SaveLog(p *FruitsPlayerData, isOffline int) {
Platform: p.Platform, Platform: p.Platform,
Snid: p.SnId, Snid: p.SnId,
PlayerName: p.Name, PlayerName: p.Name,
Channel: p.Channel,
ChannelId: p.ChannelId,
TotalIn: totalIn, TotalIn: totalIn,
TotalOut: totalOut, TotalOut: totalOut,
TaxCoin: p.taxCoin, TaxCoin: p.taxCoin,

View File

@ -954,8 +954,6 @@ func IceAgeCheckAndSaveLog(sceneEx *IceAgeSceneData, playerEx *IceAgePlayerData)
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -367,8 +367,6 @@ func (s *RichBlessedSceneData) SaveLog(p *RichBlessedPlayerData, isOffline int)
Platform: p.Platform, Platform: p.Platform,
Snid: p.SnId, Snid: p.SnId,
PlayerName: p.Name, PlayerName: p.Name,
Channel: p.Channel,
ChannelId: p.ChannelId,
TotalIn: totalIn, TotalIn: totalIn,
TotalOut: totalOut, TotalOut: totalOut,
TaxCoin: p.taxCoin, TaxCoin: p.taxCoin,

View File

@ -1179,8 +1179,6 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -1258,8 +1256,6 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -790,8 +790,6 @@ func TamQuocCheckAndSaveLog(sceneEx *TamQuocSceneData, playerEx *TamQuocPlayerDa
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,

View File

@ -188,8 +188,6 @@ func (this *PolicyThirteen) OnPlayerLeave(s *base.Scene, p *base.Player, reason
Platform: playerEx.Platform, Platform: playerEx.Platform,
Snid: playerEx.SnId, Snid: playerEx.SnId,
PlayerName: playerEx.Name, PlayerName: playerEx.Name,
Channel: playerEx.Channel,
ChannelId: playerEx.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: playerEx.taxCoin, TaxCoin: playerEx.taxCoin,
@ -1438,8 +1436,6 @@ func (this *StateBilled) OnEnter(s *base.Scene) {
Platform: o_player.Platform, Platform: o_player.Platform,
Snid: o_player.SnId, Snid: o_player.SnId,
PlayerName: o_player.Name, PlayerName: o_player.Name,
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: o_player.taxCoin, TaxCoin: o_player.taxCoin,

View File

@ -2761,8 +2761,6 @@ func (this *SceneBilledStateTienLen) OnEnter(s *base.Scene) {
LogId: sceneEx.recordId, LogId: sceneEx.recordId,
Platform: o_player.Platform, Platform: o_player.Platform,
Snid: o_player.UserId, Snid: o_player.UserId,
Channel: o_player.Channel,
ChannelId: o_player.ChannelId,
TotalIn: totalin, TotalIn: totalin,
TotalOut: totalout, TotalOut: totalout,
TaxCoin: o_player.BillTaxCoin, TaxCoin: o_player.BillTaxCoin,

View File

@ -245,34 +245,36 @@ func CreatePlayerLoginEvent(snid int32, channel, promoter, platform, city, os, i
// 玩家游戏记录 // 玩家游戏记录
type PlayerGameRecEvent struct { type PlayerGameRecEvent struct {
RecordId string //游戏记录ID Id string //id
SnId int32 //用户ID RecordId string //游戏记录ID
Channel string //包类型 SnId int32 //用户ID
Promoter string //推广 Channel string //包类型
Platform string //平台 Platform string //平台
City string //城市 OS string //操作系统
OS string //操作系统 GameId int32 //游戏id
TelephonePromoter int32 //电销标记 ModeId int32 //游戏模式
GameId int32 //游戏id Tax int64 //税收
ModeId int32 //游戏模式 Amount int64 //金币变化,税后(正值为赢;负值为输)
Tax int64 //税收 CreateTime int64 //创建时间
Amount int64 //金币变化(正值为赢;负值为输) CreateDayTime int64 //账号创建时间0点
CreateTime int64 //创建时间 Out int64 //产出
CreateDayTime int64 //账号创建时间0点 In int64 //投入
ValidBet int64 //有效下注数量 IsNew int32 //是否是新人
ValidFlow int64 //有效流水数量 GameFreeID int32 //游戏freeid
Out int64 //产出 GamingTime int32 //游戏开始到玩家结算的时长 单位:秒
In int64 //投入
IsNew int32 //是否是新人 GameDif string // 游戏分组
GameFreeID int32 //游戏freeid FirstGameDifTime int64 // 首次游戏分组时间
GamingTime int32 //游戏开始到玩家结算的时长 单位:秒 GameDifTimes int64 // 游戏分组游戏次数
FirstTime int64 //首次玩该场次游戏时间
PlayTimes int64 //该场次游戏次数 FirstTime int64 //首次玩该场次游戏时间
FirstGameTime int64 //首次玩游戏时间 PlayTimes int64 //该场次游戏次数
PlayGameTimes int64 //该游戏总次数
LastLoginTime int64 //最后登录时间 FirstGameTime int64 //首次玩游戏时间
DeviceId string //设备id PlayGameTimes int64 //该游戏总次数
ChannelId string //推广渠道id
LastLoginTime int64 //最后登录时间
ChannelId string //推广渠道id
} }
// 玩家游戏记录 // 玩家游戏记录

View File

@ -23,9 +23,33 @@ type CoinPoolCtx struct {
Controlled bool //被水池控制了 Controlled bool //被水池控制了
} }
type GameDetailedLogRet struct { type GameDetailedLog struct {
Gplt GameDetailedLogType Id bson.ObjectId `bson:"_id"`
Platform string // 平台
LogId string // 记录ID每局游戏唯一
GameDif string // 游戏组
GameId int32 // 游戏id
GameClass int32 // 游戏类型
GameMode int32 // 游戏模式,弃用
GameType int32 // 游戏类型
GameFreeId int32 // 场次id
CycleId string // 房卡场id多轮有相同的id
MatchId int64 // 比赛ID应该用字符串的
SceneId int32 // 房间id会重复
PlayerCount int32 // 玩家数量
GameTiming int32 // 游戏用时,秒
GameBaseBet int32 // 游戏底分
Ts int64 // 时间戳
Time time.Time // 记录时间
GameDetailedNote string // 游戏详情
GameDetailVer int32 // 游戏详情版本
CpCtx CoinPoolCtx // 水池上下文信息
Trend20Lately string // 最近游戏走势
CtrlType int // 1控赢 2控输 0不控
PlayerPool map[int]int // 个人水池分 玩家id:分
} }
type GameDetailedLogType struct { type GameDetailedLogType struct {
PageNo int //当前页码 PageNo int //当前页码
PageSize int //每页数量 PageSize int //每页数量
@ -33,64 +57,8 @@ type GameDetailedLogType struct {
Data []*GameDetailedLog //当页数据 Data []*GameDetailedLog //当页数据
} }
type GameDetailedLog struct { type GameDetailedLogRet struct {
Id bson.ObjectId `bson:"_id"` //记录ID Gplt GameDetailedLogType
LogId string //记录ID每局游戏唯一
GameId int32 //游戏id
ClubId int32 //俱乐部Id
ClubRoom string //俱乐部包间
Platform string //平台id
Channel string //渠道
Promoter string //推广员
MatchId int64 //比赛ID应该用字符串的
SceneId int32 //房间id会重复
GameMode int32 //游戏类型
GameFreeid int32 //游戏类型房间号
PlayerCount int32 //玩家数量
GameTiming int32 //本局游戏用时(mm)
GameBaseBet int32 //游戏单位低分
GameDetailedNote string //游戏详情
GameDetailVer int32 //游戏详情版本
CpCtx CoinPoolCtx //水池上下文信息
Time time.Time //记录时间
Trend20Lately string //最近游戏走势
Ts int64 //时间戳
CtrlType int // 1控赢 2控输 0不控
PlayerPool map[int]int // 个人水池分
CycleId string // 本轮id打一轮有多局
}
func NewGameDetailedLog() *GameDetailedLog {
log := &GameDetailedLog{Id: bson.NewObjectId()}
return log
}
func NewGameDetailedLogEx(logid string, gameid, sceneid, gamemode, gamefreeid, playercount, gametiming, gamebasebet int32,
gamedetailednote string, platform string, clubId int32, clubRoom string, cpCtx CoinPoolCtx, ver int32,
trend20Lately string, ctrlType int, playerPool map[int]int, cycleId string) *GameDetailedLog {
cl := NewGameDetailedLog()
cl.LogId = logid
cl.GameId = gameid
cl.ClubId = clubId
cl.ClubRoom = clubRoom
cl.SceneId = sceneid
cl.GameMode = gamemode
cl.GameFreeid = gamefreeid
cl.PlayerCount = playercount
cl.GameTiming = gametiming
cl.GameBaseBet = gamebasebet
cl.GameDetailedNote = gamedetailednote
cl.Platform = platform
tNow := time.Now()
cl.Time = tNow
cl.CpCtx = cpCtx
cl.GameDetailVer = ver
cl.Trend20Lately = trend20Lately
cl.Ts = time.Now().Unix()
cl.CtrlType = ctrlType
cl.PlayerPool = playerPool
cl.CycleId = cycleId
return cl
} }
func InsertGameDetailedLog(log *GameDetailedLog) (err error) { func InsertGameDetailedLog(log *GameDetailedLog) (err error) {

View File

@ -21,86 +21,36 @@ type GameTotalRecord struct {
type GamePlayerListLog struct { type GamePlayerListLog struct {
LogId bson.ObjectId `bson:"_id"` //记录ID LogId bson.ObjectId `bson:"_id"` //记录ID
SnId int32 //用户Id Platform string // 平台
Name string //名称 GameDif string // 游戏组
GameId int32 //游戏id GameId int32 // 游戏id
BaseScore int32 //游戏底注 GameClass int32 // 游戏类型
ClubId int32 //俱乐部Id GameMode int32 // 游戏模式,弃用
ClubRoom string //俱乐部包间 GameType int32 // 游戏类型
TaxCoin int64 //税收 GameFreeId int32 // 场次id
ClubPumpCoin int64 //俱乐部额外抽水 BaseScore int32 // 游戏底注
Platform string //平台id GameDetailedLogId string // 游戏记录Id
Channel string //渠道 Channel string // 包类型
Promoter string //推广员 ChannelId string // 推广渠道
PackageTag string //包标识 RoomType int32 // 房间类型
SceneId int32 //场景ID Ts int64 // 记录时间
GameMode int32 //游戏类型 Time time.Time // 记录时间
GameFreeid int32 //游戏类型房间号 CycleId string // 本轮id打一轮有多局
GameDetailedLogId string //游戏记录Id
IsFirstGame bool //是否第一次游戏
//对于拉霸类BetAmount=100 WinAmountNoAnyTax=0 (表示投入多少、收益多少,值>=0
//拉霸类小游戏会是BetAmount=0 WinAmountNoAnyTax=100 投入0、收益多少值>=0
//对战场BetAmount=0 WinAmountNoAnyTax=100 投入会有是0、收益有正负WinAmountNoAnyTax=100则盈利WinAmountNoAnyTax=-100则输100
BetAmount int64 //下注金额
WinAmountNoAnyTax int64 //盈利金额,不包含任何税
TotalIn int64 //本局投入
TotalOut int64 //本局产出
Time time.Time //记录时间
RoomType int32 //房间类型
GameDif string //游戏标识
GameClass int32 //游戏类型 1棋牌 2电子 3百人 4捕鱼 5视讯 6彩票 7体育
MatchId int64
MatchType int64 //0.普通场 1.锦标赛 2.冠军赛 3.vip专属
Ts int64
IsFree bool //拉霸专用 是否免费
WinSmallGame int64 //拉霸专用 小游戏奖励
WinTotal int64 //拉霸专用 输赢
CycleId string // 本轮id打一轮有多局
}
func NewGamePlayerListLog() *GamePlayerListLog { SnId int32 // 用户Id
log := &GamePlayerListLog{LogId: bson.NewObjectId()} Name string // 名称
return log SceneId int32 // 房间id会重复
} MatchId int64 // 比赛ID应该用字符串的
func NewGamePlayerListLogEx(snid int32, gamedetailedlogid string, platform, channel, promoter, packageTag string, gameid, baseScore, MatchType int64 // 0.普通场 1.锦标赛 2.冠军赛 3.vip专属
sceneid, gamemode, gamefreeid int32, totalin, totalout int64, clubId int32, clubRoom string, taxCoin, pumpCoin int64, roomType int32, WinAmountNoAnyTax int64 // 盈利金额,不包含任何税
betAmount, winAmountNoAnyTax int64, key, name string, gameClass int32, isFirst bool, matchid, matchType int64, TaxCoin int64 // 税收
isFree bool, winSmallGame, winTotal int64, cycleId string) *GamePlayerListLog { BetAmount int64 // 下注金额
cl := NewGamePlayerListLog() IsFirstGame bool // 是否第一次游戏
cl.SnId = snid TotalIn int64 // 本局投入
cl.GameDetailedLogId = gamedetailedlogid TotalOut int64 // 本局产出
cl.Platform = platform IsFree bool // 拉霸专用 是否免费
cl.Name = name WinSmallGame int64 // 拉霸专用 小游戏奖励
cl.Channel = channel WinTotal int64 // 拉霸专用 输赢
cl.Promoter = promoter
cl.PackageTag = packageTag
cl.GameFreeid = gamefreeid
cl.GameId = gameid
cl.BaseScore = baseScore
cl.ClubId = clubId
cl.GameMode = gamemode
cl.SceneId = sceneid
cl.TotalIn = totalin
cl.TotalOut = totalout
cl.ClubRoom = clubRoom
cl.TaxCoin = taxCoin
cl.IsFirstGame = isFirst
cl.ClubPumpCoin = pumpCoin
cl.RoomType = roomType
cl.BetAmount = betAmount
cl.WinAmountNoAnyTax = winAmountNoAnyTax
cl.GameDif = key
cl.GameClass = gameClass
cl.IsFree = isFree
cl.WinSmallGame = winSmallGame
cl.WinTotal = winTotal
tNow := time.Now()
cl.Ts = tNow.Unix()
cl.Time = tNow
cl.MatchId = matchid
cl.MatchType = matchType
cl.CycleId = cycleId
return cl
} }
type GamePlayerListRet struct { type GamePlayerListRet struct {

View File

@ -28,6 +28,7 @@ type ItemLog struct {
TypeId int32 // 变化类型 TypeId int32 // 变化类型
GameId int64 // 游戏id,游戏中获得时有值 GameId int64 // 游戏id,游戏中获得时有值
GameFreeId int64 // 场次id,游戏中获得时有值 GameFreeId int64 // 场次id,游戏中获得时有值
GameDif string // 游戏分组
Cost []*Item // 消耗的道具 Cost []*Item // 消耗的道具
Id string // 撤销的id兑换失败 Id string // 撤销的id兑换失败
RoomConfigId int32 // 房间配置id RoomConfigId int32 // 房间配置id
@ -50,6 +51,7 @@ type ItemParam struct {
TypeId int32 // 变化类型 TypeId int32 // 变化类型
GameId int64 // 游戏id,游戏中获得时有值 GameId int64 // 游戏id,游戏中获得时有值
GameFreeId int64 // 场次id,游戏中获得时有值 GameFreeId int64 // 场次id,游戏中获得时有值
GameDif string // 游戏分组
Cost []*Item // 消耗的道具 Cost []*Item // 消耗的道具
LogId string // 撤销的id兑换失败 LogId string // 撤销的id兑换失败
RoomConfigId int32 // 房间配置id RoomConfigId int32 // 房间配置id
@ -71,6 +73,7 @@ func NewItemLogEx(param ItemParam) *ItemLog {
itemLog.TypeId = param.TypeId itemLog.TypeId = param.TypeId
itemLog.GameId = param.GameId itemLog.GameId = param.GameId
itemLog.GameFreeId = param.GameFreeId itemLog.GameFreeId = param.GameFreeId
itemLog.GameDif = param.GameDif
itemLog.Cost = param.Cost itemLog.Cost = param.Cost
itemLog.Id = param.LogId itemLog.Id = param.LogId
itemLog.RoomConfigId = param.RoomConfigId itemLog.RoomConfigId = param.RoomConfigId
@ -246,7 +249,7 @@ type InsertItemLogReq struct {
Logs []*ItemLog Logs []*ItemLog
} }
func InsertItemLog(configItems map[int32]*server.DB_GameItem, param *AddItemParam, isOffline bool) error { func InsertItemLog(configItems map[int32]*server.DB_GameItem, param *AddItemParam, gamedif string, isOffline bool) error {
if rpcCli == nil { if rpcCli == nil {
logger.Logger.Warnf("rpcCli is nil") logger.Logger.Warnf("rpcCli is nil")
return errors.New("rpcCli is nil") return errors.New("rpcCli is nil")
@ -280,6 +283,7 @@ func InsertItemLog(configItems map[int32]*server.DB_GameItem, param *AddItemPara
TypeId: param.GainWay, TypeId: param.GainWay,
GameId: param.GameId, GameId: param.GameId,
GameFreeId: param.GameFreeId, GameFreeId: param.GameFreeId,
GameDif: gamedif,
Cost: param.Cost, Cost: param.Cost,
LogId: param.LogId, LogId: param.LogId,
RoomConfigId: param.RoomConfigId, RoomConfigId: param.RoomConfigId,

View File

@ -99,6 +99,7 @@ func SCPlayerFlag(s *netlib.Session, packetid int, data interface{}) error {
return nil return nil
} }
// 更新房间里玩家的状态
if scene, ok := GetScene(s).(IScene); ok && scene != nil { if scene, ok := GetScene(s).(IScene); ok && scene != nil {
p := scene.GetPlayerBySnid(msg.GetPlayerId()) p := scene.GetPlayerBySnid(msg.GetPlayerId())
if p != nil { if p != nil {

View File

@ -52,6 +52,7 @@ func SCDestroyRoom(s *netlib.Session, packid int, pack interface{}) error {
if msg.GetOpRetCode() == gamehallproto.OpResultCode_Game_OPRC_Sucess_Game { if msg.GetOpRetCode() == gamehallproto.OpResultCode_Game_OPRC_Sucess_Game {
cleanRoomState(s) cleanRoomState(s)
SceneMgrSingleton.DelScene(msg.GetRoomId())
return nil return nil
} }

View File

@ -27,6 +27,19 @@ import (
登录及机器人账号更新 登录及机器人账号更新
*/ */
func init() {
common.RegisterClockFunc(&common.ClockFunc{
OnHourTimerFunc: func() {
ClientMgrSingleton.AccountReplace()
logger.Logger.Info(ClientMgrSingleton.GetState())
},
OnDayTimerFunc: func() {
ClientMgrSingleton.AccountDeletePolicy()
},
})
}
var ClientMgrSingleton = &ClientMgr{ var ClientMgrSingleton = &ClientMgr{
sessionPool: make(map[string]*netlib.Session), sessionPool: make(map[string]*netlib.Session),
Running: true, Running: true,
@ -97,13 +110,17 @@ func (this *ClientMgr) UnRegisterSession(acc string) {
delete(this.sessionPool, acc) delete(this.sessionPool, acc)
} }
func (this *ClientMgr) HourChange() { // AccountReplace 账号替换
func (this *ClientMgr) AccountReplace() {
fileModify := false fileModify := false
eventArr := this.CycleTimeEvent[time.Now().Hour()] eventArr := this.CycleTimeEvent[time.Now().Hour()]
for _, event := range eventArr { for _, event := range eventArr {
accChan[event.newAcc] = true //使用新的账号 accChan[event.newAcc] = true //使用新的账号
cfg := NewSessionConfig()
netlib.Connect(cfg) //创建新的连接 //创建新的连接
NewSession()
// 关闭旧的连接
if session, ok := this.sessionPool[event.oldAcc]; ok && session != nil { if session, ok := this.sessionPool[event.oldAcc]; ok && session != nil {
//删除旧有账号数据 //删除旧有账号数据
pack := &serverproto.RWAccountInvalid{ pack := &serverproto.RWAccountInvalid{
@ -115,6 +132,7 @@ func (this *ClientMgr) HourChange() {
//关闭连接 //关闭连接
session.Close() session.Close()
} }
//更新本地账号数据信息 //更新本地账号数据信息
for key, value := range accPool { for key, value := range accPool {
if value.Acc == event.oldAcc { if value.Acc == event.oldAcc {
@ -143,7 +161,8 @@ func (this *ClientMgr) HourChange() {
} }
} }
func (this *ClientMgr) DayChange() { // AccountDeletePolicy 账号删除策略
func (this *ClientMgr) AccountDeletePolicy() {
invalidCount := 0 //过期账号数量 invalidCount := 0 //过期账号数量
updateLimit := len(accPool) * model.GameParamData.InvalidRobotAccRate / 100 //可更新的账号数量 updateLimit := len(accPool) * model.GameParamData.InvalidRobotAccRate / 100 //可更新的账号数量
invalidAccs := []InvalidAcc{} invalidAccs := []InvalidAcc{}
@ -182,3 +201,23 @@ func (this *ClientMgr) DayChange() {
this.CycleTimeEvent[timePoint] = eventArr this.CycleTimeEvent[timePoint] = eventArr
} }
} }
type ClientState struct {
SessionNum int
Event map[int]int
}
func (c *ClientState) String() string {
return fmt.Sprintf("ClientMgrState 连接总数:%v, 每小时账号替换数量:%v", c.SessionNum, c.Event)
}
func (this *ClientMgr) GetState() *ClientState {
ret := &ClientState{
SessionNum: len(this.sessionPool),
Event: make(map[int]int),
}
for k, v := range this.CycleTimeEvent {
ret.Event[k] = len(v)
}
return ret
}

View File

@ -1,90 +0,0 @@
package base
import (
"time"
"mongo.games.com/goserver/core/module"
)
/*
计时器
*/
var ClockMgrSingleton = &ClockMgr{
LastHour: -1,
LastDay: -1,
}
type ClockMgr struct {
LastTime time.Time
LastMonth time.Month
LastWeek int
LastDay int
LastHour int
LastMini int
LastSec int
}
func (this *ClockMgr) ModuleName() string {
return "ClockMgr"
}
func (this *ClockMgr) Init() {
tNow := time.Now().Local()
this.LastTime = tNow
_, this.LastMonth, this.LastDay = tNow.Date()
this.LastHour, this.LastMini, this.LastSec = tNow.Hour(), tNow.Minute(), tNow.Second()
_, this.LastWeek = tNow.ISOWeek()
}
func (this *ClockMgr) Update() {
tNow := time.Now().Local()
sec := tNow.Second()
if sec != this.LastSec {
this.LastSec = sec
// 秒
PlayerMgrSingleton.OnSecondTimer()
min := tNow.Minute()
if min != this.LastMini {
this.LastMini = min
// 分
PlayerMgrSingleton.OnMiniTimer()
hour := tNow.Hour()
if hour != this.LastHour {
// 时
ClientMgrSingleton.HourChange()
this.LastHour = hour
day := tNow.Day()
if day != this.LastDay {
// 天
ClientMgrSingleton.DayChange()
this.LastDay = day
_, week := tNow.ISOWeek()
if week != this.LastWeek {
// 周
this.LastWeek = week
}
month := tNow.Month()
if month != this.LastMonth {
// 月
this.LastMonth = month
}
}
}
}
}
}
func (this *ClockMgr) Shutdown() {
module.UnregisteModule(this)
}
func init() {
module.RegisteModule(ClockMgrSingleton, time.Millisecond*500, 0)
}

View File

@ -18,12 +18,19 @@ var (
WaitConnectSessions []*netlib.SessionConfig WaitConnectSessions []*netlib.SessionConfig
) )
func NewSessionConfig() *netlib.SessionConfig { // NewSession 新建session
BenchMarkModule.idx++ // id 连接id, 默认自动分配
func NewSession(id ...int) {
cfg := Config.Connects cfg := Config.Connects
cfg.Id = BenchMarkModule.idx if len(id) > 0 && id[0] > 0 {
cfg.Id = id[0]
} else {
BenchMarkModule.idx++
cfg.Id = BenchMarkModule.idx
}
cfg.Init() cfg.Init()
return &cfg logger.Logger.Info("waite connect session id=", cfg.Id)
WaitConnectSessions = append(WaitConnectSessions, &cfg)
} }
type BenchMark struct { type BenchMark struct {
@ -37,9 +44,7 @@ func (m *BenchMark) ModuleName() string {
func (m *BenchMark) Init() { func (m *BenchMark) Init() {
m.idx = RobotSessionStartId m.idx = RobotSessionStartId
for i := 0; i < Config.Count; i++ { for i := 0; i < Config.Count; i++ {
cfg := NewSessionConfig() NewSession()
logger.Logger.Info("waite connect session id=", cfg.Id)
WaitConnectSessions = append(WaitConnectSessions, cfg)
} }
} }

View File

@ -62,10 +62,7 @@ func (g *GateSessionHandler) OnSessionClosed(s *netlib.Session) {
StopSessionPingTimer(s) StopSessionPingTimer(s)
if reconnect { if reconnect {
logger.Logger.Infof("账号重连 sessionID:%v account:%v", s.Id, accIdParam) logger.Logger.Infof("账号重连 sessionID:%v account:%v", s.Id, accIdParam)
cfg := Config.Connects NewSession(s.GetSessionConfig().Id)
cfg.Id = s.GetSessionConfig().Id
cfg.Init()
WaitConnectSessions = append(WaitConnectSessions, &cfg)
} }
} }

View File

@ -16,9 +16,9 @@ type AccountData struct {
} }
var ( var (
// 待使用的账号,将要建立连接 // 待登录的账号,将要建立连接
accChan = make(map[string]bool) accChan = make(map[string]bool)
// 账号池,当前正在使用的机器人 // 账号池,当前正在使用的机器人账号
accPool []*AccountData accPool []*AccountData
) )
var accountFileName = "robotaccount.json" var accountFileName = "robotaccount.json"

View File

@ -1,16 +1,32 @@
package base package base
import ( import (
"fmt"
"math/rand" "math/rand"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/netlib" "mongo.games.com/goserver/core/netlib"
"mongo.games.com/game/common"
"mongo.games.com/game/proto" "mongo.games.com/game/proto"
hall_proto "mongo.games.com/game/protocol/gamehall" hall_proto "mongo.games.com/game/protocol/gamehall"
player_proto "mongo.games.com/game/protocol/player" player_proto "mongo.games.com/game/protocol/player"
) )
func init() {
common.RegisterClockFunc(&common.ClockFunc{
OnSecTimerFunc: func() {
PlayerMgrSingleton.OnSecondTimer()
},
OnMiniTimerFunc: func() {
PlayerMgrSingleton.OnMiniTimer()
},
OnHourTimerFunc: func() {
logger.Logger.Info(PlayerMgrSingleton.GetState())
},
})
}
var PlayerMgrSingleton = &PlayerMgr{ var PlayerMgrSingleton = &PlayerMgr{
playersMapSnId: make(map[int32]*player_proto.SCPlayerData), playersMapSnId: make(map[int32]*player_proto.SCPlayerData),
playersSession: make(map[int32]*netlib.Session), playersSession: make(map[int32]*netlib.Session),
@ -161,3 +177,22 @@ func (pm *PlayerMgr) OnSecondTimer() {
func (pm *PlayerMgr) OnMiniTimer() { func (pm *PlayerMgr) OnMiniTimer() {
pm.ProcessCheckRobotNum() pm.ProcessCheckRobotNum()
} }
type PlayerMgrState struct {
PlayerNum int
NormalSessionNum int
MatchSessionNum int
}
func (p *PlayerMgrState) String() string {
return fmt.Sprintf("PlayerMgrState 玩家总数:%v, 普通场连接数:%v, 比赛场连接数:%v", p.PlayerNum, p.NormalSessionNum, p.MatchSessionNum)
}
func (pm *PlayerMgr) GetState() *PlayerMgrState {
ret := &PlayerMgrState{
PlayerNum: len(pm.playersMapSnId),
NormalSessionNum: len(pm.playersSession),
MatchSessionNum: len(pm.playersMatchSession),
}
return ret
}

View File

@ -1,14 +1,27 @@
package base package base
import ( import (
"fmt"
"time" "time"
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/module" "mongo.games.com/goserver/core/module"
"mongo.games.com/game/common"
server_proto "mongo.games.com/game/protocol/server" server_proto "mongo.games.com/game/protocol/server"
"mongo.games.com/game/srvdata" "mongo.games.com/game/srvdata"
) )
func init() {
module.RegisteModule(SceneMgrSingleton, time.Millisecond*100, 0)
common.RegisterClockFunc(&common.ClockFunc{
OnHourTimerFunc: func() {
logger.Logger.Info(SceneMgrSingleton.GetState())
},
})
}
var SceneMgrSingleton = &SceneMgr{ var SceneMgrSingleton = &SceneMgr{
Scenes: make(map[int32]IScene), Scenes: make(map[int32]IScene),
sceneDBGameFree: make(map[int32]*server_proto.DB_GameFree), sceneDBGameFree: make(map[int32]*server_proto.DB_GameFree),
@ -47,6 +60,7 @@ func (sm *SceneMgr) GetSceneDBGameFree(sceneId, gamefreeId int32) *server_proto.
return srvdata.PBDB_GameFreeMgr.GetData(gamefreeId) return srvdata.PBDB_GameFreeMgr.GetData(gamefreeId)
} }
// IsFreeMode 是否是自由桌
func (sm *SceneMgr) IsFreeMode(sceneId int32) bool { func (sm *SceneMgr) IsFreeMode(sceneId int32) bool {
if data, exist := sm.sceneDBGameFree[sceneId]; exist { if data, exist := sm.sceneDBGameFree[sceneId]; exist {
return data.GetFreeMode() == 1 return data.GetFreeMode() == 1
@ -54,6 +68,22 @@ func (sm *SceneMgr) IsFreeMode(sceneId int32) bool {
return false return false
} }
type SceneMgrState struct {
Num map[int32]int
}
func (s *SceneMgrState) String() string {
return fmt.Sprintf("SceneMgrState 每个游戏的房间数量 [游戏id:房间数量]: %v", s.Num)
}
func (sm *SceneMgr) GetState() *SceneMgrState {
m := make(map[int32]int)
for _, v := range sm.Scenes {
m[v.GetGameId()]++
}
return &SceneMgrState{Num: m}
}
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
// / Module Implement [beg] // / Module Implement [beg]
// ////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////
@ -74,7 +104,3 @@ func (sm *SceneMgr) ModuleName() string {
func (sm *SceneMgr) Shutdown() { func (sm *SceneMgr) Shutdown() {
module.UnregisteModule(sm) module.UnregisteModule(sm)
} }
func init() {
module.RegisteModule(SceneMgrSingleton, time.Millisecond*100, 0)
}

View File

@ -690,6 +690,15 @@ func (this *BagMgr) AddItems(param *model.AddItemParam) (*BagInfo, bag.OpResultC
logType = ItemConsume logType = ItemConsume
num = -v.ItemNum num = -v.ItemNum
} }
gamedif := ""
plt := PlatformMgrSingleton.GetPlatform(p.Platform)
if plt != nil {
gf := plt.GameConfig.GetGameConfig(int32(param.GameFreeId))
if gf != nil {
gamedif = gf.GetDbGameFree().GetGameDif()
}
}
// 日志 // 日志
log := model.NewItemLogEx(model.ItemParam{ log := model.NewItemLogEx(model.ItemParam{
Platform: p.Platform, Platform: p.Platform,
@ -702,6 +711,7 @@ func (this *BagMgr) AddItems(param *model.AddItemParam) (*BagInfo, bag.OpResultC
TypeId: param.GainWay, TypeId: param.GainWay,
GameId: param.GameId, GameId: param.GameId,
GameFreeId: param.GameFreeId, GameFreeId: param.GameFreeId,
GameDif: gamedif,
Cost: param.Cost, Cost: param.Cost,
LogId: param.LogId, LogId: param.LogId,
RoomConfigId: param.RoomConfigId, RoomConfigId: param.RoomConfigId,
@ -765,6 +775,15 @@ func (this *BagMgr) AddItemsOffline(param *model.AddItemParam, callback func(err
return return
} }
gamedif := ""
plt := PlatformMgrSingleton.GetPlatform(param.Platform)
if plt != nil && param.GameFreeId > 0 {
gf := plt.GameConfig.GetGameConfig(int32(param.GameFreeId))
if gf != nil {
gamedif = gf.GetDbGameFree().GetGameDif()
}
}
// 玩家离线时 // 玩家离线时
var findPlayer *model.PlayerBaseInfo var findPlayer *model.PlayerBaseInfo
task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} { task.New(nil, task.CallableWrapper(func(o *basic.Object) interface{} {
@ -793,7 +812,7 @@ func (this *BagMgr) AddItemsOffline(param *model.AddItemParam, callback func(err
return err return err
} }
// 保存日志 // 保存日志
if err := model.InsertItemLog(srvdata.GameItemMgr.GetItems(param.Platform), param, true); err != nil { if err := model.InsertItemLog(srvdata.GameItemMgr.GetItems(param.Platform), param, gamedif, true); err != nil {
logger.Logger.Errorf("离线保存道具变更日志错误 %v", err) logger.Logger.Errorf("离线保存道具变更日志错误 %v", err)
return err return err
} }

View File

@ -1310,8 +1310,6 @@ func (this *Player) UnmarshalData(data []byte, scene *Scene) {
this.PlayerData.TotalFlow = pd.TotalFlow this.PlayerData.TotalFlow = pd.TotalFlow
if this.WelfData != nil && this.WelfData.PigBank != nil && pd.WelfData != nil && pd.WelfData.PigBank != nil { if this.WelfData != nil && this.WelfData.PigBank != nil && pd.WelfData != nil && pd.WelfData.PigBank != nil {
this.WelfData.PigBank.BankCoin = pd.WelfData.PigBank.BankCoin this.WelfData.PigBank.BankCoin = pd.WelfData.PigBank.BankCoin
this.WelfData.PigBank.TakeTimes = pd.WelfData.PigBank.TakeTimes
this.WelfData.PigBank.DayBuyTimes = pd.WelfData.PigBank.DayBuyTimes
} }
this.ItemRecExpireTime = pd.ItemRecExpireTime this.ItemRecExpireTime = pd.ItemRecExpireTime
this.IsTakeExpireItem = pd.IsTakeExpireItem this.IsTakeExpireItem = pd.IsTakeExpireItem

View File

@ -341,7 +341,7 @@ func (this *Scene) PlayerEnter(p *Player, pos int, ischangeroom bool) bool {
//离场金币 //离场金币
leaverng := this.dbGameFree.GetRobotLimitCoin() leaverng := this.dbGameFree.GetRobotLimitCoin()
if len(leaverng) >= 2 { if len(leaverng) >= 2 {
leaveCoin = leaverng[0] + rand.Int63n(leaverng[1]-leaverng[0]) leaveCoin = int64(common.RandInt(int(leaverng[0]), int(leaverng[1])))
} }
} }

View File

@ -34,13 +34,14 @@ type SceneMgr struct {
common.BaseClockSinker // 驱动时间事件 common.BaseClockSinker // 驱动时间事件
scenes map[int]*Scene // 房间id: Scene scenes map[int]*Scene // 房间id: Scene
privateAutoId int // 私人房房间号 privateAutoId int // 私人房房间号
matchAutoId int // 比赛场房间号 matchAutoId int // 比赛场房间号
coinSceneAutoId int // 金币场房间号 coinSceneAutoId int // 金币场房间号
hundredSceneAutoId int // 百人场房间号 hundredSceneAutoId int // 百人场房间号
password map[string]struct{} // 密码
pushList map[int]struct{} // 已经推荐过的房间列表 password map[string]struct{} // 密码
lastPushSceneId int // 最后推荐的房间id pushList map[int]struct{} // 已经推荐过的房间列表
lastPushSceneId int // 最后推荐的房间id
} }
// AllocReplayCode 获取回访码 // AllocReplayCode 获取回访码

View File

@ -2212,10 +2212,10 @@ func init() {
WebAPIHandlerMgrSingleton.RegisteWebAPIHandler("/api/pay/CallbackPayment", WebAPIHandlerWrapper( WebAPIHandlerMgrSingleton.RegisteWebAPIHandler("/api/pay/CallbackPayment", WebAPIHandlerWrapper(
func(tNode *transact.TransNode, params []byte) (int, proto.Message) { func(tNode *transact.TransNode, params []byte) (int, proto.Message) {
logger.Logger.Tracef("api /api/pay/CallbackPayment")
msg := &webapiproto.ASCallbackPayment{} msg := &webapiproto.ASCallbackPayment{}
pack := &webapiproto.SACallbackPayment{} pack := &webapiproto.SACallbackPayment{}
err := proto.Unmarshal(params, msg) err := proto.Unmarshal(params, msg)
logger.Logger.Info("api /api/pay/CallbackPayment msg = ", msg)
if err != nil { if err != nil {
pack.Tag = webapiproto.TagCode_FAILED pack.Tag = webapiproto.TagCode_FAILED
pack.Msg = "数据序列化失败" + err.Error() pack.Msg = "数据序列化失败" + err.Error()
@ -2258,7 +2258,7 @@ func init() {
state = msg.GetState() state = msg.GetState()
player := PlayerMgrSington.GetPlayerBySnId(info.SnId) player := PlayerMgrSington.GetPlayerBySnId(info.SnId)
if player == nil { if player == nil {
if info.State == 1 { if msg.State == 1 {
state = 3 state = 3
} }
} }

View File

@ -1118,7 +1118,7 @@ func (this *WelfareMgr) BlindBoxInfo(p *Player, bid int32) {
if cyc == 1 || blindBox.Cycle == model.WelfareOpen { if cyc == 1 || blindBox.Cycle == model.WelfareOpen {
p.WelfData.BlindBoxId = 0 p.WelfData.BlindBoxId = 0
} }
} // == 1代表当日循环 } // == 1代表当日循环
if p.WelfData.BlindBoxId == 0 { // 未领取过发随机Date if p.WelfData.BlindBoxId == 0 { // 未领取过发随机Date
idx := bid idx := bid