Compare commits

...

4 Commits

Author SHA1 Message Date
sk 1ed0d5b4d7 Merge branch 'develop' of git.pogorockgames.com:mango-games/server/game into develop 2024-12-19 13:47:49 +08:00
sk 7a7baa9568 modify:十三张牌型预选
支持清空预选
空位随机补牌
2024-12-19 13:47:29 +08:00
sk 30d3ba1cc0 add:查询平均游戏时长 2024-12-19 11:48:56 +08:00
sk 93792b3e38 add:添加日志 2024-12-17 14:25:11 +08:00
6 changed files with 153 additions and 40 deletions

View File

@ -826,38 +826,34 @@ func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, param
return false return false
} }
returnFunc := func(code thirteen.OpResultCode) { returnFunc := func(code thirteen.OpResultCode, broadcast bool) {
pack := &thirteen.SCThirteenPlayerOp{ pack := &thirteen.SCThirteenPlayerOp{
OpRetCode: code, OpRetCode: code,
OpCode: int32(opcode), OpCode: int32(opcode),
OpParam: params, OpParam: params,
Pos: int32(playerEx.GetPos()), Pos: int32(playerEx.GetPos()),
} }
if code == thirteen.OpResultCode_OPRC_Error { if broadcast {
proto.SetDefaults(pack) playerEx.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack, 0)
logger.Logger.Trace("SCThirteenPlayerOp:", pack) } else {
playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack) playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack)
return
} }
logger.Logger.Trace("SCThirteenPlayerOp:", pack)
} }
if !playerEx.IsGameing() { if !playerEx.IsGameing() {
returnFunc(thirteen.OpResultCode_OPRC_Error) returnFunc(thirteen.OpResultCode_OPRC_Error, false)
return true return true
} }
switch opcode { switch opcode {
case rule.ThirteenWaterPlayerOpMS: //确定牌 case rule.ThirteenWaterPlayerOpMS: //确定牌
//if playerEx.deterMine { // 确认牌型
// returnFunc(thirteen.OpResultCode_OPRC_Error)
// return false
//}
if len(params) == 13 { if len(params) == 13 {
//校验牌 //校验牌
a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params)) a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params))
if len(a) != 0 { if len(a) != 0 {
logger.Logger.Error("the cards is error.") logger.Logger.Error("the cards is error.")
returnFunc(thirteen.OpResultCode_OPRC_Error) returnFunc(thirteen.OpResultCode_OPRC_Error, false)
return true return true
} }
//牌赋值 //牌赋值
@ -892,38 +888,59 @@ func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, param
playerEx.cardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1} playerEx.cardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1}
playerEx.Trusteeship = 0 playerEx.Trusteeship = 0
playerEx.UnmarkFlag(base.PlayerState_Auto) playerEx.UnmarkFlag(base.PlayerState_Auto)
pack := &thirteen.SCThirteenPlayerOp{
OpRetCode: thirteen.OpResultCode_OPRC_Sucess,
OpCode: int32(opcode),
OpParam: params,
Pos: int32(playerEx.GetPos()),
}
if len(params) == 13 { if len(params) == 13 {
//校验牌 //校验牌
a := rule.DelCards(playerEx.cards[:], common.Int64Toint(params)) remain := len(playerEx.cards)
if len(a) != 0 { remainCards := make([]int, remain)
copy(remainCards, playerEx.cards[:])
for _, v := range params {
if v >= 0 {
a := rule.DelCards(remainCards, []int{int(v)})
if len(a) == remain {
logger.Logger.Error("the cards is error.") logger.Logger.Error("the cards is error.")
returnFunc(thirteen.OpResultCode_OPRC_Error) returnFunc(thirteen.OpResultCode_OPRC_Error, false)
return true return true
} }
remain = len(a)
remainCards = a
}
}
//牌赋值 //牌赋值
copy(playerEx.preCardsO.Head[:], common.Int64Toint(params[:3])) copy(playerEx.preCardsO.Head[:], common.Int64Toint(params[:3]))
copy(playerEx.preCardsO.Mid[:], common.Int64Toint(params[3:8])) copy(playerEx.preCardsO.Mid[:], common.Int64Toint(params[3:8]))
copy(playerEx.preCardsO.End[:], common.Int64Toint(params[8:])) copy(playerEx.preCardsO.End[:], common.Int64Toint(params[8:]))
playerEx.preCardsO.PokerType = 0 playerEx.preCardsO.PokerType = 0
for k, v := range playerEx.preCardsO.Head {
if v < 0 {
playerEx.preCardsO.Head[k] = remainCards[0]
remainCards = remainCards[1:]
} }
playerEx.SendToClient(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack) }
for k, v := range playerEx.preCardsO.Mid {
if v < 0 {
playerEx.preCardsO.Mid[k] = remainCards[0]
remainCards = remainCards[1:]
}
}
for k, v := range playerEx.preCardsO.End {
if v < 0 {
playerEx.preCardsO.End[k] = remainCards[0]
remainCards = remainCards[1:]
}
}
}
if len(params) == 0 {
playerEx.preCardsO = &rule.Group{Head: [3]int{-1, -1, -1}, Mid: [5]int{-1, -1, -1, -1, -1}, End: [5]int{-1, -1, -1, -1, -1}, PokerType: -1}
}
returnFunc(thirteen.OpResultCode_OPRC_Sucess, true)
case rule.ThirteenWaterPlayerOpReset: case rule.ThirteenWaterPlayerOpReset:
// 取消确认 // 取消确认
playerEx.deterMine = false playerEx.deterMine = false
pack := &thirteen.SCThirteenPlayerOp{ returnFunc(thirteen.OpResultCode_OPRC_Sucess, true)
OpRetCode: thirteen.OpResultCode_OPRC_Sucess,
OpCode: int32(opcode),
OpParam: params,
Pos: int32(playerEx.GetPos()),
}
playerEx.Broadcast(int(thirteen.TWMmoPacketID_PACKET_SCThirteenPlayerOp), pack, 0)
default: default:
return false return false

