private void JoinCount_Changed(object sender, JoinedCountChangedEventArgs e)
        {
            PokemonRaidPost         post        = null;
            IBotServerConfiguration guildConfig = null;
            PokemonRaidJoinedUser   joinedUser  = null;

            if (sender is PokemonRaidPost)
            {
                post        = (PokemonRaidPost)sender;
                guildConfig = Config.GetServerConfig(post.GuildId, ChatTypes.Discord);
            }
            else if (sender is PokemonRaidJoinedUser)
            {
                joinedUser  = (PokemonRaidJoinedUser)sender;
                guildConfig = Config.GetServerConfig(joinedUser.GuildId, ChatTypes.Discord);
                //var guild = bot.Guil
                post = guildConfig.Posts.FirstOrDefault(x => x.UniqueId == joinedUser.PostId);
            }

            if (post != null)
            {
                List <Task> tasks  = new List <Task>();
                var         parser = GetParser(guildConfig);

                var joinstr = parser.Language.Strings["joining"];

                if (e.ChangeType == JoinCountChangeType.Remove || (e.ChangeType == JoinCountChangeType.Change && e.Count < 0))
                {
                    joinstr = parser.Language.Strings["quitting"];
                }

                string message = string.Format(parser.Language.Formats["directMessage"],
                                               e.Count,
                                               joinstr,
                                               post.PokemonName,
                                               e.ArriveTime.HasValue && !joinstr.Equals(parser.Language.Strings["quitting"]) ? string.Format(parser.Language.Formats["postjoinTime"], e.ArriveTime.Value.ToString("t")) : "",
                                               e.UserName);

                var usersToDM = new List <ulong>();
                if (post.UserId != e.UserId)
                {
                    usersToDM.Add(post.UserId);
                }
                usersToDM.AddRange(post.JoinedUsers.Where(x => x.Id != e.UserId && x.Id != post.UserId).Select(x => x.Id));

                foreach (var id in usersToDM)
                {
                    var user = bot.GetUser(id);

                    if (user != default(SocketUser))
                    {
                        tasks.Add(DirectMessageUser(new DiscordChatUser(user), $"{message}\n{parser.Language.Strings["dmStop"]}"));//TODO
                    }
                }
                Task.WaitAll(tasks.ToArray());
            }
        }
        private async Task Join()
        {
            string num = null;
            string poke = null;
            string time = null;
            bool isMore = false, isLess = false;

            int number = 0;

            if (Command.Count() == 2)
            {//just have a number or pokemon;
                if (!int.TryParse(Command[1], out number))
                {
                    poke = Command[1];
                    number = 1;
                    num = "1";
                }
                else
                {
                    poke = "";
                    num = Command[1];
                }
            }
            else if (Command.Count() >= 3)
            {
                if (!int.TryParse(Command[2], out number))
                {
                    if (!int.TryParse(Command[1], out number))
                    {
                        await Handler.MakeCommandMessage(Message.Channel, string.Format(Parser.Language.Formats["commandInvalidNumber"], Command[2]));
                        return;
                    }
                    else
                    {
                        num = Command[1];
                        poke = Command[2];
                    }
                }
                else
                {
                    poke = Command[1];
                    num = Command[2];
                }

                time = string.Join(" ", Command.Skip(3));
            }
            else
            {
                num = "1";
                number = 1;
                poke = "";
            }

            if (num.StartsWith("+"))
            {
                isMore = true;
            }
            else if (num.StartsWith("-"))
            {
                isLess = true;
                number = Math.Abs(number);
            }

            if (number == 0 && Command.Count() > 2)
            {
                await Handler.MakeCommandMessage(Message.Channel, string.Format(Parser.Language.Formats["commandInvalidNumber"], Command[2]));
                return;
            }

            var post = GetPost(poke);
            if (!post.IsExisting)
            {
                await Handler.MakeCommandMessage(Message.Channel, string.Format(Parser.Language.Formats["commandPostNotFound"], poke));// $"Raid post with Id \"{Command[1]}\" does not exist.");
                return;
            }

            var joinedUser = post.JoinedUsers.FirstOrDefault(x => x.Id == Message.User.Id);
            if (joinedUser == null)
            {
                joinedUser = new PokemonRaidJoinedUser(Message.User.Id, Message.Server.Id, post.UniqueId, Message.User.Name, number);
                post.JoinedUsers.Add(joinedUser);
            }
            else if (isMore)
                joinedUser.PeopleCount += number;
            else if (isLess)
                joinedUser.PeopleCount -= number;
            else
                joinedUser.PeopleCount = number;

            if (joinedUser.PeopleCount <= 0) post.JoinedUsers.Remove(joinedUser);

            Parser.ParseTimespanFull(ref time, out TimeSpan? ts1, out TimeSpan? ts2, out DateTime? dt1, out DateTime? dt2);

            joinedUser.ArriveTime = dt2 ?? dt1 ?? (DateTime.Now + (ts1 ?? ts2)) ?? joinedUser.ArriveTime;

            await Handler.MakePost(post, Parser);
            Config.Save();
        }