Exemplo n.º 1
0
        private void LoadPunishments()
        {
            if (!File.Exists(PunishmentFile))
            {
                return;
            }

            lock (m_fileSyncObj)
            {
                using (var br = new BinaryReader(new FileStream(PunishmentFile, FileMode.Open)))
                {
                    int cnt = br.ReadInt32();

                    for (int i = 0; i < cnt; ++i)
                    {
                        ulong    id      = br.ReadUInt64();
                        DateTime endTime = DateTime.FromBinary(br.ReadInt64());
                        m_endTimes.AddOrUpdate(id, endTime, (key, val) => endTime);

                        int punishCount = br.ReadInt32();
                        var spamUser    = new SpamUser {
                            PunishCount = punishCount
                        };
                        m_spamUsers.AddOrUpdate(id, spamUser, (key, val) => spamUser);
                    }

                    br.Close();
                }
            }
        }
Exemplo n.º 2
0
        public SpamUser ResetSpamGage()
        {
            SpamUser temp = this;

            temp.SpamGage = 0;

            return(temp);
        }
Exemplo n.º 3
0
        private int UpdateSpamGage(ulong userId, ulong channelId, DateTimeOffset timestamp)
        {
            // 조용, 인증 채널에선 도배 판정하지 않음.
            if (channelId == DiscordConstants.QuietChannelId ||
                channelId == DiscordConstants.AuthChannelId)
            {
                return(0);
            }


            var newMsg = new SpamMessage
            {
                Author       = userId,
                CreationTime = timestamp,
            };


            if (m_lastChannelMsg.TryGetValue(channelId, out SpamMessage prevMsg))
            {
                // 가장 최근의 메세지로 갱신.
                m_lastChannelMsg.AddOrUpdate(channelId, newMsg, (key, val) =>
                {
                    return((newMsg.CreationTime > val.CreationTime) ? newMsg : val);
                });


                if (userId == prevMsg.Author)
                {
                    var delay = timestamp - prevMsg.CreationTime;

                    if (delay >= m_maxSpamDelay)
                    {
                        // 스팸 게이지 초기화.
                        m_spamUsers.AddOrUpdate(userId, SpamUser.Empty, (key, usr) => usr.ResetSpamGage());
                    }
                    else
                    {
                        if (timestamp == prevMsg.CreationTime)
                        {
                            // 시간 해상도가 1초이므로 시간이 같다는 것은 시간차가 최대 1초라는 것.
                            // 따라서 충분히 작은 시간으로 딜레이를 가정한다.
                            delay = TimeSpan.FromSeconds(0.01);
                        }

                        // 기존 유저 정보 얻음.
                        SpamUser spamUser;
                        if (!m_spamUsers.TryGetValue(userId, out spamUser))
                        {
                            spamUser = new SpamUser();
                        }

                        // 스팸 수치 계산.
                        int spamGage = (int)Math.Round((1.0 - (delay / m_maxSpamDelay)) * m_spamGageScale);
                        spamUser.SpamGage += spamGage;

                        int punishTime = spamUser.SpamGage / m_spamGageScale;

                        // 처벌 시간이 트리거에 도달하면 처벌이 이뤄지고 가중되도록 카운트를 증가시킴.
                        if (punishTime >= m_triggerPunishTime)
                        {
                            spamUser.PunishCount += 1;
                        }

                        // 변경된 유저 정보 갱신.
                        m_spamUsers.AddOrUpdate(userId, spamUser, (key, old) =>
                        {
                            return((spamUser.PunishCount >= old.PunishCount) ? spamUser : old);
                        });

                        if (punishTime >= m_triggerPunishTime)
                        {
                            // 가중 처벌이 계산된 처벌 시간 반환.
                            return(punishTime * spamUser.PunishCount * spamUser.PunishCount);
                        }
                    }
                }
                else
                {
                    // 대화 중인 것으로 판정하여 도배로 보지 않음.
                    m_spamUsers.AddOrUpdate(userId, SpamUser.Empty, (key, usr) => usr.ResetSpamGage());
                    m_spamUsers.AddOrUpdate(prevMsg.Author, SpamUser.Empty, (key, usr) => usr.ResetSpamGage());
                }
            }
            else
            {
                // 가장 최근의 메세지로 초기화.
                m_lastChannelMsg.AddOrUpdate(channelId, newMsg, (key, val) =>
                {
                    return((newMsg.CreationTime > val.CreationTime) ? newMsg : val);
                });
            }


            return(0);
        }