123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554 |
- package model
- import (
- "active/constant"
- "active/tools"
- "database/sql"
- "encoding/json"
- "fmt"
- "strconv"
- "strings"
- "sync"
- "time"
- "git.jiaxianghudong.com/go/gsdkclient"
- "git.jiaxianghudong.com/go/logs"
- "git.jiaxianghudong.com/go/xlog"
- "git.jiaxianghudong.com/webs/pkg/dbx"
- "git.jiaxianghudong.com/webs/pkg/rds"
- )
- //GoodsCache 调用到的计费点缓存
- var GoodsCache sync.Map
- var PayBlackCache sync.Map
- //PayBlackCacheNew 锁机制
- var PayBlackCacheNew *PbCacheMap
- var VerIPBlackCacheNew *VerIpCacheMap
- const MaxIpNum = 50
- type PbCacheMap struct {
- Data map[int]int
- Lock *sync.RWMutex
- }
- func NewPayBlackCacheNew() *PbCacheMap {
- return &PbCacheMap{
- Data: make(map[int]int),
- Lock: &sync.RWMutex{},
- }
- }
- func (d *PbCacheMap) Get(k int) (int, bool) {
- d.Lock.RLock()
- defer d.Lock.RUnlock()
- v, ok := d.Data[k]
- return v, ok
- }
- func (d *PbCacheMap) Set(k int, v int) {
- d.Lock.Lock()
- defer d.Lock.Unlock()
- d.Data[k] = v
- }
- type VerIpCacheMap struct {
- Data map[string][]string
- Lock *sync.RWMutex
- }
- func NewVerIpCacheNew() *VerIpCacheMap {
- return &VerIpCacheMap{
- Data: make(map[string][]string),
- Lock: &sync.RWMutex{},
- }
- }
- func (d *VerIpCacheMap) Get(k string) ([]string, bool) {
- d.Lock.RLock()
- defer d.Lock.RUnlock()
- v, ok := d.Data[k]
- return v, ok
- }
- func (d *VerIpCacheMap) Set(k string, v []string) {
- d.Lock.Lock()
- defer d.Lock.Unlock()
- d.Data[k] = v
- }
- //BlackIPDuan 审核人员IP段
- var BlackIPDuan = []string{"182.254.115", "59.37.125"}
- //BlackIPs 审核人员IP
- var BlackIPs = []string{"111.222.19.134"}
- var TestUserIDS = []int{101832265, 125660976, 101758654, 101616296, 56409319}
- func GetBlackByVerIP(ver, ip string, appid int) bool {
- vkey := fmt.Sprintf("%d-%s", appid, ver)
- //判断大于 50个不同IP就返回 黑名单关闭
- if barr, ok := VerIPBlackCacheNew.Get(vkey); !ok {
- VerIPBlackCacheNew.Set(vkey, []string{ip})
- return true
- } else {
- if len(barr) >= MaxIpNum {
- return false
- } else {
- //未达到50次
- if !tools.InStringArray(ip, barr) {
- barr = append(barr, ip)
- VerIPBlackCacheNew.Set(vkey, barr)
- }
- return true
- }
- }
- }
- //GetGoods 获取计费点缓存
- func GetGoods(vcfrom string) map[string]interface{} {
- //先读取缓存
- var goodsret string
- goodsKey := fmt.Sprintf("%s%s", vcfrom, constant.GOODSKEY)
- if data, ok := GoodsCache.Load(goodsKey); ok {
- logs.Debugf("cache key: %s", goodsKey)
- return data.(map[string]interface{})
- }
- allgoods := make(map[string]interface{})
- goodsret = rds.Redis8.Get(goodsKey).Val()
- err := json.Unmarshal([]byte(goodsret), &allgoods)
- if err != nil {
- logs.Error(fmt.Sprintf("goodsret: %s err: %v", goodsret, err))
- return allgoods
- }
- var goodsconfigs = make(map[string]interface{})
- if data, ok := allgoods[constant.GOODSVERSION]; ok {
- if val, ok := data.(map[string]interface{}); ok {
- goodsconfigs = val
- }
- }
- fmt.Printf("【goods configs】: key:%s %+v", goodsKey, goodsconfigs)
- GoodsCache.Store(goodsKey, goodsconfigs)
- return goodsconfigs
- }
- //InBlacklist 获取黑名单
- func InBlacklist(userid string) bool {
- if data, ok := PayBlackCache.Load(constant.PAYBLACKLIST); ok {
- logs.Debugf("PayBlackCache cache key: %s", constant.PAYBLACKLIST)
- return tools.InStringArray(userid, data.([]string))
- }
- blist := rds.Redis8.SMembers(constant.PAYBLACKLIST).Val()
- fmt.Printf(" \n【pay black configs】: %+v", blist)
- PayBlackCache.Store(constant.PAYBLACKLIST, blist)
- return tools.InStringArray(userid, blist)
- }
- //GetBlackList 获取黑名单
- func GetBlackList(userid string, ip, UA string) bool {
- var ipDuan string
- ipArr := strings.Split(ip, ".")
- if len(ipArr) >= 3 {
- ipDuan = strings.Join(ipArr[0:3], ".")
- }
- // 1. 根据ip段来判断如果是黑名单IP段, 用户直接拉入黑名单
- if GetBlackIPDuanCache(ipDuan) {
- var count int
- uID, _ := strconv.Atoi(userid)
- userInfo := gsdkclient.Client().UserInfoNoLoginData(uID)
- temp := gsdkclient.Client().GetEffortEx(uint(uID), []int{2}, false) //获取局数
- if temp != nil {
- count = int(temp[2]) //局数
- }
- xlog.Infof("【 黑名单网段玩家 】 %v ip:%s agent:%v", userid, ip, UA)
- if userIp := rds.Redis8.HGet(constant.PAYBLACKUSERHASH, userid).Val(); userIp != "" {
- rds.Redis8.HSet(constant.PAYBLACKUSERHASHTMP, userid, fmt.Sprintf("%s|局数:%d|注册时间:%s", ip, count, userInfo.RegDate))
- }
- return true
- }
- if userIp := rds.Redis8.HGet(constant.PAYBLACKUSERHASH, userid).Val(); userIp != "" {
- xlog.Infof("【 审核玩家 】 %v ip:%s agent:%v", userid, ip, UA)
- rds.Redis8.HIncrBy(constant.PAYBLACKIPHASH, ip, 1) //黑名单玩家计入使用该ip次数
- return true
- }
- // hour := time.Now().Hour() //高峰期不执行查询操作, 小于晚上8点,或者大于等于10点 进行特定IP认证
- // if hour < 20 || hour >= 22 {
- // //2. 不是IP段再确认玩家是否黑名单玩家
- // if userIp := rds.Redis8.HGet(constant.PAYBLACKUSERHASH, userid).Val(); userIp != "" {
- // rds.Redis8.HIncrBy(constant.PAYBLACKIPHASH, ip, 1) //黑名单玩家计入使用该ip次数
- // return true
- // }
- // // //3. 不是黑名单玩家再判断是否 具体黑名单IP并且达到拉黑值
- // // if blackip := rds.Redis8.HGet(constant.PAYBLACKIPHASH, ip).Val(); blackip != "" { //观察黑名单IP列表名单
- // // if c, _ := strconv.Atoi(blackip); c >= 5 { //超过黑名单IP次数,加入黑名单用户
- // // rds.Redis8.HSet(constant.PAYBLACKUSERHASH, userid, ip)
- // // return true
- // // }
- // // }
- // }
- return false
- }
- //GetBlackIPDuanCache 获取黑名单ip段缓存
- func GetBlackIPDuanCache(ipDuan string) bool {
- // if data, ok := PayBlackIPDuanCache.Load(constant.PAYBLACKIPRANGE); ok {
- // logs.Debugf("PayBlackIPDuanCache cache key: %s", constant.PAYBLACKIPRANGE)
- // return tools.InStringArray(ipDuan, data.([]string))
- // }
- //blist := rds.Redis8.SMembers(constant.PAYBLACKIPRANGE).Val()
- //fmt.Printf(" \n【PayBlackIPDuanCache configs】: %+v", blist)
- //PayBlackCache.Store(constant.PAYBLACKIPRANGE, blist)
- //return tools.InStringArray(ipDuan, blist)
- return tools.InStringArray(ipDuan, BlackIPDuan)
- }
- //GetBlackListVer2 黑名单新算法尝试 黑名单 A,B,C,D, E
- func GetBlackListVer2(userid, ip, UA string, totalmoney int, nickname string) (int, bool) {
- var ipDuan string
- ipArr := strings.Split(ip, ".")
- if len(ipArr) >= 3 {
- ipDuan = strings.Join(ipArr[0:3], ".")
- }
- uID, _ := strconv.Atoi(userid)
- if tools.InStringArray(ip, BlackIPs) {
- return 0, true
- }
- // 1. 根据ip段来判断如果是黑名单IP段, 用户直接拉入黑名单分区
- if GetBlackIPDuanCache(ipDuan) {
- xlog.Infof("【 黑名单网段玩家 】 %v ip:%s agent:%v", userid, ip, UA)
- //获取用户信息
- userInfo := gsdkclient.Client().UserInfoNoLoginData(uID)
- var count int
- temp := gsdkclient.Client().GetEffortEx(uint(uID), []int{2}, false) //获取局数
- if temp != nil {
- count = int(temp[2]) //局数
- }
- //CheckBlackAB 判断黑名单AB
- if typ, ok := CheckBlackABE(ip, userInfo.NickName, userInfo.RegDate, uID, 2, totalmoney, count); ok {
- return typ, ok
- }
- if totalmoney == 0 { //判断黑名单C 无特征,无支付 不影响审核人员判断依据,但是不开放支付功能
- b := &BlackUsers{
- Type: 3,
- Ip: ip,
- Count: count,
- Createtime: userInfo.RegDate,
- Nickname: userInfo.NickName,
- Totalmoney: totalmoney,
- Userid: uID,
- }
- b.Add()
- return b.Type, true
- } else { //黑名单D 无特征,有支付过玩家,不开放支付,进入审核名单没问题可以对外开放
- b := &BlackUsers{
- Type: 4,
- Ip: ip,
- Count: count,
- Createtime: userInfo.RegDate,
- Nickname: userInfo.NickName,
- Totalmoney: totalmoney,
- Userid: uID,
- }
- b.Add()
- return b.Type, true
- }
- } else {
- //非黑名单认证用户nick是不是审核人员
- if typ, ok := CheckBlackA(ip, nickname, uID); ok {
- return typ, ok
- }
- }
- //判断是不是黑名单成员 如果是等级AB 记录他使用的IP, 等级CD只限制不统计IP
- //规则 A|182.254.115.151|局数:0|注册时间:2021-07-15 17:22:33.000000|昵称:WL_368879456|历史支付:10元
- if typ := GetBlackLevel(uID); typ > 0 {
- if tools.InIntArray(typ, []int{1, 2}) {
- xlog.Infof("【 黑名单明确审核玩家切换IP 】 %v ip:%s agent:%v", userid, ip, UA)
- // rds.Redis8.HIncrBy(constant.PAYBLACKLEVELIP, ip, 1) //黑名单玩家计入使用该ip次数
- return 0, true
- }
- xlog.Infof("【 黑名单不确定审核人员玩家切换IP 】 %v ip:%s agent:%v", userid, ip, UA)
- return 0, true
- }
- hour := time.Now().Hour() //高峰期不执行查询操作, 小于晚上8点,或者大于等于10点 进行特定IP认证
- if hour < 20 || hour >= 23 {
- //判断用户IP是不是 黑名单用户使用过的IP
- countX := rds.Redis8.HGet(constant.PAYBLACKLEVELIP, ip).Val()
- if c, _ := strconv.Atoi(countX); c >= 5 {
- userInfo := gsdkclient.Client().UserInfoNoLoginData(uID)
- var count int
- temp := gsdkclient.Client().GetEffortEx(uint(uID), []int{2}, false) //获取局数
- if temp != nil {
- count = int(temp[2]) //局数
- }
- //CheckBlackAE 判断黑名单AE
- if typ, ok := CheckBlackABE(ip, userInfo.NickName, userInfo.RegDate, uID, 5, totalmoney, count); ok {
- xlog.Infof("【 通过黑名单IP进来的审核人员 】 %v ip:%s agent:%v", userid, ip, UA)
- return typ, ok
- }
- var day int
- regTime := strings.Replace(userInfo.RegDate, "T", " ", -1)
- if len(regTime) >= 19 {
- parse, _ := time.Parse("2006-01-02 15:04:05", regTime)
- day = CheckSubDay(parse)
- }
- //2个月未支付玩家,拉入黑名单C
- if day >= 60 && totalmoney == 0 {
- b := &BlackUsers{
- Type: 3,
- Ip: ip,
- Count: count,
- Createtime: userInfo.RegDate,
- Nickname: userInfo.NickName,
- Totalmoney: totalmoney,
- Userid: uID,
- }
- b.Add()
- return b.Type, true
- } else {
- //用了黑名单用户ip, 但是充值过,或者只是近期没充值加入观察名单
- r := &RedUsers{
- Type: 1,
- Ip: ip,
- Count: count,
- Createtime: userInfo.RegDate,
- Nickname: userInfo.NickName,
- Totalmoney: totalmoney,
- Userid: uID,
- }
- r.Add()
- return 0, false
- }
- }
- }
- return 0, false
- }
- func CheckBlackA(ip, nickname string, userid int) (int, bool) {
- if len(nickname) > 7 {
- //判断是否符合黑名单A特征 含有关键字
- if strings.HasPrefix(nickname, "tencent_game") ||
- strings.HasPrefix(nickname, "rdgztest_") ||
- strings.HasPrefix(nickname, "minigamecheck") {
- b := &BlackUsers{
- Type: 1,
- Ip: ip,
- Count: 0,
- Createtime: "2022-01-01 00:00:00",
- Nickname: nickname,
- Totalmoney: 0,
- Userid: userid,
- }
- b.Add()
- return b.Type, true
- }
- }
- return 0, false
- }
- func CheckBlackABE(ip, nickname, reg string, userid, paytype, totalmoney, count int) (int, bool) {
- //判断是否符合黑名单A特征 含有关键字
- if strings.Contains(nickname, "tencent_game") ||
- strings.Contains(nickname, "rdgztest_") ||
- strings.Contains(nickname, "minigamecheck") ||
- strings.Contains(nickname, "city") {
- b := &BlackUsers{
- Type: 1,
- Ip: ip,
- Count: count,
- Createtime: reg,
- Nickname: nickname,
- Totalmoney: totalmoney,
- Userid: userid,
- }
- b.Add()
- return b.Type, true
- }
- //判断黑名单B,E情况 局数0注册时间久
- regTime := strings.Replace(reg, "T", " ", -1)
- if len(regTime) >= 19 {
- parse, _ := time.Parse("2006-01-02 15:04:05", regTime)
- if day := CheckSubDay(parse); day >= 180 && count == 0 {
- b := &BlackUsers{
- Type: paytype,
- Ip: ip,
- Count: count,
- Createtime: reg,
- Nickname: nickname,
- Totalmoney: totalmoney,
- Userid: userid,
- }
- b.Add()
- return b.Type, true
- }
- }
- return 0, false
- }
- //GetBlackLevel 获取黑名单等级
- func GetBlackLevel(userid int) int {
- if v, ok := PayBlackCacheNew.Get(userid); ok {
- return v
- }
- return -1
- }
- //RedUsers 观察名单
- type RedUsers struct {
- Id int `json:"id" sql:"id"` //自增ID
- Userid int `json:"userid" sql:"userid"` //用户ID
- Nickname string `json:"nickname" sql:"nickname"` //用户昵称
- Count int `json:"count" sql:"count"` //局数
- Totalmoney int `json:"total_money" sql:"total_money"` //支付历史金额
- Ip string `json:"ip" sql:"ip"` //ip
- Createtime string `json:"create_time" sql:"create_time"` //注册时间
- Time string `json:"time" sql:"time"` //创建时间
- Type int `json:"type" sql:"type"` //等级 1观察名单 3 排除名单
- }
- //BlackUsers 黑名单
- type BlackUsers struct {
- Id int `json:"id" sql:"id"` //自增ID
- Userid int `json:"userid" sql:"userid"` //用户ID
- Nickname string `json:"nickname" sql:"nickname"` //用户昵称
- Count int `json:"count" sql:"count"` //局数
- Totalmoney int `json:"total_money" sql:"total_money"` //支付历史金额
- Ip string `json:"ip" sql:"ip"` //ip
- Createtime string `json:"create_time" sql:"create_time"` //注册时间
- Time string `json:"time" sql:"time"` //创建时间
- Type int `json:"type" sql:"type"` //等级 1(关键字) 2(无游戏) 3(无支付) 4(IP段其他) 5(单IP无游戏)
- }
- func (b *BlackUsers) Add() (int64, error) {
- var last int64
- var err error
- sqlQuery := fmt.Sprintf("INSERT IGNORE INTO black_users (`userid`,`nickname`,`count`,`total_money`,`ip`, `create_time`, `type`) VALUE(?,?,?,?,?,?,?)")
- last, err = dbx.MySQL.Insert(sqlQuery, b.Userid, b.Nickname, b.Count, b.Totalmoney, b.Ip, strings.Replace(b.Createtime, "T", " ", -1), b.Type)
- if err != nil {
- logs.Error(fmt.Sprintf("black_users param:%#v err:%v", b, err))
- return 0, err
- }
- return last, nil
- }
- func GetBlackUsersType(userid int) int {
- var typ int
- err := dbx.MySQL.QueryRow("SELECT type from `black_users` where userid = ? ",
- userid).Scan(&typ)
- if nil != err {
- if err == sql.ErrNoRows {
- return typ
- }
- logs.Errorf("GetBlackUsersType err:%v", err)
- }
- return typ
- }
- func GetBlackAlLUsers() {
- PayBlackCacheNew = NewPayBlackCacheNew()
- t1 := time.Now()
- rows, err := dbx.MySQL.Query("SELECT userid, type from `black_users` where type in (1,2)")
- defer rows.Close()
- if err != nil && err != sql.ErrNoRows {
- logs.Errorf("GetBlackAlLUsers err:%v", err)
- return
- }
- var userid, typ int
- for rows.Next() {
- err = rows.Scan(&userid, &typ)
- if err != nil {
- logs.Errorf("GetBlackAlLUsers err:%v", err)
- return
- }
- PayBlackCacheNew.Set(userid, typ)
- }
- t2 := time.Now()
- xlog.Infof("加载黑名单配置时长:%s 数据:%+v", t2.Sub(t1), PayBlackCacheNew)
- }
- func (b *RedUsers) Add() (int64, error) {
- var last int64
- var err error
- sqlQuery := "INSERT IGNORE INTO red_users (`userid`,`nickname`,`count`,`total_money`,`ip`, `create_time`, `type`) VALUE(?,?,?,?,?,?,?)"
- last, err = dbx.MySQL.Insert(sqlQuery, b.Userid, b.Nickname, b.Count, b.Totalmoney, b.Ip, strings.Replace(b.Createtime, "T", " ", -1), b.Type)
- if err != nil {
- logs.Error(fmt.Sprintf("red_users param:%#v err:%v", b, err))
- return 0, err
- }
- return last, nil
- }
- func GetBUserInfo(tag string, st int64, level string) []BlackUsers {
- start := tools.TimeParseForMat(st, "2006-01-02 15:04:05")
- end := tools.TimeParseForMat(st+86400, "2006-01-02 15:04:05")
- var table, where string
- if tag == "red" {
- table = "red_users"
- } else if tag == "black" {
- table = "black_users"
- } else {
- return nil
- }
- if level != "" {
- l, _ := strconv.Atoi(level)
- where = fmt.Sprintf(" and type = %d", l)
- }
- var bu []BlackUsers
- sql := fmt.Sprintf("select * from `%s` where time >= '%s' and time <= '%s' %s ORDER BY time DESC", table, start, end, where)
- dbx.MySQL.Query2(sql, &bu)
- return bu
- }
|