View File

@ -1262,9 +1262,11 @@ func SavePlayerData(pd *PlayerData) bool {
} }
if pd != nil { if pd != nil {
var ret bool var ret bool
t1 := time.Now()
err := rpcCli.CallWithTimeout("PlayerDataSvc.SavePlayerData", pd, &ret, time.Second*30) err := rpcCli.CallWithTimeout("PlayerDataSvc.SavePlayerData", pd, &ret, time.Second*30)
if err != nil { if err != nil {
logger.Logger.Errorf("SavePlayerData %v err:%v", pd.SnId, err) logger.Logger.Errorf("SavePlayerData %v cost:%v fail err:%v PlayerData:%+v",
pd.SnId, time.Now().Sub(t1), err, *pd)
return false return false
} }
return ret return ret

View File

@ -1,17 +1,18 @@
StartTime: "2024-11-26T00:00:00+08:00" StartTime: "2024-12-19T00:00:00+08:00"
EndTime: "2024-11-27T00:00:00+08:00" EndTime: "2024-12-20T00:00:00+08:00"
Switch: # 1: open, 0: close Switch: # 1: open, 0: close
- 0 # 新用户游戏破产率 - 0 # 新用户游戏破产率
- 0 # 新用户平均游戏时长 - 0 # 新用户平均游戏时长
- 1 # 用户平均游戏时长
- 0 # 新用户平均局数 - 0 # 新用户平均局数
- 0 # 平均倍数 - 0 # 平均倍数
- 1 # 活跃破产率 - 0 # 活跃破产率
- 1 # 控输赢胜率 - 0 # 控输赢胜率
- 1 # 机器人胜率 - 0 # 机器人胜率
- 1 # 人均获得金币 - 0 # 人均获得金币
- 1 # 破产后离线 - 0 # 破产后离线
- 1 # 充值玩家金币余额 - 0 # 充值玩家金币余额
Gamefreeids: Gamefreeids:
- 2070001 - 2070001

View File

@ -18,6 +18,7 @@ import (
const ( const (
ExcelTypeNewPlayerBankrupt = iota // 新用户游戏破产率 ExcelTypeNewPlayerBankrupt = iota // 新用户游戏破产率
ExcelTypeGameTimeAvg // 新用户平均游戏时长 ExcelTypeGameTimeAvg // 新用户平均游戏时长
ExcelTypeGameTimeAllAvg // 用户平均游戏时长
ExcelTypeGameCountAvg // 新用户平均局数 ExcelTypeGameCountAvg // 新用户平均局数
ExcelTypeGameRate // 平均倍数 ExcelTypeGameRate // 平均倍数
ExcelTypeActiveRate // 活跃破产率 ExcelTypeActiveRate // 活跃破产率
@ -71,6 +72,7 @@ func main() {
mgr := NewExcelMgr() mgr := NewExcelMgr()
mgr.Register(ExcelTypeNewPlayerBankrupt, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}) mgr.Register(ExcelTypeNewPlayerBankrupt, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"})
mgr.Register(ExcelTypeGameTimeAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"}) mgr.Register(ExcelTypeGameTimeAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"})
mgr.Register(ExcelTypeGameTimeAllAvg, []string{"日期", "场次id", "参与人数", "平均游戏时长"})
mgr.Register(ExcelTypeGameCountAvg, []string{"日期", "场次id", "参与人数", "平均局数"}) mgr.Register(ExcelTypeGameCountAvg, []string{"日期", "场次id", "参与人数", "平均局数"})
mgr.Register(ExcelTypeGameRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"}) mgr.Register(ExcelTypeGameRate, []string{"日期", "场次id", "总局数", "平均倍数", "有炸弹分局数", "炸弹分平均倍数", "2留在手里的局数"})
mgr.Register(ExcelTypeActiveRate, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"}) mgr.Register(ExcelTypeActiveRate, []string{"日期", "场次id", "破产人数", "参与人数", "破产率"})
@ -99,6 +101,10 @@ func main() {
// 新用户平均游戏时长 // 新用户平均游戏时长
mgr.GenNewPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr) mgr.GenNewPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
} }
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
// 用户平均游戏时长
mgr.GenPlayerGameTimeAvgExcel("1", startTimeStr, endTimeStr)
}
if switchArr[ExcelTypeGameCountAvg] == 1 { if switchArr[ExcelTypeGameCountAvg] == 1 {
// 新用户平均局数 // 新用户平均局数
mgr.GenGameCountExcel("1", startTimeStr, endTimeStr) mgr.GenGameCountExcel("1", startTimeStr, endTimeStr)
@ -144,7 +150,10 @@ func (e *ExcelMgr) SaveAll(startTime, endTime string) {
e.Save(ExcelTypeNewPlayerBankrupt, fmt.Sprintf("新用户破产率_%s_%s.xlsx", startTime, endTime)) e.Save(ExcelTypeNewPlayerBankrupt, fmt.Sprintf("新用户破产率_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeGameTimeAvg] == 1 { if switchArr[ExcelTypeGameTimeAvg] == 1 {
e.Save(ExcelTypeGameTimeAvg, fmt.Sprintf("新用户平局游戏时长_%s_%s.xlsx", startTime, endTime)) e.Save(ExcelTypeGameTimeAvg, fmt.Sprintf("新用户平均游戏时长_%s_%s.xlsx", startTime, endTime))
}
if switchArr[ExcelTypeGameTimeAllAvg] == 1 {
e.Save(ExcelTypeGameTimeAllAvg, fmt.Sprintf("用户平均游戏时长_%s_%s.xlsx", startTime, endTime))
} }
if switchArr[ExcelTypeGameCountAvg] == 1 { if switchArr[ExcelTypeGameCountAvg] == 1 {
e.Save(ExcelTypeGameCountAvg, fmt.Sprintf("新用户平均局数_%s_%s.xlsx", startTime, endTime)) e.Save(ExcelTypeGameCountAvg, fmt.Sprintf("新用户平均局数_%s_%s.xlsx", startTime, endTime))
@ -223,6 +232,29 @@ func (e *ExcelMgr) GenNewPlayerGameTimeAvgExcel(plt string, startTime, endTime s
} }
} }
func (e *ExcelMgr) GenPlayerGameTimeAvgExcel(plt string, startTime, endTime string) {
for _, v := range VP.GetIntSlice("Gamefreeids") {
a, b, err := task.PlayerGameTimeAvg(plt, startTime, endTime, v)
if err != nil {
logger.Logger.Errorf("PlayerGameTimeAvg get StartTime:%v EndTime:%v GameFreeId:%v err: %v", startTime, endTime, v, err)
continue
}
ex := e.Get(ExcelTypeGameTimeAllAvg)
ex.NewLine()
ex.SetCell(startTime[:10])
ex.SetCell(GetGameFreeName(v))
ex.SetCell(a)
if a > 0 {
avg := float64(b) / float64(a)
show := fmt.Sprintf("%v", time.Second*time.Duration(avg))
ex.SetCell(show)
} else {
ex.SetCell(0)
}
logger.Logger.Tracef("PlayerGameTimeAvg GameFreeId: %v avg: %v", v, float64(b)/float64(a))
}
}
func (e *ExcelMgr) GenGameCountExcel(plt string, startTime, endTime string) { func (e *ExcelMgr) GenGameCountExcel(plt string, startTime, endTime string) {
for _, v := range VP.GetIntSlice("Gamefreeids") { for _, v := range VP.GetIntSlice("Gamefreeids") {
a, b, err := task.NewPlayerGameCountAvg(plt, startTime, endTime, v) a, b, err := task.NewPlayerGameCountAvg(plt, startTime, endTime, v)

View File

@ -45,6 +45,37 @@ func GetNewPayerIds(plt string, startTime, endTime string) ([]int, error) {
return ret, nil return ret, nil
} }
func GetPayerIds(plt string, startTime, endTime string) ([]int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
c, err := mymongo.GetLogCollection(plt, mongomodel.LogGamePlayerListLog)
if err != nil {
return nil, err
}
var res []struct{ Snid int }
dd, err := c.Aggregate(context.TODO(), bson.A{
bson.M{"$match": bson.M{"time": bson.M{"$gte": s, "$lt": e}}},
bson.M{"$group": bson.M{"_id": "$snid", "snid": bson.M{"$first": "$snid"}}},
})
if err != nil {
if errors.Is(err, mongo.ErrNoDocuments) {
return nil, nil
}
logger.Logger.Errorf("find game player snid get err: %v", err)
return nil, err
}
if err := dd.All(context.TODO(), &res); err != nil {
logger.Logger.Errorf("find game player snid decode err: %v", err)
return nil, err
}
var ret []int
for _, v := range res {
ret = append(ret, v.Snid)
}
logger.Logger.Tracef("find game player snid: %v", ret)
return ret, nil
}
// 场次破产总人数 // 场次破产总人数
func GameFreeIdBankruptPlayerCount(plt string, ids []int, startTime, endTime string, gamefreeid int) (int, error) { func GameFreeIdBankruptPlayerCount(plt string, ids []int, startTime, endTime string, gamefreeid int) (int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime) s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)

View File

@ -102,3 +102,33 @@ func NewPlayerGameTimeAvg(plt string, startTime, endTime string, gamefreeid int)
} }
return b, a, err return b, a, err
} }
func PlayerGameTimeAvg(plt string, startTime, endTime string, gamefreeid int) (int, int, error) {
s, e := common.StrRFC3339TimeToTime(startTime), common.StrRFC3339TimeToTime(endTime)
if s.IsZero() || e.IsZero() {
return 0, 0, fmt.Errorf("time format error")
}
ids, err := GetPayerIds(plt, startTime, endTime)
if err != nil {
return 0, 0, err
}
if len(ids) == 0 {
return 0, 0, nil
}
a, _, err := NewPlayerGameTime(plt, ids, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, err
}
if len(ids) == 0 {
return 0, 0, nil
}
b, err := PlayingGameCount(plt, ids, startTime, endTime, gamefreeid)
if err != nil {
return 0, 0, err
}
if b == 0 {
return 0, 0, nil
}
return b, a, err
}