| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299 |
- package model
- import (
- "github.com/gogf/gf/text/gstr"
- "hash/crc32"
- "rocommon/util"
- "roserver/baseserver/model"
- "roserver/serverproto"
- "unicode/utf8"
- )
- type RoleStatistic struct {
- SaveObject
- cheatData map[int32]int32
- //cheat chat msg
- cheatMsgPersonalCheckTime uint64
- cheatChatPersonal map[uint64]*serverproto.RoleCheatChat //恶意私聊 [消息识别码]
- cheatChatPersonalContentList []string
- cheatMsgPublicCheckTime uint64
- cheatChatPublic map[uint64]int //世界&公会聊天 [消息识别码,数量]
- cheatChatPublicContentList []string
- }
- var GlobalCheatChatPublicContentList = map[uint64]string{} //全局聊天处理
- const (
- CheatType_GMWEB = 0 //后台进行封号操作
- CheatType_TimeScale = 1 //时间加速
- CheatType_NormalLevel = 2 //普通关卡挑战时间过短
- CheatType_TowerLevel = 3 //爬塔关卡挑战时间过短
- CheatType_PersonalChat = 4 //恶意私聊:账号封停功能
- CheatType_PublicChat = 5 //世界频道、公会频道:账号禁言功能
- )
- func newRoleStatistic(r *Role) *RoleStatistic {
- roleStatistics := &RoleStatistic{
- SaveObject: SaveObject{
- role: r,
- },
- cheatChatPersonal: map[uint64]*serverproto.RoleCheatChat{},
- cheatChatPublic: map[uint64]int{},
- }
- roleStatistics.cheatData = make(map[int32]int32)
- return roleStatistics
- }
- func (this *RoleStatistic) Load(msg interface{}) bool {
- proRole := msg.(*serverproto.Role)
- if proRole.RoleStatistic != nil {
- if len(proRole.RoleStatistic.CheatData) > 0 {
- for _, data := range proRole.RoleStatistic.CheatData {
- this.cheatData[data.Key] = data.Value
- }
- }
- }
- return true
- }
- func (this *RoleStatistic) Save() {
- this.SetDirty(false)
- util.InfoF("uid=%v RoleStatistic save...", this.role.GetUUid())
- saveMsg := &serverproto.SSStatisticsDataSaveReq{
- Statistics: &serverproto.RoleStatistic{},
- }
- for key, value := range this.cheatData {
- saveMsg.Statistics.CheatData = append(saveMsg.Statistics.CheatData, &serverproto.KeyValueType{
- Key: key,
- Value: value,
- })
- }
- this.role.SendDb(saveMsg)
- }
- func (this *RoleStatistic) RecordCheatData(cheatType int32) {
- this.cheatData[cheatType] += 1
- this.SetDirty(true)
- util.ErrorF("uid=%v RoleStatistic name=%v cheat type=%v count=%v", this.role.GetUUid(), string(this.role.GetNickName()), cheatType, this.cheatData[cheatType])
- this.cheatKick(cheatType)
- }
- func (this *RoleStatistic) ClearCheatData() {
- util.InfoF("uid=%v RoleStatistic ClearCheatData cheatData=%v", this.cheatData)
- this.cheatData = map[int32]int32{}
- this.SetDirty(true)
- }
- func (this *RoleStatistic) cheatKick(cheatType int32) {
- //玩家作弊,踢下线
- var cheatNum = this.cheatData[cheatType]
- //for _, val := range this.cheatData {
- // cheatNum += val
- //}
- var banTime uint64 = 0
- if cheatNum >= model.GlobalMaxCheatBanNum {
- banTime = model.GlobalMaxCheatBanTime
- } else {
- if tmpTime, ok := model.GlobalCheatBanTime[cheatNum]; ok {
- banTime = tmpTime
- }
- }
- if banTime <= 0 {
- if cheatType != CheatType_PublicChat {
- this.role.KickWithSave(int32(serverproto.ErrorCode_ERROR_SERVER_KICK_CHEAT))
- }
- } else {
- if cheatType == CheatType_PublicChat {
- //禁言
- this.role.BanRoleChat(true, banTime, cheatType)
- } else {
- //封号
- this.role.BanRole(true, banTime, cheatType)
- }
- }
- }
- func (this *RoleStatistic) GetCheatErrorCode(cheatType int32) int32 {
- switch cheatType {
- case CheatType_TimeScale:
- return int32(serverproto.ErrorCode_ERROR_ROLE_BANED_TYPE_TIME)
- case CheatType_NormalLevel:
- return int32(serverproto.ErrorCode_ERROR_ROLE_BANED_TYPE_LEVEL)
- case CheatType_TowerLevel:
- return int32(serverproto.ErrorCode_ERROR_ROLE_BANED_TYPE_LEVEL)
- case CheatType_PersonalChat:
- return int32(serverproto.ErrorCode_ERROR_ROLE_BANED_TYPE_PERSONALCHAT)
- case CheatType_PublicChat:
- return int32(serverproto.ErrorCode_ERROR_ROLE_BANED_TYPE_PERSONALCHAT)
- }
- return int32(serverproto.ErrorCode_ERROR_ROLE_BANED)
- }
- //true可以发送聊天 false屏蔽发言
- func (this *RoleStatistic) CheckChatMsg(msgType int32, targetUid uint64, chatContent string) bool {
- bSendMsg := true
- if msgType == int32(serverproto.ChatMessageType_CMT_PERSONAL) {
- if this.role.GetRoleLevel() > model.GlobalCheatPersonalChat.Level ||
- int32(this.role.GetTotalRecharge()) >= model.GlobalCheatPersonalChat.RechargeNum {
- return bSendMsg
- }
- nowTime := util.GetTimeMilliseconds()
- if nowTime > this.cheatMsgPersonalCheckTime &&
- nowTime-this.cheatMsgPersonalCheckTime > model.GlobalCheatPersonalChat.ChatDuration {
- this.cheatMsgPersonalCheckTime = nowTime
- this.cheatChatPersonal = map[uint64]*serverproto.RoleCheatChat{}
- }
- //trim转义字符
- bMatch := SensitiveUtil.IsMatch(chatContent)
- if bMatch {
- bSendMsg = false
- return bSendMsg
- }
- //1,相同内容屏蔽操作
- chatContentCrc32 := uint64(crc32.ChecksumIEEE([]byte(chatContent)))
- chatCrc32Data, ok := this.cheatChatPersonal[chatContentCrc32]
- if ok {
- bFindTargetUid := false
- for idx := 0; idx < len(chatCrc32Data.TargetId); idx++ {
- if chatCrc32Data.TargetId[idx] == targetUid {
- bFindTargetUid = true
- break
- }
- }
- if !bFindTargetUid {
- chatCrc32Data.TargetId = append(chatCrc32Data.TargetId, targetUid)
- }
- //封号/踢人
- if len(chatCrc32Data.TargetId) >= model.GlobalCheatPersonalChat.ParamList[0] &&
- model.GlobalCheatPersonalChat.ParamList[0] > 0 {
- this.RecordCheatData(CheatType_PersonalChat)
- this.cheatMsgPersonalCheckTime = nowTime
- this.cheatChatPersonal = map[uint64]*serverproto.RoleCheatChat{}
- bSendMsg = false
- return bSendMsg
- }
- } else {
- chatCrc32Data = &serverproto.RoleCheatChat{
- ChatMsgCrc32: chatContentCrc32,
- }
- chatCrc32Data.TargetId = append(chatCrc32Data.TargetId, targetUid)
- this.cheatChatPersonal[chatContentCrc32] = chatCrc32Data
- }
- //2,相似度屏蔽操作
- msgLen := utf8.RuneCountInString(chatContent)
- if msgLen > 10 {
- similarCount := 0
- for idx := 0; idx < len(this.cheatChatPersonalContentList); idx++ {
- var tmpPercent float64 = 0
- gstr.SimilarText(this.cheatChatPersonalContentList[idx], chatContent, &tmpPercent)
- if tmpPercent >= 50.0 {
- similarCount++
- }
- }
- if similarCount >= 3 {
- this.RecordCheatData(CheatType_PublicChat)
- this.cheatMsgPublicCheckTime = nowTime
- bSendMsg = false
- }
- this.cheatChatPersonalContentList = append(this.cheatChatPersonalContentList, chatContent)
- if len(this.cheatChatPersonalContentList) >= 25 {
- msgLen := len(this.cheatChatPersonalContentList)
- this.cheatChatPersonalContentList = this.cheatChatPersonalContentList[msgLen-10:]
- }
- }
- } else if msgType == int32(serverproto.ChatMessageType_CMT_WORLD) ||
- msgType == int32(serverproto.ChatMessageType_CMT_GUILD) {
- if this.role.GetRoleLevel() > model.GlobalCheatPublicChat.Level ||
- int32(this.role.GetTotalRecharge()) >= model.GlobalCheatPublicChat.RechargeNum {
- return bSendMsg
- }
- nowTime := util.GetTimeMilliseconds()
- if this.role.GetRoleBase().roleBase.ChatBanTime*1000 > nowTime {
- bSendMsg = false
- return bSendMsg
- }
- if nowTime > this.cheatMsgPublicCheckTime &&
- nowTime-this.cheatMsgPublicCheckTime > model.GlobalCheatPublicChat.ChatDuration {
- this.cheatMsgPublicCheckTime = nowTime
- this.cheatChatPublic = map[uint64]int{}
- }
- //trim转义字符
- bMatch := SensitiveUtil.IsMatch(chatContent)
- if bMatch {
- bSendMsg = false
- return bSendMsg
- }
- //全局相似度匹配操作(全局中存放的消息队列为禁言玩家的消息列表)
- //1,相同内容屏蔽操作
- chatContentCrc32 := uint64(crc32.ChecksumIEEE([]byte(chatContent)))
- chatCrc32Data, ok := this.cheatChatPublic[chatContentCrc32]
- if ok {
- if chatCrc32Data >= model.GlobalCheatPublicChat.ParamList[0] &&
- model.GlobalCheatPublicChat.ParamList[0] > 0 {
- this.RecordCheatData(CheatType_PublicChat)
- this.cheatMsgPublicCheckTime = nowTime
- this.cheatChatPublic = map[uint64]int{}
- bSendMsg = false
- return bSendMsg
- } else {
- this.cheatChatPublic[chatContentCrc32]++
- }
- } else {
- this.cheatChatPublic[chatContentCrc32]++
- }
- //2,相似度屏蔽操作
- msgLen := utf8.RuneCountInString(chatContent)
- if msgLen >= 10 {
- similarCount := 0
- for idx := 0; idx < len(this.cheatChatPublicContentList); idx++ {
- var tmpPercent float64 = 0
- gstr.SimilarText(this.cheatChatPublicContentList[idx], chatContent, &tmpPercent)
- if tmpPercent >= 50.0 {
- similarCount++
- }
- }
- if similarCount >= 3 {
- this.RecordCheatData(CheatType_PublicChat)
- this.cheatMsgPublicCheckTime = nowTime
- bSendMsg = false
- }
- this.cheatChatPublicContentList = append(this.cheatChatPublicContentList, chatContent)
- if len(this.cheatChatPublicContentList) >= 25 {
- msgLen := len(this.cheatChatPublicContentList)
- this.cheatChatPublicContentList = this.cheatChatPublicContentList[msgLen-10:]
- }
- }
- //全局屏蔽字处理(不做禁止发言操作,值做自言自语)
- if bSendMsg {
- bSensitiveMatch := model.AdvSensitiveUtil.IsMatch(chatContent)
- if bSensitiveMatch {
- bSendMsg = false
- util.InfoF("uid=%v sensitivematch checkchatmsg=%v ", this.role.GetUUid(), string(chatContent))
- }
- }
- }
- return bSendMsg
- }
|