Compare commits

..

2 Commits

Author SHA1 Message Date
sk 8177397b26 add 统计十三张自动手动摆牌时间 2024-12-21 09:13:01 +08:00
sk 694e8a5992 modify 十三张手动摆牌 2024-12-21 09:05:08 +08:00
9 changed files with 484 additions and 441 deletions

View File

@ -940,6 +940,10 @@ func (this *StateOp) OnPlayerOp(s *base.Scene, p *base.Player, opcode int, param
} }
} }
if len(params) == 1 {
sceneEx.SelectCards(playerEx, int(params[0]))
}
if len(params) == 0 { 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} 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}
} }
@ -974,13 +978,16 @@ func (this *StateOp) OnLeave(s *base.Scene) {
for _, player := range sceneEx.players { for _, player := range sceneEx.players {
if player != nil && player.IsGameing() { if player != nil && player.IsGameing() {
if !player.IsRobot() {
mq.Write(model.ThirteenAutoLog{ mq.Write(model.ThirteenAutoLog{
Id: primitive.NewObjectID().Hex(), Id: primitive.NewObjectID().Hex(),
Platform: player.Platform,
LogId: sceneEx.logid, LogId: sceneEx.logid,
SnId: player.SnId, SnId: player.SnId,
AutoTime: player.AutoMill.Milliseconds(), AutoTime: player.AutoMill.Milliseconds(),
HandTime: player.HandMill.Milliseconds(), HandTime: player.HandMill.Milliseconds(),
}, mq.BackThirteenAutoLog) }, mq.BackThirteenAutoLog)
}
// 使用预选牌 // 使用预选牌
if player.preCardsO != nil && player.preCardsO.PokerType != -1 && (player.cardsO == nil || player.cardsO.PokerType == -1) { if player.preCardsO != nil && player.preCardsO.PokerType != -1 && (player.cardsO == nil || player.cardsO.PokerType == -1) {

View File

@ -1,9 +1,10 @@
package model package model
type ThirteenAutoLog struct { type ThirteenAutoLog struct {
Id string Id string `gorm:"primaryKey"`
LogId string Platform string `gorm:"-"`
SnId int32 LogId string `gorm:"index;column:logid"`
SnId int32 `gorm:"index;column:snid"`
AutoTime int64 // 自动时长,毫秒 AutoTime int64 // 自动时长,毫秒
HandTime int64 // 手动时长,毫秒 HandTime int64 // 手动时长,毫秒
} }

View File

@ -25,3 +25,8 @@ update_invite_num: 30
update_second_item: 10 update_second_item: 10
# 一次最多读取多少道具日志 # 一次最多读取多少道具日志
update_item_num: 100 update_item_num: 100
# rabbitmq配置
rabbitmq:
url: amqp://win88:123456@127.0.0.1:5672/win99
exchange: win99

View File

@ -15,9 +15,10 @@ import (
"mongo.games.com/goserver/core/utils" "mongo.games.com/goserver/core/utils"
"mongo.games.com/goserver/core/viperx" "mongo.games.com/goserver/core/viperx"
"mongo.games.com/game/mq"
mongomodel "mongo.games.com/game/statistics/modelmongo" mongomodel "mongo.games.com/game/statistics/modelmongo"
mysqlmodel "mongo.games.com/game/statistics/modelmysql" mysqlmodel "mongo.games.com/game/statistics/modelmysql"
"mongo.games.com/game/statistics/static" _ "mongo.games.com/game/statistics/mq"
"mongo.games.com/game/statistics/syn" "mongo.games.com/game/statistics/syn"
) )
@ -92,26 +93,32 @@ func main() {
mysqlx.SetAutoMigrateTables(mysqlmodel.Tables) mysqlx.SetAutoMigrateTables(mysqlmodel.Tables)
// mq
mq.StartConsumer(VP.GetString("rabbitmq.url"), VP.GetString("rabbitmq.exchange"), true)
wg := &sync.WaitGroup{} wg := &sync.WaitGroup{}
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
// 同步注册和登录日志
DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second"))*time.Second, SyncSnId) DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second"))*time.Second, SyncSnId)
DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_snid"))*time.Second, func(ctx context.Context) { //DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_snid"))*time.Second, func(ctx context.Context) {
wg := new(sync.WaitGroup) // wg := new(sync.WaitGroup)
for _, v := range VP.GetStringSlice("platforms") { // for _, v := range VP.GetStringSlice("platforms") {
platform := v // platform := v
wg.Add(1) // wg.Add(1)
go func() { // go func() {
defer wg.Done() // defer wg.Done()
Static(platform) // Static(platform)
}() // }()
} // }
wg.Wait() // wg.Wait()
}) //})
// 同步邀请数据
DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_invite"))*time.Second, SyncInvite) DoTick(ctx, wg, time.Duration(VP.GetInt64("update_second_invite"))*time.Second, SyncInvite)
// 同步道具日志数据
DoTickPlatform(ctx, wg, time.Duration(VP.GetInt64("update_second_item"))*time.Second, VP.GetInt("update_item_num"), DoTickPlatform(ctx, wg, time.Duration(VP.GetInt64("update_second_item"))*time.Second, VP.GetInt("update_item_num"),
func(ctx context.Context, platform string, batchSize int) { func(ctx context.Context, platform string, batchSize int) {
err := syn.ItemGainDone(&syn.Data[mongomodel.ItemLog]{ err := syn.ItemGainDone(&syn.Data[mongomodel.ItemLog]{
@ -123,7 +130,7 @@ func main() {
} }
}) })
logger.Logger.Info("start") logger.Logger.Info("start success")
c := make(chan os.Signal, 1) c := make(chan os.Signal, 1)
signal.Notify(c, os.Interrupt, os.Kill) signal.Notify(c, os.Interrupt, os.Kill)
@ -162,36 +169,36 @@ func SyncSnId(ctx context.Context) {
} }
// Static 玩家id触发数据统计 // Static 玩家id触发数据统计
func Static(platform string) { //func Static(platform string) {
// 查询需要更新的玩家id // // 查询需要更新的玩家id
var ids []*mysqlmodel.UserID // var ids []*mysqlmodel.UserID
db, err := mysqlx.GetDatabase(platform) // db, err := mysqlx.GetDatabase(platform)
if err != nil { // if err != nil {
logger.Logger.Errorf("GetDatabase error: %v", err) // logger.Logger.Errorf("GetDatabase error: %v", err)
return // return
} // }
if err := db.Limit(VP.GetInt("update_snid_num")).Find(&ids).Error; err != nil { // if err := db.Limit(VP.GetInt("update_snid_num")).Find(&ids).Error; err != nil {
logger.Logger.Warnf("Get UserID error: %v", err) // logger.Logger.Warnf("Get UserID error: %v", err)
return // return
} // }
//
if len(ids) == 0 { // if len(ids) == 0 {
logger.Logger.Tracef("Static: no need to update") // logger.Logger.Tracef("Static: no need to update")
return // return
} // }
//
// 统计玩家跳出记录 // // 统计玩家跳出记录
if err := static.UserLogin(platform, ids); err != nil { // //if err := static.UserLogin(platform, ids); err != nil {
logger.Logger.Errorf("StaticUserLogin error: %v", err) // // logger.Logger.Errorf("StaticUserLogin error: %v", err)
return // // return
} // //}
//
// 删除更新过的玩家id // // 删除更新过的玩家id
if err := db.Delete(ids).Error; err != nil { // if err := db.Delete(ids).Error; err != nil {
logger.Logger.Errorf("Delete error: %v", err) // logger.Logger.Errorf("Delete error: %v", err)
return // return
} // }
} //}
// SyncInvite 同步邀请数据 // SyncInvite 同步邀请数据
func SyncInvite(ctx context.Context) { func SyncInvite(ctx context.Context) {

View File

@ -1,5 +1,7 @@
package modelmysql package modelmysql
import "mongo.games.com/game/model"
// 需要自动迁移的表添加在这里 Tables // 需要自动迁移的表添加在这里 Tables
var Tables = []interface{}{ var Tables = []interface{}{
@ -14,4 +16,5 @@ var Tables = []interface{}{
&LogMid{}, &LogMid{},
&ItemGain{}, &ItemGain{},
&ItemTotalGain{}, &ItemTotalGain{},
&model.ThirteenAutoLog{},
} }

View File

@ -1 +1,35 @@
package mq package mq
import (
"mongo.games.com/goserver/core/logger"
"mongo.games.com/goserver/core/mysqlx"
"mongo.games.com/game/model"
"mongo.games.com/game/mq"
)
func init() {
mq.RegisterHandler(&mq.RegisterHandlerParam{
Name: mq.BackThirteenAutoLog,
Data: &model.ThirteenAutoLog{},
Handler: func(data interface{}) (err error) {
d, ok := data.(*model.ThirteenAutoLog)
if !ok {
return nil
}
db, err := mysqlx.GetDatabase(d.Platform)
if err != nil {
logger.Logger.Errorf("mysql: SyncThirteenAutoLog failed to get database: %v", err)
return err
}
if err = db.Create(d).Error; err != nil {
logger.Logger.Errorf("mysql: SyncThirteenAutoLog failed to create thirteen_auto_log: %v", err)
return err
}
return nil
},
})
}

View File

@ -1,371 +1,355 @@
package static package static
import ( //func getAccountTel(platform string, id int) (string, error) {
"context" // acc := &mongomodel.Account{}
"errors" // cc, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount)
// if err != nil {
"go.mongodb.org/mongo-driver/bson" // logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err)
"go.mongodb.org/mongo-driver/mongo" // return "", err
"go.mongodb.org/mongo-driver/mongo/options" // }
"mongo.games.com/goserver/core/logger" // dd := cc.FindOne(context.TODO(), bson.M{"snid": id}, options.FindOne().SetProjection(bson.M{"tel": 1}))
// err = dd.Err()
mymongo "mongo.games.com/goserver/core/mongox" // if err != nil {
mymysql "mongo.games.com/goserver/core/mysqlx" // if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Tracef("getAccountTel %v not found in user_account", id)
mongomodel "mongo.games.com/game/statistics/modelmongo" // return "", nil
mysqlmodel "mongo.games.com/game/statistics/modelmysql" // }
) // logger.Logger.Errorf("getAccountTel %v get user_account err: %v", id, err)
// return "", err
func getAccountTel(platform string, id int) (string, error) { // }
acc := &mongomodel.Account{} // if err := dd.Decode(acc); err != nil {
cc, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount) // logger.Logger.Errorf("getAccountTel %v decode user_account err: %v", id, err)
if err != nil { // return "", err
logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err) // }
return "", err // return acc.Tel, nil
} //}
dd := cc.FindOne(context.TODO(), bson.M{"snid": id}, options.FindOne().SetProjection(bson.M{"tel": 1})) //
err = dd.Err() //// 游戏结束离开
if err != nil { //func checkGameOver(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
if errors.Is(err, mongo.ErrNoDocuments) { // // 最早的一条掉线记录并且是游戏结束离开
logger.Logger.Tracef("getAccountTel %v not found in user_account", id) // a := &mongomodel.LoginLog{}
return "", nil // c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin)
} // if err != nil {
logger.Logger.Errorf("getAccountTel %v get user_account err: %v", id, err) // logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err)
return "", err // return false, err
} // }
if err := dd.Decode(acc); err != nil { // d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": 0, "lastgameid": bson.D{{"$gt", 0}}},
logger.Logger.Errorf("getAccountTel %v decode user_account err: %v", id, err) // options.FindOne().SetSort(bson.D{{"time", 1}}))
return "", err // err = d.Err()
} // if err != nil {
return acc.Tel, nil // if errors.Is(err, mongo.ErrNoDocuments) {
} // logger.Logger.Tracef("checkGameOver %v not found in log_login", id)
// return false, nil
// 游戏结束离开 // }
func checkGameOver(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { // logger.Logger.Errorf("checkGameOver %v get log_login err: %v", id, err)
// 最早的一条掉线记录并且是游戏结束离开 // return false, err
a := &mongomodel.LoginLog{} // }
c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin) // if err := d.Decode(a); err != nil {
if err != nil { // logger.Logger.Errorf("checkGameOver %v decode log_login err: %v", id, err)
logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err) // return false, err
return false, err // }
} //
d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": 0, "lastgameid": bson.D{{"$gt", 0}}}, // // account tel
options.FindOne().SetSort(bson.D{{"time", 1}})) // tel, err := getAccountTel(platform, id)
err = d.Err() // if err != nil {
if err != nil { // logger.Logger.Warnf("get account tel %v err: %v", id, err)
if errors.Is(err, mongo.ErrNoDocuments) { // }
logger.Logger.Tracef("checkGameOver %v not found in log_login", id) //
return false, nil // update := &mysqlmodel.UserLogin{
} // //OfflineTs: int(a.Ts),
logger.Logger.Errorf("checkGameOver %v get log_login err: %v", id, err) // OfflineTime: a.Time,
return false, err // OutType: mysqlmodel.OutTypeGameOver,
} // GameID: a.LastGameID,
if err := d.Decode(a); err != nil { // Tel: tel,
logger.Logger.Errorf("checkGameOver %v decode log_login err: %v", id, err) // DeviceName: a.DeviceName,
return false, err // AppVersion: a.AppVersion,
} // BuildVersion: a.BuildVersion,
// AppChannel: a.AppChannel,
// account tel // ChannelId: a.ChannelId,
tel, err := getAccountTel(platform, id) // }
if err != nil { //
logger.Logger.Warnf("get account tel %v err: %v", id, err) // if err := db.Model(login).Select(
} // "OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel",
// ).Updates(update).Error; err != nil {
update := &mysqlmodel.UserLogin{ // logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
//OfflineTs: int(a.Ts), // return false, err
OfflineTime: a.Time, // }
OutType: mysqlmodel.OutTypeGameOver, //
GameID: a.LastGameID, // return true, nil
Tel: tel, //}
DeviceName: a.DeviceName, //
AppVersion: a.AppVersion, //// 游戏中离开
BuildVersion: a.BuildVersion, //func checkGaming(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
AppChannel: a.AppChannel, // // 最早的一条掉线记录并且是游戏中掉线
ChannelId: a.ChannelId, // a := &mongomodel.LoginLog{}
} // c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin)
// if err != nil {
if err := db.Model(login).Select( // logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err)
"OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel", // return false, err
).Updates(update).Error; err != nil { // }
logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err) // d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": bson.D{{"$gt", 0}}},
return false, err // options.FindOne().SetSort(bson.D{{"time", 1}}))
} // err = d.Err()
// if err != nil {
return true, nil // if errors.Is(err, mongo.ErrNoDocuments) {
} // logger.Logger.Tracef("checkGaming %v not found in log_login", id)
// return false, nil
// 游戏中离开 // }
func checkGaming(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { // logger.Logger.Errorf("checkGaming %v get log_login err: %v", id, err)
// 最早的一条掉线记录并且是游戏中掉线 // return false, err
a := &mongomodel.LoginLog{} // }
c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin) // if err := d.Decode(a); err != nil {
if err != nil { // logger.Logger.Errorf("checkGaming %v decode log_login err: %v", id, err)
logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err) // return false, err
return false, err // }
} //
d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop, "gameid": bson.D{{"$gt", 0}}}, // // account tel
options.FindOne().SetSort(bson.D{{"time", 1}})) // tel, err := getAccountTel(platform, id)
err = d.Err() // if err != nil {
if err != nil { // logger.Logger.Warnf("get account tel %v err: %v", id, err)
if errors.Is(err, mongo.ErrNoDocuments) { // }
logger.Logger.Tracef("checkGaming %v not found in log_login", id) //
return false, nil // update := &mysqlmodel.UserLogin{
} // //OfflineTs: int(a.Ts),
logger.Logger.Errorf("checkGaming %v get log_login err: %v", id, err) // OfflineTime: a.Time,
return false, err // OutType: mysqlmodel.OutTypeGaming,
} // GameID: a.GameId,
if err := d.Decode(a); err != nil { // Tel: tel,
logger.Logger.Errorf("checkGaming %v decode log_login err: %v", id, err) // DeviceName: a.DeviceName,
return false, err // AppVersion: a.AppVersion,
} // BuildVersion: a.BuildVersion,
// AppChannel: a.AppChannel,
// account tel // ChannelId: a.ChannelId,
tel, err := getAccountTel(platform, id) // }
if err != nil { //
logger.Logger.Warnf("get account tel %v err: %v", id, err) // if err := db.Model(login).Select(
} // "OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel",
// ).Updates(update).Error; err != nil {
update := &mysqlmodel.UserLogin{ // logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
//OfflineTs: int(a.Ts), // return false, err
OfflineTime: a.Time, // }
OutType: mysqlmodel.OutTypeGaming, //
GameID: a.GameId, // return true, nil
Tel: tel, //}
DeviceName: a.DeviceName, //
AppVersion: a.AppVersion, //// 登录后离开
BuildVersion: a.BuildVersion, //func checkLogin(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
AppChannel: a.AppChannel, // // 最早的一条掉线记录
ChannelId: a.ChannelId, // a := &mongomodel.LoginLog{}
} // c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin)
// if err != nil {
if err := db.Model(login).Select( // logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err)
"OfflineTime", "OutType", "GameID", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel", // return false, err
).Updates(update).Error; err != nil { // }
logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err) // d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop}, options.FindOne().SetSort(bson.D{{"time", 1}}))
return false, err // err = d.Err()
} // if err != nil {
// if errors.Is(err, mongo.ErrNoDocuments) {
return true, nil // logger.Logger.Tracef("checkLogin %v not found in log_login", id)
} // return false, nil
// }
// 登录后离开 // logger.Logger.Errorf("checkLogin %v get log_login err: %v", id, err)
func checkLogin(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { // return false, err
// 最早的一条掉线记录 // }
a := &mongomodel.LoginLog{} // if err := d.Decode(a); err != nil {
c, err := mymongo.GetLogCollection(platform, mongomodel.LogLogin) // logger.Logger.Errorf("checkLogin %v decode log_login err: %v", id, err)
if err != nil { // return false, err
logger.Logger.Errorf("get collection %s error %v", mongomodel.LogLogin, err) // }
return false, err //
} // // account tel
d := c.FindOne(context.TODO(), bson.M{"snid": id, "logtype": mongomodel.LogTypeDrop}, options.FindOne().SetSort(bson.D{{"time", 1}})) // tel, err := getAccountTel(platform, id)
err = d.Err() // if err != nil {
if err != nil { // logger.Logger.Warnf("get account tel %v err: %v", id, err)
if errors.Is(err, mongo.ErrNoDocuments) { // }
logger.Logger.Tracef("checkLogin %v not found in log_login", id) //
return false, nil // update := &mysqlmodel.UserLogin{
} // //OfflineTs: int(a.Ts),
logger.Logger.Errorf("checkLogin %v get log_login err: %v", id, err) // OfflineTime: a.Time,
return false, err // OutType: mysqlmodel.OutTypeLogin,
} // Tel: tel,
if err := d.Decode(a); err != nil { // DeviceName: a.DeviceName,
logger.Logger.Errorf("checkLogin %v decode log_login err: %v", id, err) // AppVersion: a.AppVersion,
return false, err // BuildVersion: a.BuildVersion,
} // AppChannel: a.AppChannel,
// ChannelId: a.ChannelId,
// account tel // }
tel, err := getAccountTel(platform, id) //
if err != nil { // if err := db.Model(login).Select(
logger.Logger.Warnf("get account tel %v err: %v", id, err) // "OfflineTime", "OutType", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel",
} // ).Updates(update).Error; err != nil {
// logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err)
update := &mysqlmodel.UserLogin{ // return false, err
//OfflineTs: int(a.Ts), // }
OfflineTime: a.Time, //
OutType: mysqlmodel.OutTypeLogin, // return true, nil
Tel: tel, //}
DeviceName: a.DeviceName, //
AppVersion: a.AppVersion, //// 注册后离开
BuildVersion: a.BuildVersion, //func checkRegister(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) {
AppChannel: a.AppChannel, // a := &mongomodel.Account{}
ChannelId: a.ChannelId, // c, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount)
} // if err != nil {
// logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err)
if err := db.Model(login).Select( // return false, err
"OfflineTime", "OutType", "DeviceName", "AppVersion", "BuildVersion", "AppChannel", "Tel", // }
).Updates(update).Error; err != nil { // d := c.FindOne(context.TODO(), bson.M{"snid": id})
logger.Logger.Errorf("checkLogin %v update user_login err: %v", id, err) // err = d.Err()
return false, err // if err != nil {
} // if errors.Is(err, mongo.ErrNoDocuments) {
// logger.Logger.Warnf("checkRegister %v not found in user_account", id)
return true, nil // return false, nil
} // }
// logger.Logger.Errorf("checkRegister %v get user_account err: %v", id, err)
// 注册后离开 // return false, err
func checkRegister(db *mymysql.Database, login *mysqlmodel.UserLogin, platform string, id int) (bool, error) { // }
a := &mongomodel.Account{} // if err := d.Decode(a); err != nil {
c, err := mymongo.GetUserCollection(platform, mongomodel.UserAccount) // logger.Logger.Errorf("checkRegister %v decode user_account err: %v", id, err)
if err != nil { // return false, err
logger.Logger.Errorf("get collection %s error %v", mongomodel.UserAccount, err) // }
return false, err //
} // // account tel
d := c.FindOne(context.TODO(), bson.M{"snid": id}) // tel, err := getAccountTel(platform, id)
err = d.Err() // if err != nil {
if err != nil { // logger.Logger.Warnf("get account tel %v err: %v", id, err)
if errors.Is(err, mongo.ErrNoDocuments) { // }
logger.Logger.Warnf("checkRegister %v not found in user_account", id) //
return false, nil // login.Snid = id
} // //login.OnlineTs = int(a.RegisterTs)
logger.Logger.Errorf("checkRegister %v get user_account err: %v", id, err) // login.OnlineTime = a.RegisteTime
return false, err // //login.OfflineTs = int(a.RegisterTs)
} // login.OfflineTime = a.RegisteTime
if err := d.Decode(a); err != nil { // login.OutType = mysqlmodel.OutTypRegister
logger.Logger.Errorf("checkRegister %v decode user_account err: %v", id, err) // login.Tel = tel
return false, err // login.DeviceName = a.DeviceName
} // login.AppVersion = a.AppVersion
// login.BuildVersion = a.BuildVersion
// account tel // login.AppChannel = a.AppChannel
tel, err := getAccountTel(platform, id) // login.ChannelId = a.ChannelId
if err != nil { //
logger.Logger.Warnf("get account tel %v err: %v", id, err) // if err := db.Create(login).Error; err != nil {
} // logger.Logger.Errorf("checkRegister create err: %v", err)
// return false, err
login.Snid = id // }
//login.OnlineTs = int(a.RegisterTs) // return true, nil
login.OnlineTime = a.RegisteTime //}
//login.OfflineTs = int(a.RegisterTs)
login.OfflineTime = a.RegisteTime
login.OutType = mysqlmodel.OutTypRegister
login.Tel = tel
login.DeviceName = a.DeviceName
login.AppVersion = a.AppVersion
login.BuildVersion = a.BuildVersion
login.AppChannel = a.AppChannel
login.ChannelId = a.ChannelId
if err := db.Create(login).Error; err != nil {
logger.Logger.Errorf("checkRegister create err: %v", err)
return false, err
}
return true, nil
}
// UserLogin 玩家跳出统计 // UserLogin 玩家跳出统计
func UserLogin(platform string, ids []*mysqlmodel.UserID) error { //func UserLogin(platform string, ids []*mysqlmodel.UserID) error {
f := func(id int) error { // f := func(id int) error {
// 玩家是否已经统计结束,已经是游戏结束状态 // // 玩家是否已经统计结束,已经是游戏结束状态
login := &mysqlmodel.UserLogin{} // login := &mysqlmodel.UserLogin{}
db, err := mymysql.GetDatabase(platform) // db, err := mymysql.GetDatabase(platform)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin get db err: %v", err) // logger.Logger.Errorf("UserLogin get db err: %v", err)
return err // return err
} // }
if err = db.Where("snid = ?", id).Find(login).Error; err != nil { // if err = db.Where("snid = ?", id).Find(login).Error; err != nil {
logger.Logger.Errorf("UserLogin find %v err: %v", id, err) // logger.Logger.Errorf("UserLogin find %v err: %v", id, err)
return err // return err
} // }
//
switch login.OutType { // switch login.OutType {
case mysqlmodel.OutTypeGameOver: // case mysqlmodel.OutTypeGameOver:
return nil // return nil
//
case mysqlmodel.OutTypeGaming: // case mysqlmodel.OutTypeGaming:
_, err := checkGameOver(db, login, platform, id) // _, err := checkGameOver(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
return err // return err
} // }
return nil // return nil
//
case mysqlmodel.OutTypeLogin: // case mysqlmodel.OutTypeLogin:
ret, err := checkGameOver(db, login, platform, id) // ret, err := checkGameOver(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
ret, err = checkGaming(db, login, platform, id) // ret, err = checkGaming(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
//
case mysqlmodel.OutTypRegister: // case mysqlmodel.OutTypRegister:
ret, err := checkGameOver(db, login, platform, id) // ret, err := checkGameOver(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
ret, err = checkGaming(db, login, platform, id) // ret, err = checkGaming(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
ret, err = checkLogin(db, login, platform, id) // ret, err = checkLogin(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
//
default: // default:
ret, err := checkRegister(db, login, platform, id) // ret, err := checkRegister(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkRegister %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkRegister %v err: %v", id, err)
return err // return err
} // }
if !ret { // if !ret {
logger.Logger.Warnf("UserLogin not found user_account checkRegister %v err: %v", id, err) // logger.Logger.Warnf("UserLogin not found user_account checkRegister %v err: %v", id, err)
return nil // return nil
} // }
//
ret, err = checkGameOver(db, login, platform, id) // ret, err = checkGameOver(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGameOver %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
ret, err = checkGaming(db, login, platform, id) // ret, err = checkGaming(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkGaming %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
ret, err = checkLogin(db, login, platform, id) // ret, err = checkLogin(db, login, platform, id)
if err != nil { // if err != nil {
logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err) // logger.Logger.Errorf("UserLogin checkLogin %v err: %v", id, err)
return err // return err
} // }
if ret { // if ret {
return nil // return nil
} // }
return nil // return nil
} // }
//
return nil // return nil
} // }
//
for _, v := range ids { // for _, v := range ids {
if err := f(v.Snid); err != nil { // if err := f(v.Snid); err != nil {
return err // return err
} // }
} // }
//
return nil // return nil
} //}

