<commit_before>﻿using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Modules.Permissions.Classes;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;

namespace NadekoBot.Modules.Administration.Commands
{
    internal class LogCommand : DiscordCommand
    {

        private readonly ConcurrentDictionary<Server, Channel> logs = new ConcurrentDictionary<Server, Channel>();
        private readonly ConcurrentDictionary<Server, Channel> loggingPresences = new ConcurrentDictionary<Server, Channel>();
        private readonly ConcurrentDictionary<Channel, Channel> voiceChannelLog = new ConcurrentDictionary<Channel, Channel>();

        public LogCommand(DiscordModule module) : base(module)
        {
            NadekoBot.Client.MessageReceived += MsgRecivd;
            NadekoBot.Client.MessageDeleted += MsgDltd;
            NadekoBot.Client.MessageUpdated += MsgUpdtd;
            NadekoBot.Client.UserUpdated += UsrUpdtd;
            NadekoBot.Client.UserBanned += UsrBanned;


            NadekoBot.Client.MessageReceived += async (s, e) =>
            {
                if (e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                if (!SpecificConfigurations.Default.Of(e.Server.Id).SendPrivateMessageOnMention) return;
                try
                {
                    var usr = e.Message.MentionedUsers.FirstOrDefault(u => u != e.User);
                    if (usr?.Status != UserStatus.Offline)
                        return;
                    await e.Channel.SendMessage($"User `{usr.Name}` is offline. PM sent.").ConfigureAwait(false);
                    await usr.SendMessage(
                        $"User `{e.User.Name}` mentioned you on " +
                        $"`{e.Server.Name}` server while you were offline.\n" +
                        $"`Message:` {e.Message.Text}").ConfigureAwait(false);
                }
                catch { }
            };
        }

        private async void UsrBanned(object sender, UserEventArgs e)
        {
            try
            {
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch))
                    return;
                await ch.SendMessage($"`User banned:` **{e.User.Name}** ({e.User.Id})").ConfigureAwait(false);
            }
            catch { }
        }

        public Func<CommandEventArgs, Task> DoFunc() => async e =>
        {
            Channel ch;
            if (!logs.TryRemove(e.Server, out ch))
            {
                logs.TryAdd(e.Server, e.Channel);
                await e.Channel.SendMessage($"**I WILL BEGIN LOGGING SERVER ACTIVITY IN THIS CHANNEL**").ConfigureAwait(false);
                return;
            }

            await e.Channel.SendMessage($"**NO LONGER LOGGING IN {ch.Mention} CHANNEL**").ConfigureAwait(false);
        };

