package main import ( "github.com/globalsign/mgo" "mongo.games.com/game/model" "mongo.games.com/goserver/core/logger" "net" "strings" ) const ( BlackState_Login uint = 1 << iota //登录 BlackState_Exchange //兑换 BlackState_Recharge //充值 BlackState_Match //比赛 BlackState_Max ) var BlackListMgrSington = NewBlackListMgr() type BlackInfoApi struct { Id int32 Space int32 Snid int32 Alipay_account string Alipay_name string Bankcard string Ip string Platform string PackageTag string Explain string Creator int32 Create_time string Update_time string DeviceId string //设备ID } type BlackInfo struct { Id int32 BlackType int //1.游戏2.兑换3.充值4.比赛 Alipay_account string Alipay_name string Bankcard string Ip string //support like "192.0.2.0/24" or "2001:db8::/32", as defined in RFC 4632 and RFC 4291. Platform string PackageTag string DeviceId string //设备ID ipNet *net.IPNet } type BlackListMgr struct { BlackList map[int32]*BlackInfo BlackListByPlatform [BlackState_Max]map[string]map[int32]*BlackInfo AlipayAccByPlatform [BlackState_Max]map[string]map[string]*BlackInfo AlipayNameByPlatform [BlackState_Max]map[string]map[string]*BlackInfo BankcardByPlatform [BlackState_Max]map[string]map[string]*BlackInfo IpByPlatform [BlackState_Max]map[string]map[string]*BlackInfo IpNetByPlatform [BlackState_Max]map[string][]*BlackInfo PackageTagByPlatform [BlackState_Max]map[string]*BlackInfo DeviceByPlatform [BlackState_Max]map[string]map[string]*BlackInfo } func NewBlackListMgr() *BlackListMgr { ret := &BlackListMgr{ BlackList: make(map[int32]*BlackInfo), } for i := uint(0); i < BlackState_Max; i++ { ret.BlackListByPlatform[i] = make(map[string]map[int32]*BlackInfo) ret.AlipayAccByPlatform[i] = make(map[string]map[string]*BlackInfo) ret.AlipayNameByPlatform[i] = make(map[string]map[string]*BlackInfo) ret.BankcardByPlatform[i] = make(map[string]map[string]*BlackInfo) ret.IpByPlatform[i] = make(map[string]map[string]*BlackInfo) ret.IpNetByPlatform[i] = make(map[string][]*BlackInfo) ret.PackageTagByPlatform[i] = make(map[string]*BlackInfo) ret.DeviceByPlatform[i] = make(map[string]map[string]*BlackInfo) } return ret } func (this *BlackListMgr) DivBlackInfo(blackInfo *BlackInfo) { for i := uint(0); i < BlackState_Max; i++ { if blackInfo.BlackType&(1< 0 { aabp := this.AlipayAccByPlatform[i] if aabp != nil { if pool, exist := aabp[blackInfo.Platform]; exist { pool[blackInfo.Alipay_account] = blackInfo } else { pool = make(map[string]*BlackInfo) if pool != nil { pool[blackInfo.Alipay_account] = blackInfo aabp[blackInfo.Platform] = pool } } } } //alipay name if len(blackInfo.Alipay_name) > 0 { anbp := this.AlipayNameByPlatform[i] if anbp != nil { if pool, exist := anbp[blackInfo.Platform]; exist { pool[blackInfo.Alipay_name] = blackInfo } else { pool = make(map[string]*BlackInfo) if pool != nil { pool[blackInfo.Alipay_name] = blackInfo anbp[blackInfo.Platform] = pool } } } } //bank if len(blackInfo.Bankcard) > 0 { bankbp := this.BankcardByPlatform[i] if bankbp != nil { if pool, exist := bankbp[blackInfo.Platform]; exist { pool[blackInfo.Bankcard] = blackInfo } else { pool = make(map[string]*BlackInfo) if pool != nil { pool[blackInfo.Bankcard] = blackInfo bankbp[blackInfo.Platform] = pool } } } } //ip if len(blackInfo.Ip) > 0 { ipbp := this.IpByPlatform[i] if ipbp != nil { if pool, exist := ipbp[blackInfo.Platform]; exist { pool[blackInfo.Ip] = blackInfo } else { pool = make(map[string]*BlackInfo) if pool != nil { pool[blackInfo.Ip] = blackInfo ipbp[blackInfo.Platform] = pool } } } } //ipnet if blackInfo.ipNet != nil { ipbp := this.IpNetByPlatform[i] if ipbp != nil { if pool, exist := ipbp[blackInfo.Platform]; exist { pool = append(pool, blackInfo) ipbp[blackInfo.Platform] = pool } else { ipbp[blackInfo.Platform] = []*BlackInfo{blackInfo} } } } //packageid if len(blackInfo.PackageTag) > 0 { packbp := this.PackageTagByPlatform[i] if packbp != nil { packbp[blackInfo.PackageTag] = blackInfo } } //deviceinfo if len(blackInfo.DeviceId) > 0 { ipbp := this.DeviceByPlatform[i] if ipbp != nil { if pool, exist := ipbp[blackInfo.Platform]; exist { pool[blackInfo.DeviceId] = blackInfo } else { pool = make(map[string]*BlackInfo) if pool != nil { pool[blackInfo.DeviceId] = blackInfo ipbp[blackInfo.Platform] = pool } } } } } } } func (this *BlackListMgr) UnDivBlackInfo(blackInfo *BlackInfo) { for i := uint(0); i < BlackState_Max; i++ { if blackInfo.BlackType&(1< 0 { aabp := this.AlipayAccByPlatform[i] if aabp != nil { if pool, exist := aabp[blackInfo.Platform]; exist { delete(pool, blackInfo.Alipay_account) } } } //alipay name if len(blackInfo.Alipay_name) > 0 { anbp := this.AlipayNameByPlatform[i] if anbp != nil { if pool, exist := anbp[blackInfo.Platform]; exist { delete(pool, blackInfo.Alipay_name) } } } //bank if len(blackInfo.Bankcard) > 0 { bankbp := this.BankcardByPlatform[i] if bankbp != nil { if pool, exist := bankbp[blackInfo.Platform]; exist { delete(pool, blackInfo.Bankcard) } } } //ip if len(blackInfo.Ip) > 0 { ipbp := this.IpByPlatform[i] if ipbp != nil { if pool, exist := ipbp[blackInfo.Platform]; exist { delete(pool, blackInfo.Ip) } } } //ipnet if blackInfo.ipNet != nil { ipbp := this.IpNetByPlatform[i] if ipbp != nil { if pool, exist := ipbp[blackInfo.Platform]; exist { index := -1 for i, bi := range pool { if bi.ipNet == blackInfo.ipNet { index = i break } } if index != -1 { pool = append(pool[:index], pool[index+1:]...) } ipbp[blackInfo.Platform] = pool } } } //packageid if len(blackInfo.PackageTag) > 0 { packbp := this.PackageTagByPlatform[i] if packbp != nil { delete(packbp, blackInfo.PackageTag) } } //deviceinfo if len(blackInfo.DeviceId) > 0 { ipbp := this.DeviceByPlatform[i] if ipbp != nil { if pool, exist := ipbp[blackInfo.Platform]; exist { delete(pool, blackInfo.DeviceId) } } } } } } // 初始化 func (this *BlackListMgr) InitBlackInfo(bia *BlackInfoApi) { blackInfo := &BlackInfo{ Id: bia.Id, BlackType: int(bia.Space), Alipay_account: bia.Alipay_account, Alipay_name: bia.Alipay_name, Bankcard: bia.Bankcard, Ip: bia.Ip, Platform: bia.Platform, PackageTag: bia.PackageTag, DeviceId: bia.DeviceId, } if strings.Contains(blackInfo.Ip, "/") { _, blackInfo.ipNet, _ = net.ParseCIDR(blackInfo.Ip) } this.BlackList[blackInfo.Id] = blackInfo this.DivBlackInfo(blackInfo) } func (this *BlackListMgr) UpsertBlackInfo(bia *BlackInfoApi) { blackInfo := &BlackInfo{ Id: bia.Id, BlackType: int(bia.Space), Alipay_account: bia.Alipay_account, Alipay_name: bia.Alipay_name, Bankcard: bia.Bankcard, Ip: bia.Ip, Platform: bia.Platform, PackageTag: bia.PackageTag, DeviceId: bia.DeviceId, } if strings.Contains(blackInfo.Ip, "/") { _, blackInfo.ipNet, _ = net.ParseCIDR(blackInfo.Ip) } if old, exist := this.BlackList[blackInfo.Id]; exist { this.UnDivBlackInfo(old) } this.BlackList[blackInfo.Id] = blackInfo this.DivBlackInfo(blackInfo) } func (this *BlackListMgr) RemoveBlackInfo(Id int32, platform string) { if org, exist := this.BlackList[Id]; exist { if len(platform) == 0 || org.Platform == platform { logger.Logger.Infof("(this *BlackListMgr) RemoveBlackInfo(Id:%v, platform:%v)", Id, platform) delete(this.BlackList, Id) this.UnDivBlackInfo(org) } } } func (this *BlackListMgr) CheckPlayerInvalid(blackinfo *BlackInfo, data *model.PlayerData) bool { if len(blackinfo.Platform) > 0 && (data.Platform != blackinfo.Platform && blackinfo.Platform != "0") { return false } switch { //case blackinfo.Snid == data.SnId: //根据用户的ID找到了对应的用户 // return true case len(blackinfo.Ip) > 0 && blackinfo.Ip == data.Ip: //根据用户的IP找到了对应的用户 return true case len(blackinfo.Alipay_name) > 0 && blackinfo.Alipay_name == data.AlipayAccName: //根据用户的支付宝找到了对应的用户 return true case len(blackinfo.Alipay_account) > 0 && blackinfo.Alipay_account == data.AlipayAccount: //根据用户的支付宝账户找到了对应的用户 return true case len(blackinfo.Bankcard) > 0 && blackinfo.Bankcard == data.BankAccount: //根据用户的银行卡找到了对应的用户 return true case len(blackinfo.PackageTag) > 0 && strings.HasPrefix(data.PackageID, blackinfo.PackageTag): //根据包标识找对应的用户 return true } if blackinfo.ipNet != nil { ip := net.ParseIP(data.Ip) if ip != nil { if blackinfo.ipNet.Contains(ip) { return true } } } return false } func (this *BlackListMgr) CheckLogin(data *model.PlayerData) (*BlackInfo, bool) { if bi, ok := this.CheckPlayerInBlack(data, BlackState_Login); ok { return bi, false } return nil, true } func (this *BlackListMgr) CheckExchange(data *model.PlayerData) (*BlackInfo, bool) { if bi, ok := this.CheckPlayerInBlack(data, BlackState_Exchange); ok { return bi, false } return nil, true } func (this *BlackListMgr) CheckRecharge(data *model.PlayerData) (*BlackInfo, bool) { if bi, ok := this.CheckPlayerInBlack(data, BlackState_Recharge); ok { return bi, false } return nil, true } func (this *BlackListMgr) CheckMatch(data *model.PlayerData) (*BlackInfo, bool) { if bi, ok := this.CheckPlayerInBlack(data, BlackState_Match); ok { return bi, false } return nil, true } func (this *BlackListMgr) CheckPlayerInBlack(data *model.PlayerData, blackType uint) (bi *BlackInfo, ok bool) { if data.IsRob { return nil, false } if bi, ok := this.CheckPlayerInBlackByPlatfromUsePlayerBind(data, blackType, data.Platform); ok { return bi, true } return nil, false } func (this *BlackListMgr) CheckPlayerInBlackByPlatfromUsePlayerBind(data *model.PlayerData, blackType uint, platform string) (*BlackInfo, bool) { if blackType >= 0 && blackType < BlackState_Max { //先检查snid if uint(data.BlacklistType)&blackType != 0 { logger.Logger.Infof("found platform:%v player:%d snid in blacklist", platform, data.SnId) return nil, true } //支付宝账号 //if len(data.AlipayAccount) > 0 { // aabp := this.AlipayAccByPlatform[blackType] // if aabp != nil { // if pool, exist := aabp[platform]; exist { // if bi, exist := pool[data.AlipayAccount]; exist { // logger.Logger.Infof("found platform:%v player:%d AlipayAccount:%v in blacklist", platform, data.SnId, data.AlipayAccount) // return bi, true // } // } // } //} //支付宝用户名 //if len(data.AlipayAccName) > 0 { // aabp := this.AlipayNameByPlatform[blackType] // if aabp != nil { // if pool, exist := aabp[platform]; exist { // if bi, exist := pool[data.AlipayAccName]; exist { // logger.Logger.Infof("found platform:%v player:%d AlipayAccName:%v in blacklist", platform, data.SnId, data.AlipayAccName) // return bi, true // } // } // } //} //银行卡号 //if len(data.BankAccount) > 0 { // bankbp := this.BankcardByPlatform[blackType] // if bankbp != nil { // if pool, exist := bankbp[platform]; exist { // if bi, exist := pool[data.BankAccount]; exist { // logger.Logger.Infof("found platform:%v player:%d BankAccount:%v in blacklist", platform, data.SnId, data.BankAccount) // return bi, true // } // } // } //} //ip检查 if len(data.Ip) > 0 { //精准ip ipbp := this.IpByPlatform[blackType] if ipbp != nil { if pool, exist := ipbp[platform]; exist { if bi, exist := pool[data.Ip]; exist { logger.Logger.Infof("found platform:%v player:%d Ip:%v in blacklist", platform, data.SnId, data.Ip) return bi, true } } } //ip段 ipnetbp := this.IpNetByPlatform[blackType] if ipnetbp != nil { if pool, exist := ipnetbp[platform]; exist { for _, bi := range pool { ip := net.ParseIP(data.Ip) if ip != nil { if bi.ipNet.Contains(ip) { logger.Logger.Infof("found platform:%v player:%d Ip:%v in blacklist ipnet:%v", platform, data.SnId, data.Ip, bi.ipNet.String()) return bi, true } } } } } } //包标识 if len(data.PackageID) > 0 { packbp := this.PackageTagByPlatform[blackType] if packbp != nil { if bi, exist := packbp[data.PackageID]; exist { logger.Logger.Infof("found platform:%v player:%d PackageID:%v in blacklist", platform, data.SnId, data.PackageID) return bi, true } } } //设备号 if len(data.DeviceId) > 0 { deviceByPlatform := this.DeviceByPlatform[blackType] if deviceByPlatform != nil { if devices, exist := deviceByPlatform[data.Platform]; exist { if bi, ok := devices[data.DeviceId]; ok { logger.Logger.Infof("found platform:%v player:%d PackageID:%v in blacklist", platform, data.SnId, data.PackageID) return bi, true } } } } } return nil, false } // 设备号验证 func (this *BlackListMgr) CheckDeviceInBlack(deviceId string, blackType uint, platform string) (*BlackInfo, bool) { if bi, ok := this.CheckDeviceInBlackByPlatfrom(deviceId, blackType, platform); ok { return bi, true } return nil, false } func (this *BlackListMgr) CheckDeviceInBlackByPlatfrom(deviceId string, blackType uint, platform string) (*BlackInfo, bool) { if blackType >= 0 && blackType < BlackState_Max { if len(deviceId) > 0 { devicebp := this.DeviceByPlatform[blackType] if devicebp != nil { if pool, exist := devicebp[platform]; exist { if bi, ok := pool[deviceId]; ok { logger.Logger.Infof("found platform:%v device:%s in blacklist", platform, deviceId) return bi, true } } } } } return nil, false } func init() { mgo.SetStats(true) }