Initial commit

This commit is contained in:
eleksir
2025-06-08 04:32:16 +03:00
parent c1ad1d3925
commit dd0296d323
100 changed files with 9773 additions and 462 deletions

View File

@@ -1,163 +1,160 @@
package moon
import (
"fmt"
"slices"
"strconv"
"strings"
"time"
)
func RunAndBan() {
for {
// If user have both events, he is not spammer. So wipe him from unchecked events list, just for sure.
for _, chatid := range ChatList {
Log.Infof("RunAndBan by chatid: %d", chatid)
var (
ListAppearedMembers, ListNewMembers []string
empty string
)
var ListAppearedMembers, ListNewMembers []int64
AppearedMembers.Range(
func(k, _ any) bool {
ListAppearedMembers = append(ListAppearedMembers, k.(string))
AppearedMembers[chatid].Range(
func(k, _ any) bool {
ListAppearedMembers = append(ListAppearedMembers, k.(int64))
return true
},
)
return true
},
)
NewMembers.Range(
func(k, _ any) bool {
ListNewMembers = append(ListNewMembers, k.(string))
NewMembers[chatid].Range(
func(k, _ any) bool {
ListNewMembers = append(ListNewMembers, k.(int64))
return true
},
)
return true
},
)
for _, AppearedMember := range ListAppearedMembers {
for _, NewMember := range ListNewMembers {
if AppearedMember == NewMember {
// TODO: Store also additional attributes in temporary database.
Log.Infof(
"Skip banning user %s %s (username = %s, id = %d) in %s %s (%d), because it has both events newMember and updateMember",
"",
"",
"",
NewMember,
"",
"",
chatid,
)
Log.Infof(
"Deleting user %s %s (username = %s, id = %d) in %s %s (%d), from AppearedMember DB",
"",
"",
"",
NewMember,
"",
"",
chatid,
)
AppearedMembers[chatid].Delete(AppearedMember)
Log.Infof(
"Deleting user %s %s (username = %s, id = %d) in %s %s (%d), from NewMember DB",
"",
"",
"",
NewMember,
"",
"",
chatid,
)
NewMembers[chatid].Delete(NewMember)
}
for _, AppearedMember := range ListAppearedMembers {
for _, NewMember := range ListNewMembers {
if AppearedMember == NewMember {
AppearedMembers.Delete(AppearedMember)
NewMembers.Delete(NewMember)
}
}
}
currentTime := time.Now().Unix()
// We would like to process only events that definitely older than 10 seconds!
for _, chatid := range ChatList {
var (
ListAppearedMembers, ListNewMembers []int64
)
ListAppearedMembers = ListAppearedMembers[:0]
ListNewMembers = ListNewMembers[:0]
ListAppearedMembers = slices.Clip(ListAppearedMembers)
ListNewMembers = slices.Clip(ListNewMembers)
AppearedMembers[chatid].Range(
func(k, v interface{}) bool {
ListAppearedMembers = append(ListAppearedMembers, k.(int64))
AppearedMembers.Range(
func(k, _ any) bool {
ListAppearedMembers = append(ListAppearedMembers, k.(string))
return true
},
)
return true
},
)
NewMembers[chatid].Range(
func(k, v interface{}) bool {
ListNewMembers = append(ListNewMembers, k.(int64))
NewMembers.Range(
func(k, _ any) bool {
ListNewMembers = append(ListNewMembers, k.(string))
return true
},
)
return true
},
)
for _, AppearedMember := range ListAppearedMembers {
eventTimestamp, found := AppearedMembers[chatid].Get(AppearedMember)
for _, AppearedMember := range ListAppearedMembers {
eventTimestamp, found := AppearedMembers.Get(AppearedMember)
if !found {
continue
}
eventTimeDelta := currentTime - eventTimestamp.(int64)
// Looks like it is spammer!
if eventTimeDelta > 10 {
// TODO: Store also additional attributes in temporary database.
Log.Infof(
"Ban user %s %s (username = %s, id = %d) in chat %s %s (%d) that have no newChatMember message since chatMemberUpdated for more than 10 seconds",
"",
"",
"",
AppearedMember,
"",
"",
chatid,
)
squash(
chatid,
"",
"",
AppearedMember,
"",
"",
"",
)
AppearedMembers[chatid].Delete(AppearedMember)
}
if !found {
continue
}
for _, NewMember := range ListNewMembers {
eventTimestamp, found := NewMembers[chatid].Get(NewMember)
eventTimeDelta := currentTime - eventTimestamp.(int64)
// Spammer?
if eventTimeDelta > 10 {
item := strings.Split(AppearedMember, "+")
chatid, err := strconv.ParseInt(item[0], 10, 64)
if err != nil {
Log.Errorf("Got broken key in AppearedMembers cache: %s", AppearedMember)
if !found {
continue
}
eventTimeDelta := currentTime - eventTimestamp.(int64)
userid, err := strconv.ParseInt(item[1], 10, 64)
// Totally new members should not have chatMemberUpdated events.
if eventTimeDelta > 15 {
// TODO: Store also additional attributes in temporary database.
Log.Debugf("Clean newChatMember event record older than 10 seconds for user user %s %s (username = %s, id = %d) in chat %s %s (%d)",
"",
"",
"",
NewMember,
"",
"",
chatid,
)
if err != nil {
Log.Errorf("Got broken key in AppearedMembers cache: %s", AppearedMember)
NewMembers[chatid].Delete(NewMember)
continue
}
Log.Infof(
"Ban user %s %s (username = %s, id = %d) in chat %s %s (%d) that have no newChatMember message since chatMemberUpdated for more than 10 seconds",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
squash(
chatid,
empty,
empty,
userid,
empty,
empty,
empty,
)
AppearedMembers.Delete(AppearedMember)
}
}
for _, NewMember := range ListNewMembers {
eventTimestamp, found := NewMembers.Get(NewMember)
if !found {
continue
}
eventTimeDelta := currentTime - eventTimestamp.(int64)
// Spammer?
if eventTimeDelta > 10 {
item := strings.Split(NewMember, "+")
chatid, err := strconv.ParseInt(item[0], 10, 64)
if err != nil {
Log.Errorf("Got broken key in AppearedMembers cache: %s", NewMember)
continue
}
userid, err := strconv.ParseInt(item[1], 10, 64)
if err != nil {
Log.Errorf("Got broken key in AppearedMembers cache: %s", NewMember)
continue
}
Log.Debugf("Clean newChatMember event record older than 10 seconds for user user %s %s (username = %s, id = %d) in chat %s %s (%d)",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
NewMembers.Delete(NewMember)
}
}
@@ -165,4 +162,142 @@ func RunAndBan() {
}
}
func PeriodicCASCheck() {
for {
var (
ListPendingMembers []string
empty string
)
PendingCASMembers.Range(
func(k, _ any) bool {
ListPendingMembers = append(ListPendingMembers, k.(string))
return true
},
)
currentTime := time.Now().Unix()
for _, PendingMember := range ListPendingMembers {
eventTimestamp, found := PendingCASMembers.Get(PendingMember)
if !found {
continue
}
eventTimeDelta := currentTime - eventTimestamp.(int64)
// It's time to check for second time this id if it was banned in CAS.
if eventTimeDelta > 300 {
item := strings.Split(PendingMember, "+")
chatid, err := strconv.ParseInt(item[0], 10, 64)
if err != nil {
Log.Errorf("Got broken key in PendingMembers cache: %s", PendingMember)
continue
}
userid, err := strconv.ParseInt(item[1], 10, 64)
if err != nil {
Log.Errorf("Got broken key in PendingMembers cache: %s", PendingMember)
continue
}
value := Cfg.GetValue(
"BannedMembers",
fmt.Sprintf("%d", chatid),
fmt.Sprintf("%d", userid),
)
if value != "" {
Log.Debugf("User %s %s (username = %s, id = %d) in %s %s (%d) is already banned, skip cas check.",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
Log.Debugf(
"Remove user %s %s (username = %s, id = %d) in %s %s (%d) from PendingCASMembers",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
key := fmt.Sprintf("%d+%d", chatid, userid)
PendingCASMembers.Delete(key)
return
}
Log.Debugf("Checking user %s %s (username = %s, id = %d) in %s %s (%d) for second time in CAS",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
banned, err := CasCheckID(userid)
if err != nil {
Log.Error(err)
}
if banned {
Log.Infof(
"Ban user %s %s (username = %s, id = %d) in %s %s (%d) by CAS blacklist",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
squash(
userid,
empty,
empty,
userid,
empty,
empty,
empty,
)
}
Log.Debugf(
"Remove user %s %s (username = %s, id = %d) in %s %s (%d) from PendingCASMembers",
empty,
empty,
empty,
userid,
empty,
empty,
chatid,
)
PendingCASMembers.Delete(PendingMember)
}
}
time.Sleep(10 * time.Minute)
}
}
/* vim: set ft=go noet ai ts=4 sw=4 sts=4: */