        private async void MsgRecivd(object sender, MessageEventArgs e)
        {
            try
            {
                if (e.Server == null || e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
                    return;
                await ch.SendMessage($"`Type:` **Message received** `Time:` **{DateTime.Now}** `Channel:` **{e.Channel.Name}**\n`{e.User}:` {e.Message.Text}").ConfigureAwait(false);
            }
            catch { }
        }
        private async void MsgDltd(object sender, MessageEventArgs e)
        {
            try
            {
                if (e.Server == null || e.Channel.IsPrivate || e.User?.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
                    return;
                await ch.SendMessage($"`Type:` **Message deleted** `Time:` **{DateTime.Now}** `Channel:` **{e.Channel.Name}**\n`{e.User?.ToString() ?? ("NULL") }:` {e.Message.Text}").ConfigureAwait(false);
            }
            catch { }
        }
        private async void MsgUpdtd(object sender, MessageUpdatedEventArgs e)
        {
            try
            {
                if (e.Server == null || e.Channel.IsPrivate || e.User?.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
                    return;
                await ch.SendMessage($"`Type:` **Message updated** `Time:` **{DateTime.Now}** `Channel:` **{e.Channel.Name}**\n**BEFORE**: `{e.User?.ToString() ?? ("NULL")}:` {e.Before.Text}\n---------------\n**AFTER**: `{e.User}:` {e.After.Text}").ConfigureAwait(false);
            }
            catch { }
        }
        private async void UsrUpdtd(object sender, UserUpdatedEventArgs e)
        {
            try
            {
                Channel ch;
                if (loggingPresences.TryGetValue(e.Server, out ch))
                    if (e.Before.Status != e.After.Status)
                    {
                        await ch.SendMessage($"`[{DateTime.Now:HH:mm:ss}]`**{e.Before.Name}** is now **{e.After.Status}**.").ConfigureAwait(false);
                    }
            }
            catch { }

            try
            {
                if (e.Before.VoiceChannel != null && voiceChannelLog.ContainsKey(e.Before.VoiceChannel))
                {
                    if (e.After.VoiceChannel != e.Before.VoiceChannel)
                        await voiceChannelLog[e.Before.VoiceChannel].SendMessage($"🎼`{e.Before.Name} has left the` {e.Before.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false);
                }
                if (e.After.VoiceChannel != null && voiceChannelLog.ContainsKey(e.After.VoiceChannel))
                {
                    if (e.After.VoiceChannel != e.Before.VoiceChannel)
                        await voiceChannelLog[e.After.VoiceChannel].SendMessage($"🎼`{e.After.Name} has joined the`{e.After.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false);
                }
            }
            catch { }

            try
            {
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch))
                    return;
                string str = $"`Type:` **User updated** `Time:` **{DateTime.Now}** `User:` **{e.Before.Name}**\n";
                if (e.Before.Name != e.After.Name)
                    str += $"`New name:` **{e.After.Name}**";
                else if (e.Before.AvatarUrl != e.After.AvatarUrl)
                    str += $"`New Avatar:` {e.After.AvatarUrl}";
                else
                    return;
                await ch.SendMessage(str).ConfigureAwait(false);
            }
            catch { }
        }

        internal override void Init(CommandGroupBuilder cgb)
        {
<commit_msg>improved .logserver  ref #111<commit_after>﻿using Discord;
using Discord.Commands;
using NadekoBot.Classes;
using NadekoBot.Modules.Permissions.Classes;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading.Tasks;

namespace NadekoBot.Modules.Administration.Commands
{
    internal class LogCommand : DiscordCommand
    {

        private readonly ConcurrentDictionary<Server, Channel> logs = new ConcurrentDictionary<Server, Channel>();
        private readonly ConcurrentDictionary<Server, Channel> loggingPresences = new ConcurrentDictionary<Server, Channel>();
        private readonly ConcurrentDictionary<Channel, Channel> voiceChannelLog = new ConcurrentDictionary<Channel, Channel>();

        private string prettyCurrentTime => $"{DateTime.Now:HH:mm:ss}";

        public LogCommand(DiscordModule module) : base(module)
        {
            NadekoBot.Client.MessageReceived += MsgRecivd;
            NadekoBot.Client.MessageDeleted += MsgDltd;
            NadekoBot.Client.MessageUpdated += MsgUpdtd;
            NadekoBot.Client.UserUpdated += UsrUpdtd;
            NadekoBot.Client.UserBanned += UsrBanned;


            NadekoBot.Client.MessageReceived += async (s, e) =>
            {
                if (e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                if (!SpecificConfigurations.Default.Of(e.Server.Id).SendPrivateMessageOnMention) return;
                try
                {
                    var usr = e.Message.MentionedUsers.FirstOrDefault(u => u != e.User);
                    if (usr?.Status != UserStatus.Offline)
                        return;
                    await e.Channel.SendMessage($"User `{usr.Name}` is offline. PM sent.").ConfigureAwait(false);
                    await usr.SendMessage(
                        $"User `{e.User.Name}` mentioned you on " +
                        $"`{e.Server.Name}` server while you were offline.\n" +
                        $"`Message:` {e.Message.Text}").ConfigureAwait(false);
                }
                catch { }
            };
        }

        private async void UsrBanned(object sender, UserEventArgs e)
        {
            try
            {
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch))
                    return;
                await ch.SendMessage($"`User banned:` **{e.User.Name}** ({e.User.Id})").ConfigureAwait(false);
            }
            catch { }
        }

        public Func<CommandEventArgs, Task> DoFunc() => async e =>
        {
            Channel ch;
            if (!logs.TryRemove(e.Server, out ch))
            {
                logs.TryAdd(e.Server, e.Channel);
                await e.Channel.SendMessage($"**I WILL BEGIN LOGGING SERVER ACTIVITY IN THIS CHANNEL**").ConfigureAwait(false);
                return;
            }

            await e.Channel.SendMessage($"**NO LONGER LOGGING IN {ch.Mention} CHANNEL**").ConfigureAwait(false);
        };

        private async void MsgRecivd(object sender, MessageEventArgs e)
        {
            try
            {
                if (e.Server == null || e.Channel.IsPrivate || e.User.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
                    return;
                await ch.SendMessage(
$@"🕔`[{prettyCurrentTime}]` **New Message** `{e.Channel.Mention}`
👤`{e.User?.ToString() ?? ("NULL")}` {e.Message.Text}").ConfigureAwait(false);
            }
            catch { }
        }
        private async void MsgDltd(object sender, MessageEventArgs e)
        {
            try
            {
                if (e.Server == null || e.Channel.IsPrivate || e.User?.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
                    return;
                await ch.SendMessage(
$@"🕔`[{prettyCurrentTime}]` **Message** 🚮 `{e.Channel.Mention}`
👤`{e.User?.ToString() ?? ("NULL")}` {e.Message.Text}").ConfigureAwait(false);
            }
            catch { }
        }
        private async void MsgUpdtd(object sender, MessageUpdatedEventArgs e)
        {
            try
            {
                if (e.Server == null || e.Channel.IsPrivate || e.User?.Id == NadekoBot.Client.CurrentUser.Id)
                    return;
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch) || e.Channel == ch)
                    return;
                await ch.SendMessage(
$@"🕔`[{prettyCurrentTime}]` **Message** 📝 `{e.Channel.Mention}`👤`{e.User?.ToString() ?? ("NULL")}`
\\t`Old:` {e.Before.Text}
\\t`New:` {e.After.Text}").ConfigureAwait(false);
            }
            catch { }
        }
        private async void UsrUpdtd(object sender, UserUpdatedEventArgs e)
        {
            try
            {
                Channel ch;
                if (loggingPresences.TryGetValue(e.Server, out ch))
                    if (e.Before.Status != e.After.Status)
                    {
                        await ch.SendMessage($"`[{DateTime.Now:HH:mm:ss}]`**{e.Before.Name}** is now **{e.After.Status}**.").ConfigureAwait(false);
                    }
            }
            catch { }

            try
            {
                if (e.Before.VoiceChannel != null && voiceChannelLog.ContainsKey(e.Before.VoiceChannel))
                {
                    if (e.After.VoiceChannel != e.Before.VoiceChannel)
                        await voiceChannelLog[e.Before.VoiceChannel].SendMessage($"🎼`{e.Before.Name} has left the` {e.Before.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false);
                }
                if (e.After.VoiceChannel != null && voiceChannelLog.ContainsKey(e.After.VoiceChannel))
                {
                    if (e.After.VoiceChannel != e.Before.VoiceChannel)
                        await voiceChannelLog[e.After.VoiceChannel].SendMessage($"🎼`{e.After.Name} has joined the`{e.After.VoiceChannel.Mention} `voice channel.`").ConfigureAwait(false);
                }
            }
            catch { }

            try
            {
                Channel ch;
                if (!logs.TryGetValue(e.Server, out ch))
                    return;
                string str = $"`Type:` **User updated** `Time:` **{DateTime.Now}** `User:` **{e.Before.Name}**\n";
                if (e.Before.Name != e.After.Name)
                    str += $"`New name:` **{e.After.Name}**";
                else if (e.Before.AvatarUrl != e.After.AvatarUrl)
                    str += $"`New Avatar:` {e.After.AvatarUrl}";
                else if (!e.Before.Roles.SequenceEqual(e.After.Roles))
                {
                    str += $"`Roles Changed:` {string.Join(", ", e.Before.Roles)} => {string.Join(", ", e.After.Roles)}";
                }
                else
                    return;
                await ch.SendMessage(str).ConfigureAwait(false);
            }
            catch { }
        }

        internal override void Init(CommandGroupBuilder cgb)
        {

{'fraction_non_alphanumeric': 0.13216324804398394, 'fraction_numerical': 0.00021146119687037428, 'mean_word_length': 1.6391369047619047, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2399427', 'n_tokens_mistral': 4089, 'n_tokens_neox': 3896, 'n_words': 736}