View File

@ -9,12 +9,12 @@ import (
"go.mongodb.org/mongo-driver/mongo" "go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options" "go.mongodb.org/mongo-driver/mongo/options"
"gorm.io/gorm" "gorm.io/gorm"
mongomodel "mongo.games.com/game/statistics/modelmongo"
mysqlmodel "mongo.games.com/game/statistics/modelmysql"
"mongo.games.com/goserver/core/logger" "mongo.games.com/goserver/core/logger"
mymongo "mongo.games.com/goserver/core/mongox" mymongo "mongo.games.com/goserver/core/mongox"
mymysql "mongo.games.com/goserver/core/mysqlx" mymysql "mongo.games.com/goserver/core/mysqlx"
mongomodel "mongo.games.com/game/statistics/modelmongo"
mysqlmodel "mongo.games.com/game/statistics/modelmysql"
) )
/* /*
@ -155,19 +155,19 @@ func LogLogin(platform string, batchSize int) ([]*mysqlmodel.LogLogin, error) {
return err return err
} }
for _, v := range ls { //for _, v := range ls {
if err = tx.First(&mysqlmodel.UserID{}, "snid = ?", v.Snid).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { // if err = tx.First(&mysqlmodel.UserID{}, "snid = ?", v.Snid).Error; err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
logger.Logger.Errorf("mysql: SyncLogLogin failed to find user_id: %v", err) // logger.Logger.Errorf("mysql: SyncLogLogin failed to find user_id: %v", err)
return err // return err
} // }
//
if errors.Is(err, gorm.ErrRecordNotFound) { // if errors.Is(err, gorm.ErrRecordNotFound) {
if err = tx.Create(&mysqlmodel.UserID{Snid: v.Snid}).Error; err != nil { // if err = tx.Create(&mysqlmodel.UserID{Snid: v.Snid}).Error; err != nil {
logger.Logger.Errorf("mysql: SyncLogLogin failed to create user_id: %v", err) // logger.Logger.Errorf("mysql: SyncLogLogin failed to create user_id: %v", err)
return err // return err
} // }
} // }
} //}
return nil return nil
}) })

View File

@ -1 +1,3 @@
游戏服mongodb同步到mysql 游戏服mongodb同步到mysql
datasync.go 同步模型