Sfoglia il codice sorgente

更新数据统计

zhengtao 11 mesi fa
parent
commit
ef2b4c33f4

+ 3 - 1
components/cron/go.mod

@@ -1,6 +1,8 @@
 module github.com/mhaya/components/cron
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
 	github.com/mhaya v1.3.13

+ 4 - 2
components/data-config/go.mod

@@ -1,11 +1,13 @@
 module github.com/mhaya/components/data-config
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
-	github.com/mhaya v1.3.13
 	github.com/go-redis/redis/v8 v8.11.5
 	github.com/json-iterator/go v1.1.12
+	github.com/mhaya v1.3.13
 	github.com/radovskyb/watcher v1.0.7
 )
 

+ 5 - 3
components/etcd/go.mod

@@ -1,10 +1,12 @@
 module github.com/mhaya/components/etcd
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
-	github.com/mhaya v1.3.13
 	github.com/json-iterator/go v1.1.12
+	github.com/mhaya v1.3.13
 	go.etcd.io/etcd/api/v3 v3.5.9
 	go.etcd.io/etcd/client/v3 v3.5.9
 )
@@ -29,7 +31,7 @@ require (
 	go.uber.org/zap v1.26.0 // indirect
 	golang.org/x/crypto v0.13.0 // indirect
 	golang.org/x/net v0.10.0 // indirect
-	golang.org/x/sys v0.12.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
 	golang.org/x/text v0.13.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c // indirect

+ 1 - 0
components/etcd/go.sum

@@ -151,6 +151,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=

+ 5 - 3
components/gin/go.mod

@@ -1,10 +1,12 @@
 module github.com/mhaya/components/gin
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
-	github.com/mhaya v1.3.13
 	github.com/gin-gonic/gin v1.9.1
+	github.com/mhaya v1.3.13
 )
 
 require (
@@ -32,7 +34,7 @@ require (
 	golang.org/x/arch v0.3.0 // indirect
 	golang.org/x/crypto v0.13.0 // indirect
 	golang.org/x/net v0.10.0 // indirect
-	golang.org/x/sys v0.12.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
 	golang.org/x/text v0.13.0 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect

+ 1 - 0
components/gin/go.sum

@@ -81,6 +81,7 @@ golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
 golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

+ 5 - 3
components/gops/go.mod

@@ -1,10 +1,12 @@
 module github.com/mhaya/components/gops
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
-	github.com/mhaya v1.3.13
 	github.com/google/gops v0.3.28
+	github.com/mhaya v1.3.13
 )
 
 require (
@@ -15,7 +17,7 @@ require (
 	github.com/pkg/errors v0.9.1 // indirect
 	go.uber.org/multierr v1.10.0 // indirect
 	go.uber.org/zap v1.26.0 // indirect
-	golang.org/x/sys v0.12.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
 	google.golang.org/protobuf v1.31.0 // indirect
 )
 

+ 1 - 0
components/gops/go.sum

@@ -32,6 +32,7 @@ go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo=
 go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so=
 golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
 google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=

+ 3 - 1
components/gorm/go.mod

@@ -1,6 +1,8 @@
 module github.com/mhaya/components/gorm
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
 	github.com/mhaya v1.3.13

+ 3 - 1
components/mongo/go.mod

@@ -1,6 +1,8 @@
 module github.com/mhaya/components/mongo
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
 	github.com/mhaya v1.3.13

+ 0 - 1
extend/utils/geoip.go

@@ -1 +0,0 @@
-package mhayaUtils

BIN
game/config/GeoLite2-Country.mmdb


+ 3 - 0
game/config/data/RuleConfig.json

@@ -0,0 +1,3 @@
+[
+		{"ID":1,"Num":20,"MaxTime":5}	
+]

+ 3 - 3
game/config/data/drawConfig.json

@@ -9,7 +9,7 @@
 		{"ID":8,"Type":1,"Order":7,"Weight":0,"Reward":[{"itemBaseType":4,"itemID":3,"amount":100000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
 		{"ID":9,"Type":1,"Order":5,"Weight":0,"Reward":[{"itemBaseType":4,"itemID":3,"amount":1000000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
 		{"ID":10,"Type":1,"Order":12,"Weight":0,"Reward":[{"itemBaseType":4,"itemID":4,"amount":1000000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
-		{"ID":11,"Type":1,"Order":4,"Weight":3000,"Reward":[{"itemBaseType":4,"itemID":3,"amount":1000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":3},
+		{"ID":11,"Type":1,"Order":8,"Weight":3000,"Reward":[{"itemBaseType":4,"itemID":3,"amount":1000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":3},
 		{"ID":12,"Type":1,"Order":10,"Weight":2500,"Reward":[{"itemBaseType":4,"itemID":3,"amount":100000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":3},
 		{"ID":13,"Type":2,"Order":6,"Weight":3500,"Reward":[{"itemBaseType":1,"itemID":5,"amount":10000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
 		{"ID":14,"Type":2,"Order":3,"Weight":1400,"Reward":[{"itemBaseType":1,"itemID":5,"amount":100000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
@@ -21,6 +21,6 @@
 		{"ID":20,"Type":2,"Order":7,"Weight":0,"Reward":[{"itemBaseType":4,"itemID":3,"amount":100000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
 		{"ID":21,"Type":2,"Order":5,"Weight":0,"Reward":[{"itemBaseType":4,"itemID":3,"amount":1000000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
 		{"ID":22,"Type":2,"Order":12,"Weight":0,"Reward":[{"itemBaseType":4,"itemID":4,"amount":1000000000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
-		{"ID":23,"Type":2,"Order":4,"Weight":1000,"Reward":[{"itemBaseType":4,"itemID":3,"amount":1000000}],"HourTotalCondition":2000,"DailyTotalCondition":10000,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
-		{"ID":24,"Type":2,"Order":10,"Weight":500,"Reward":[{"itemBaseType":4,"itemID":3,"amount":100000}],"HourTotalCondition":3000,"DailyTotalCondition":1000,"WeeklyTotalCondition":0,"PersonTotalCondition":0}	
+		{"ID":23,"Type":2,"Order":8,"Weight":1000,"Reward":[{"itemBaseType":4,"itemID":3,"amount":1000000}],"HourTotalCondition":2000,"DailyTotalCondition":7000,"WeeklyTotalCondition":0,"PersonTotalCondition":0},
+		{"ID":24,"Type":2,"Order":10,"Weight":500,"Reward":[{"itemBaseType":4,"itemID":3,"amount":100000}],"HourTotalCondition":0,"DailyTotalCondition":0,"WeeklyTotalCondition":0,"PersonTotalCondition":0}	
 ]

+ 22 - 16
game/config/profile-gc.json

@@ -35,7 +35,7 @@
         "node_id": "m-center",
         "address": "",
         "__settings__": {
-          "db_id_list" : {
+          "db_id_list": {
             "game_db_id": "game_db_1"
           },
           "ref_logger": "center_log"
@@ -48,7 +48,7 @@
         "node_id": "m-gate-1",
         "address": "0.0.0.0:10010",
         "__settings__": {
-          "db_id_list" : {
+          "db_id_list": {
             "game_db_id": "game_db_1"
           },
           "ref_logger": "gate_log"
@@ -61,10 +61,10 @@
         "node_id": "m-web-1",
         "address": "0.0.0.0:20000",
         "__settings__": {
-          "db_id_list" : {
+          "db_id_list": {
             "game_db_id": "game_db_1"
           },
-          "ref_logger": "master_log"
+          "ref_logger": "web_log"
         },
         "enable": true
       }
@@ -74,10 +74,10 @@
         "node_id": "m-web-admin-1",
         "address": "0.0.0.0:30000",
         "__settings__": {
-          "db_id_list" : {
+          "db_id_list": {
             "game_db_id": "game_db_1"
           },
-          "ref_logger": "master_log"
+          "ref_logger": "web_admin_log"
         },
         "enable": true
       }
@@ -86,7 +86,7 @@
       {
         "node_id": "10001",
         "__settings__": {
-          "db_id_list" : {
+          "db_id_list": {
             "game_db_id": "game_db_1"
           },
           "ref_logger": "game_log"
@@ -124,6 +124,20 @@
       "file_link_path": "logs/game.log",
       "file_path_format": "logs/game_%Y%m%d%H%M.log"
     },
+    "web_log": {
+      "level": "debug",
+      "enable_console": true,
+      "enable_write_file": true,
+      "file_link_path": "logs/web.log",
+      "file_path_format": "logs/web_%Y%m%d%H%M.log"
+    },
+    "web_admin_log": {
+      "level": "debug",
+      "enable_console": true,
+      "enable_write_file": true,
+      "file_link_path": "logs/web_admin_log.log",
+      "file_path_format": "logs/web_admin_log_%Y%m%d%H%M.log"
+    },
     "cross_log": {
       "level": "debug",
       "enable_console": true,
@@ -138,16 +152,8 @@
         "enable": true,
         "db_id": "game_db_1",
         "db_name": "db_mhaya",
-        "uri": "mongodb://192.168.0.68:27017"
+        "uri": "mongodb://127.0.0.1:27017"
       }
-    ],
-    "web_db_admin_group":[
-        {
-            "enable": true,
-            "db_id": "game_db_1",
-            "db_name": "db_user_daily",
-            "uri": "mongodb://192.168.0.68:27017"
-        }
     ]
   },
   "data_config": {

+ 11 - 7
game/game_cluster/internal/constant/constant.go

@@ -16,17 +16,21 @@ const (
 	PlayerStatHKey      = "PlayerStat"
 	PlayerLevelStatHKey = "PlayerLevelStat"
 	ServerLoadHKey      = "ServerLoad"
-	MoneyRatio          = 10000000
+	PlayerIpRecordKey   = "PlayerIpRecord"
+
+	MoneyRatio = 10000000
 )
 
 // 游戏表名
 const (
-	CNameAccount           = "account"
-	CNamePlayer            = "player"
-	CNamePlayerReward      = "playerReward"
-	CNamePlayerDailyRecord = "playerDailyRecord"
-	CNameCashOutRecord     = "cashOutRecord "
-	CNamePlayerLevelStat   = "playerLevelStat"
+	CNameAccount               = "account"
+	CNamePlayer                = "player"
+	CNamePlayerReward          = "playerReward"
+	CNamePlayerDailyRecord     = "playerDailyRecord"
+	CNameCashOutRecord         = "cashOutRecord "
+	CNamePlayerLevelStat       = "playerLevelStat"
+	CNameServerLoadStat        = "serverLoadStat "
+	CNamePlayerCountryByIPStat = "playerCountryStat"
 )
 
 // 榜单数据来源类型

+ 62 - 0
game/game_cluster/internal/data/RuleConfig.go

@@ -0,0 +1,62 @@
+// this file is auto create by program, don't edit manually
+
+package data
+
+import (
+	mhayaError "github.com/mhaya/error"
+	mhayaLogger "github.com/mhaya/logger"
+)
+
+type ruleConfig struct {
+	maps map[int]*RuleConfigRow
+}
+
+type RuleConfigRow struct {
+	ID      int // ID
+	Num     int // 注册人数
+	MaxTime int // 过期时间(按天)
+}
+
+func (p *ruleConfig) Name() string {
+	return "RuleConfig"
+}
+
+func (p *ruleConfig) Init() {
+	p.maps = make(map[int]*RuleConfigRow)
+}
+
+func (p *ruleConfig) OnLoad(maps interface{}, _ bool) (int, error) {
+	list, ok := maps.([]interface{})
+	if !ok {
+		return 0, mhayaError.Error("maps convert to []interface{} error.")
+	}
+
+	loadMaps := make(map[int]*RuleConfigRow)
+	for index, data := range list {
+		loadConfig := &RuleConfigRow{}
+		err := DecodeData(data, loadConfig)
+		if err != nil {
+			mhayaLogger.Warnf("decode error. [row = %d, %v], err = %s", index+1, loadConfig, err)
+			continue
+		}
+
+		loadMaps[loadConfig.ID] = loadConfig
+	}
+
+	p.maps = loadMaps
+
+	return len(list), nil
+}
+
+func (p *ruleConfig) OnAfterLoad(_ bool) {
+}
+
+func (p *ruleConfig) Get(pk int) (*RuleConfigRow, bool) {
+	i, found := p.maps[pk]
+	return i, found
+}
+
+func (p *ruleConfig) Contain(pk int) bool {
+	_, found := p.Get(pk)
+	return found
+}

+ 2 - 0
game/game_cluster/internal/data/component.go

@@ -11,6 +11,7 @@ import (
 var (
 	ChannelConfig      = &channelConfig{}
 	PlatformConfig     = &platformConfig{}
+	RuleConfig         = &ruleConfig{}
 	AchieveTaskConfig  = &achieveTaskConfig{}
 	DailyTaskConfig    = &dailyTaskConfig{}
 	DiscreteRuleConfig = &discreteRuleConfig{}
@@ -29,6 +30,7 @@ func New() *mhayaDataConfig.Component {
 	dataConfig.Register(
 		ChannelConfig,
 		PlatformConfig,
+		RuleConfig,
 		AchieveTaskConfig,
 		DailyTaskConfig,
 		DiscreteRuleConfig,

+ 84 - 2
game/game_cluster/internal/mdb/models/PlayerStat.go

@@ -1,12 +1,94 @@
 package models
 
+import (
+	mhayaTime "github.com/mhaya/extend/time"
+	"github.com/mhaya/game/game_cluster/internal/data"
+)
+
 type PlayerLevelStat struct {
 	Platform    string         `bson:"platform"  json:"platform"` // platform: 用户所在的平台,例如“Android”或“IOS”
 	Channel     string         `bson:"channel" json:"channel"`    // channel: 用户来源渠道
 	ServerLevel map[string]int `json:"serverLevel" bson:"serverLevel"`
+	UpdateTime  int64          `bson:"updateTime" json:"updateTime"`
 }
 
 type PlayerServerLoadStat struct {
-	Name string            `bson:"name" json:"name"`
-	Load map[string]string `bson:"load" json:"load"`
+	Name       string            `bson:"name" json:"name"`
+	TotalUser  int64             `bson:"totalUser" json:"totalUser"`
+	Load       map[string]string `bson:"load" json:"load"`
+	UpdateTime int64             `bson:"updateTime" json:"updateTime"`
+}
+
+type PlayerCountryStat struct {
+	Daily                 int64          `bson:"daily" json:"daily"`                                 //日期
+	Platform              string         `bson:"platform"  json:"platform"`                          // platform: 用户所在的平台,例如“Android”或“IOS”
+	Channel               string         `bson:"channel" json:"channel"`                             // channel: 用户来源渠道
+	PlayerRegisterCountry map[string]int `bson:"playerRegisterCountry" json:"playerRegisterCountry"` // playerRegisterCountry 玩家注册国家
+	UpdateTime            int64          `bson:"updateTime" json:"updateTime"`
+}
+
+type Preserve struct {
+	ID    int64   `json:"id"`
+	Num   int     `json:"num"`
+	Ratio float64 `json:"ratio"`
+}
+
+var preserveConfig = []int64{2, 3, 7, 15, 30}
+
+// GetPlayerPreserve 获取用户留存
+func GetPlayerPreserve(startTime, EndTime int64) {
+	if startTime > mhayaTime.Now().Unix() || EndTime > mhayaTime.Now().Unix() {
+		return
+	}
+	sTime := mhayaTime.CreateFromTimestamp(startTime).DailyTOTimeStamp()
+
+	if EndTime > mhayaTime.Now().Unix() {
+		EndTime = mhayaTime.Now().Unix()
+	}
+	eTime := mhayaTime.CreateFromTimestamp(EndTime).DailyTOTimeStamp()
+	mhayaTime.CreateFromTimestamp(sTime).DiffInDays(mhayaTime.CreateFromTimestamp(eTime))
+}
+
+func PlayerPreserve(startTime, day int64) {
+	var preserve []*Preserve
+	_, curNum := GetNewPlayerMap(startTime, DailyRecordNewRegistered)
+	if curNum < 1 {
+		return
+	}
+
+	preserve = append(preserve, &Preserve{ID: 1, Num: curNum, Ratio: 100})
+
+	for _, v := range preserveConfig {
+		if day < v {
+			preserve = append(preserve, &Preserve{ID: v, Num: 0, Ratio: 0})
+		} else {
+			//	nextTime := mhayaTime.CreateFromTimestamp(startTime).AddDays(int(v) - 1)
+			//next, nextNum := GetNewPlayerMap(startTime, DailyRecordOldLogin)
+			preserve = append(preserve, &Preserve{ID: v, Num: 1, Ratio: 0})
+		}
+
+	}
+}
+
+func GetNewPlayerMap(startTime int64, op int) (map[string]struct{}, int) {
+	var user = make(map[string]struct{})
+
+	platformConfig := data.PlatformConfig.GatMap()
+	channelConfig := data.ChannelConfig.GatMap()
+
+	for _, v := range platformConfig {
+		for _, v2 := range channelConfig {
+			ret, err := GetAppointDailyRecordUserHash(v.Name, v2.Name, startTime, op)
+			if err != nil {
+				continue
+			}
+			for k, _ := range ret {
+				if _, ok := user[k]; !ok {
+					user[k] = struct{}{}
+				}
+			}
+
+		}
+	}
+	return user, len(user)
 }

+ 4 - 2
game/game_cluster/internal/mdb/models/account.go

@@ -41,9 +41,11 @@ func (ac *Account) AccountRegisterOrLogin(req *param.LoginReq) (*Account, int32)
 		clog.Error("Failed to AccountRegisterOrLogin request: %v  err = %v", devAccountTable, err.Error())
 		return nil, code.LoginError
 	}
-
 	//统计新注册
-	SetDailyRecordUserHash(req.Platform, req.Channel, devAccountTable.UserName, DailyRecordNewRegistered)
+	SetDailyRecordNewUserRegisterHash(req.Platform, req.Channel, devAccountTable.UserName, req.IP, DailyRecordNewRegistered)
+
+	//设置IP 规则
+	SetPlayerBlacklistIpRecord(req.IP)
 
 	return devAccountTable, code.OK
 }

+ 27 - 2
game/game_cluster/internal/mdb/models/dailyRecord.go

@@ -5,7 +5,9 @@ import (
 	"fmt"
 	mhayaTime "github.com/mhaya/extend/time"
 	"github.com/mhaya/game/game_cluster/internal/constant"
+	"github.com/mhaya/game/game_cluster/internal/data"
 	"github.com/mhaya/game/game_cluster/internal/mdb"
+	"time"
 )
 
 const (
@@ -71,9 +73,19 @@ func SetDailyRecordUserHash(platform, channel, userName string, op int) {
 	mdb.RDB.HSet(context.Background(), key, userName, int64(1))
 }
 
-func GetAppointDailyRecordUserHash(platform, channel, userName string, daily int64, op int) (int64, error) {
+func SetDailyRecordNewUserRegisterHash(platform, channel, userName, ip string, op int) {
+	key := GetDailyRecordKey(platform, channel, op)
+	mdb.RDB.HSet(context.Background(), key, userName, ip)
+}
+
+func GetAllDailyRecordNewUserRegister(platform, channel string, op int) (map[string]string, error) {
+	key := GetDailyRecordKey(platform, channel, op)
+	return mdb.RDB.HGetAll(context.Background(), key).Result()
+}
+
+func GetAppointDailyRecordUserHash(platform, channel string, daily int64, op int) (map[string]string, error) {
 	key := GetAppointDailyRecordKey(platform, channel, daily, op)
-	return mdb.RDB.HGet(context.Background(), key, userName).Int64()
+	return mdb.RDB.HGetAll(context.Background(), key).Result()
 }
 
 func GetDailyRecordLen(platform, channel string, op int) int64 {
@@ -120,3 +132,16 @@ func SetServerRecord(nodeId string, num int) {
 func GetAllServerRecord() (map[string]string, error) {
 	return mdb.RDB.HGetAll(context.Background(), constant.ServerLoadHKey).Result()
 }
+
+func SetPlayerBlacklistIpRecord(ip string) bool {
+	ret, ok := data.RuleConfig.Get(1)
+	if !ok {
+		return false
+	}
+	num := mdb.RDB.HIncrBy(context.Background(), constant.PlayerIpRecordKey, ip, 1).Val()
+	mdb.RDB.Expire(context.Background(), constant.PlayerIpRecordKey, time.Duration(ret.MaxTime)*24*time.Hour)
+	if int(num) > ret.Num {
+		return true
+	}
+	return false
+}

BIN
game/game_cluster/internal/third/GeoLite2-Country.mmdb


+ 24 - 0
game/game_cluster/internal/third/geoip.go

@@ -0,0 +1,24 @@
+package third
+
+import (
+	"github.com/oschwald/geoip2-golang"
+	"net"
+)
+
+func GetCountryByIP(ip string) (string, error) {
+	// 打开GeoIP数据库
+	db, err := geoip2.Open("./game/config/GeoLite2-Country.mmdb")
+	if err != nil {
+		return "default", err
+	}
+	defer db.Close()
+
+	// 查询IP地址
+	country, err := db.Country(net.ParseIP(ip))
+	if err != nil {
+		return "default", err
+	}
+
+	// 返回国家名称
+	return country.Country.IsoCode, nil
+}

+ 67 - 2
game/game_cluster/nodes/center/module/account/actor_account.go

@@ -10,6 +10,7 @@ import (
 	"github.com/mhaya/game/game_cluster/internal/mdb"
 	"github.com/mhaya/game/game_cluster/internal/mdb/models"
 	"github.com/mhaya/game/game_cluster/internal/param"
+	"github.com/mhaya/game/game_cluster/internal/third"
 	cactor "github.com/mhaya/net/actor"
 	"go.mongodb.org/mongo-driver/bson"
 	"go.mongodb.org/mongo-driver/mongo/options"
@@ -33,19 +34,23 @@ func (p *ActorAccount) AliasID() string {
 // OnInit center为后端节点,不直接与客户端通信,所以注册了一些remote函数,供RPC调用
 func (p *ActorAccount) OnInit() {
 	p.Remote().Register("registerAccount", p.registerOrLoinAccount)
+	p.Timer().Add(5*time.Second, p.load)
 	p.Timer().Add(time.Minute, p.Stat)
+	p.Timer().Add(1*time.Minute, p.PlayerIpStat)
 	p.Timer().Add(time.Minute, p.playerLevelStat)
 	p.Timer().AddFixedHour(23, 59, 59, p.Stat)
 }
 
 func (p *ActorAccount) Stat() {
 	daily := mhayaTime.Now().DailyTOTimeStamp()
+
+	var dailyRecord models.DailyRecord
+	dailyRecord.Daily = daily
 	platformConfig := data.PlatformConfig.GatMap()
 	channelConfig := data.ChannelConfig.GatMap()
 	for _, v := range platformConfig {
 		for _, v2 := range channelConfig {
 			p.dailyStat(v.Name, v2.Name, daily)
-			time.Sleep(time.Second)
 		}
 	}
 }
@@ -60,6 +65,64 @@ func (p *ActorAccount) playerLevelStat() {
 	}
 }
 
+func (p *ActorAccount) PlayerIpStat() {
+	daily := mhayaTime.Now().DailyTOTimeStamp()
+	platformConfig := data.PlatformConfig.GatMap()
+	channelConfig := data.ChannelConfig.GatMap()
+	for _, v := range platformConfig {
+		for _, v2 := range channelConfig {
+			p.ipStat(v.Name, v2.Name, daily)
+		}
+	}
+}
+
+func (p *ActorAccount) load() {
+	m, err := mdb.RDB.HGetAll(context.Background(), constant.ServerLoadHKey).Result()
+	if err != nil {
+		return
+	}
+	var stat models.PlayerServerLoadStat
+	stat.Name = "load"
+	stat.Load = m
+	stat.TotalUser = p.userStat()
+	stat.UpdateTime = mhayaTime.Now().Unix()
+	mdb.MDB.Collection(constant.CNameServerLoadStat).UpdateOne(context.Background(), bson.M{"name": "load"}, bson.M{"$set": &stat}, options.Update().SetUpsert(true))
+}
+
+func (p *ActorAccount) userStat() int64 {
+	var num int64
+
+	platformConfig := data.PlatformConfig.GatMap()
+	channelConfig := data.ChannelConfig.GatMap()
+
+	for _, v := range platformConfig {
+		for _, v2 := range channelConfig {
+			num += models.GetTotalPlayerRecordLen(v.Name, v2.Name)
+		}
+	}
+	return num
+}
+
+func (p *ActorAccount) ipStat(platform, channel string, daily int64) {
+	var ipMap = make(map[string]int)
+	ret, err := models.GetAllDailyRecordNewUserRegister(platform, channel, models.DailyRecordNewRegistered)
+	if err != nil {
+		return
+	}
+
+	for _, v := range ret {
+		c, _ := third.GetCountryByIP(v)
+		ipMap[c] += 1
+	}
+	var stat models.PlayerCountryStat
+	stat.Daily = daily
+	stat.Platform = platform
+	stat.Channel = channel
+	stat.PlayerRegisterCountry = ipMap
+	stat.UpdateTime = mhayaTime.Now().Unix()
+	mdb.MDB.Collection(constant.CNamePlayerCountryByIPStat).UpdateOne(context.Background(), bson.M{"platform": platform, "channel": channel, "daily": daily}, bson.M{"$set": &stat}, options.Update().SetUpsert(true))
+}
+
 func (p *ActorAccount) levelStat(platform, channel string) {
 	level := make(map[string]int)
 	ret, err := models.GetAllTotalPlayerRecord(platform, channel)
@@ -73,10 +136,11 @@ func (p *ActorAccount) levelStat(platform, channel string) {
 	stat.Platform = platform
 	stat.Channel = channel
 	stat.ServerLevel = level
+	stat.UpdateTime = mhayaTime.Now().Unix()
 	mdb.MDB.Collection(constant.CNamePlayerLevelStat).UpdateOne(context.Background(), bson.M{"platform": platform, "channel": channel}, bson.M{"$set": &stat}, options.Update().SetUpsert(true))
 }
 
-func (p *ActorAccount) dailyStat(platform, channel string, daily int64) {
+func (p *ActorAccount) dailyStat(platform, channel string, daily int64) *models.DailyRecord {
 
 	var dailyRecord models.DailyRecord
 	dailyRecord.Daily = daily
@@ -109,6 +173,7 @@ func (p *ActorAccount) dailyStat(platform, channel string, daily int64) {
 	dailyRecord.UpdatedAt = mhayaTime.Now().Unix()
 
 	mdb.MDB.Collection(constant.CNamePlayerDailyRecord).UpdateOne(context.Background(), bson.M{"platform": platform, "channel": channel, "daily": daily}, bson.M{"$set": &dailyRecord}, options.Update().SetUpsert(true))
+	return &dailyRecord
 }
 
 // registerDevAccount 注册开发者帐号

+ 3 - 3
game/game_cluster/nodes/game/module/player/actor_players.go

@@ -83,11 +83,11 @@ func (p *ActorPlayers) onLoginEvent(e cfacade.IEventData) {
 	}
 
 	node, ok := cstring.SplitIndex(evt.TargetPath, cconst.DOT, 0)
-	if ok {
+	if ok && len(node) == 0 {
 		models.SetServerRecord(node, online.Count())
 	}
 
-	clog.Infof("[PlayerLoginEvent] [playerId = %v,openid = %v,TargetPath=%v,, onlineCount = %v]",
+	clog.Infof("[PlayerLoginEvent] [playerId = %v,openid = %v,TargetPath=%v,onlineCount = %v]",
 		evt.PlayerId,
 		evt.OpenID,
 		evt.TargetPath,
@@ -103,7 +103,7 @@ func (p *ActorPlayers) onLogoutEvent(e cfacade.IEventData) {
 	}
 
 	node, ok := cstring.SplitIndex(evt.TargetPath, cconst.DOT, 0)
-	if ok {
+	if ok && len(node) == 0 {
 		models.SetServerRecord(node, online.Count())
 	}
 

+ 1 - 1
game/game_cluster/nodes/web/controller/controller.go

@@ -98,7 +98,7 @@ func (p *Controller) auth(c *mhayaGin.Context) {
 	var pa param.LoginReq
 	//body := c.GetBody()
 	if err := c.BindJSON(&pa); err != nil {
-		mhayaLogger.Warnf("if login err {. params=%s ", pa)
+		mhayaLogger.Warnf("if login err {. params=%s", pa)
 		code.RenderResult(c, code.PIDError)
 		return
 	}

BIN
game/game_cluster/screenshot.png


+ 9 - 5
game/go.mod

@@ -1,6 +1,8 @@
 module github.com/mhaya/game
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
 	github.com/aws/aws-sdk-go v1.55.5
@@ -48,6 +50,8 @@ require (
 	github.com/nats-io/nats.go v1.30.2 // indirect
 	github.com/nats-io/nkeys v0.4.5 // indirect
 	github.com/nats-io/nuid v1.0.1 // indirect
+	github.com/oschwald/geoip2-golang v1.11.0 // indirect
+	github.com/oschwald/maxminddb-golang v1.13.0 // indirect
 	github.com/pelletier/go-toml/v2 v2.0.8 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
 	github.com/radovskyb/watcher v1.0.7 // indirect
@@ -64,11 +68,11 @@ require (
 	go.uber.org/multierr v1.10.0 // indirect
 	go.uber.org/zap v1.26.0 // indirect
 	golang.org/x/arch v0.3.0 // indirect
-	golang.org/x/crypto v0.22.0 // indirect
+	golang.org/x/crypto v0.26.0 // indirect
 	golang.org/x/net v0.21.0 // indirect
-	golang.org/x/sync v0.7.0 // indirect
-	golang.org/x/sys v0.19.0 // indirect
-	golang.org/x/text v0.14.0 // indirect
+	golang.org/x/sync v0.8.0 // indirect
+	golang.org/x/sys v0.23.0 // indirect
+	golang.org/x/text v0.17.0 // indirect
 	golang.org/x/time v0.3.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 )

+ 12 - 0
game/go.sum

@@ -86,6 +86,10 @@ github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OS
 github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
 github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
 github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
+github.com/oschwald/geoip2-golang v1.11.0 h1:hNENhCn1Uyzhf9PTmquXENiWS6AlxAEnBII6r8krA3w=
+github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
+github.com/oschwald/maxminddb-golang v1.13.0 h1:R8xBorY71s84yO06NgTmQvqvTvlS/bnYZrrWX1MElnU=
+github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
 github.com/pelletier/go-toml/v2 v2.0.8 h1:0ctb6s9mE31h0/lhu+J6OPmVeDxJn+kYnJc2jZR9tGQ=
 github.com/pelletier/go-toml/v2 v2.0.8/go.mod h1:vuYfssBdrU2XDZ9bYydBu6t+6a6PYNcZljzZR9VXg+4=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
@@ -145,6 +149,8 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
 golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
 golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
+golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw=
+golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
@@ -155,6 +161,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
 golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
+golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
+golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
 golang.org/x/sys v0.0.0-20190130150945-aca44879d564/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -165,6 +173,8 @@ golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
 golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
+golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM=
+golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -173,6 +183,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
 golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
 golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
+golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
+golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
 golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
 golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=

+ 6 - 4
go.mod

@@ -1,6 +1,8 @@
 module github.com/mhaya
 
-go 1.18
+go 1.21
+
+toolchain go1.22.4
 
 require (
 	github.com/gorilla/websocket v1.5.0
@@ -8,13 +10,13 @@ require (
 	github.com/lestrrat-go/strftime v1.0.6
 	github.com/nats-io/nats.go v1.30.2
 	github.com/nats-io/nuid v1.0.1
+	github.com/oschwald/geoip2-golang v1.11.0
 	github.com/shopspring/decimal v1.4.0
 	go.uber.org/zap v1.26.0
 	google.golang.org/protobuf v1.31.0
 )
 
 require (
-	github.com/aws/aws-sdk-go v1.55.5 // indirect
 	github.com/golang/protobuf v1.5.2 // indirect
 	github.com/google/go-cmp v0.5.9 // indirect
 	github.com/klauspost/compress v1.17.0 // indirect
@@ -22,9 +24,9 @@ require (
 	github.com/modern-go/reflect2 v1.0.2 // indirect
 	github.com/nats-io/nats-server/v2 v2.10.3 // indirect
 	github.com/nats-io/nkeys v0.4.5 // indirect
+	github.com/oschwald/maxminddb-golang v1.13.0 // indirect
 	github.com/pkg/errors v0.9.1 // indirect
-	github.com/stretchr/testify v1.8.3 // indirect
 	go.uber.org/multierr v1.10.0 // indirect
 	golang.org/x/crypto v0.13.0 // indirect
-	golang.org/x/sys v0.12.0 // indirect
+	golang.org/x/sys v0.20.0 // indirect
 )

+ 3 - 0
go.sum

@@ -35,6 +35,8 @@ github.com/nats-io/nkeys v0.4.5 h1:Zdz2BUlFm4fJlierwvGK+yl20IAKUm7eV6AAZXEhkPk=
 github.com/nats-io/nkeys v0.4.5/go.mod h1:XUkxdLPTufzlihbamfzQ7mw/VGx6ObUs+0bN5sNvt64=
 github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw=
 github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c=
+github.com/oschwald/geoip2-golang v1.11.0/go.mod h1:P9zG+54KPEFOliZ29i7SeYZ/GM6tfEL+rgSn03hYuUo=
+github.com/oschwald/maxminddb-golang v1.13.0/go.mod h1:BU0z8BfFVhi1LQaonTwwGQlsHUEu9pWNdMfmq4ztm0o=
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
@@ -54,6 +56,7 @@ golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
 golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
 golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
 golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=