Example #1
0
        async Task HandleMudaeMessageAsync(SocketUserMessage message)
        {
            if (!message.Embeds.Any())
            {
                return;
            }

            var guild = ((IGuildChannel)message.Channel).Guild;
            var embed = message.Embeds.First();

            // character must not belong to another user
            if (embed.Footer.HasValue && embed.Footer.Value.Text.StartsWith("Belongs to", StringComparison.OrdinalIgnoreCase))
            {
                return;
            }

            //
            if (!embed.Author.HasValue || embed.Author.Value.IconUrl != null)
            {
                return;
            }

            var character = embed.Author.Value.Name.Trim().ToLowerInvariant();
            var anime     = embed.Description.Split('\n')[0].Trim().ToLowerInvariant();

            // matching
            var matched = false;

            matched |= _config.WishedCharacterRegex?.IsMatch(character) ?? false;
            matched |= _config.WishedAnimeRegex?.IsMatch(anime) ?? false;

            // ensure we can claim right now
            if (matched)
            {
                var state = _state.Get(guild.Id);

                if (!state.CanClaim && DateTime.Now < state.ClaimReset)
                {
                    Log.Warning($"{guild} {message.Channel}: Found character '{character}' but cannot claim it due to cooldown.");
                    return;
                }
            }

            if (matched)
            {
                Log.Warning($"{guild} {message.Channel}: Found character '{character}', trying marriage.");

                // reactions may not have been attached when we received this message
                // remember this message so we can attach an appropriate reaction later when we receive it
                _claimQueue[message.Id] = message;
            }
            else
            {
                Log.Info($"{guild} {message.Channel}: Ignored character '{character}', not wished.");
            }
        }
Example #2
0
        async Task RunRollAsync(SocketGuild guild, CancellationToken cancellationToken = default)
        {
            while (!cancellationToken.IsCancellationRequested)
            {
                var state = _state.Get(guild.Id);

                var interval = _config.RollIntervalOverride;

                if (interval == null)
                {
                    if (!_config.RollEnabled || state.RollsLeft <= 0)
                    {
                        await Task.Delay(TimeSpan.FromSeconds(1), cancellationToken);

                        continue;
                    }

                    interval = new TimeSpan((state.RollsReset - DateTime.Now).Ticks / state.RollsLeft);
                }

                foreach (var channel in guild.TextChannels)
                {
                    if (!_config.BotChannelIds.Contains(channel.Id))
                    {
                        continue;
                    }

                    using (channel.EnterTypingState())
                    {
                        await Task.Delay(_config.RollTypingDelay, cancellationToken);

                        try
                        {
                            await channel.SendMessageAsync(_config.RollCommand);

                            --state.RollsLeft;

                            Log.Debug($"{channel.Guild} #{channel}: Rolled '{_config.RollCommand}'.");
                        }
                        catch (Exception e)
                        {
                            Log.Warning($"{channel.Guild} #{channel}: Could not send roll command '{_config.RollCommand}'.", e);
                        }
                    }

                    break;
                }

                if (interval < TimeSpan.FromSeconds(5))
                {
                    interval = TimeSpan.FromSeconds(5);
                }

                await Task.Delay(interval.Value, cancellationToken);
            }
        }
Example #3
0
        async Task HandleReactionAsync(Cacheable <IUserMessage, ulong> cacheable, ISocketMessageChannel channel, SocketReaction reaction)
        {
            if (!_config.ClaimEnabled)
            {
                return;
            }

            if (!(channel is IGuildChannel guildChannel))
            {
                return;
            }

            // channel must be enabled for claiming
            if (!_config.BotChannelIds.Contains(channel.Id))
            {
                return;
            }

            // retrieve message
            if (!_messageCache.TryGetValue(reaction.MessageId, out var message))
            {
                return;
            }

            // reactor must be mudae
            var user = reaction.User.IsSpecified ? reaction.User.Value : _client.GetUser(reaction.UserId);

            if (user == null || !MudaeInfo.IsMudae(user))
            {
                return;
            }

            // reaction must be kakera
            if (!_kakeraMap.TryGetValue(reaction.Emote.Name, out var kakera))
            {
                return;
            }

            // kakera must be configured to be claimed
            if (!_config.KakeraTargets.Contains(kakera))
            {
                return;
            }

            // must have enough kakera power to claim this kakera
            var state = _state.Get(guildChannel.GuildId);

            if (!state.CanKakera)
            {
                return;
            }

            // claim kakera
            await Task.Delay(_config.KakeraClaimDelay);

            await message.AddReactionAsync(reaction.Emote);

            // update state
            state.KakeraPower -= state.KakeraConsumption;
        }
Example #4
0
        async Task HandleMudaeMessageAsync(IUserMessage message)
        {
            if (!message.Embeds.Any())
            {
                return;
            }

            var guild = ((IGuildChannel)message.Channel).Guild;
            var embed = message.Embeds.First();

            if (embed.Footer.HasValue)
            {
                // character must not belong to another user
                if (embed.Footer.Value.Text.StartsWith("Belongs to", StringComparison.OrdinalIgnoreCase))
                {
                    return;
                }

                // message must not be $im
                if (_imFooterRegex.IsMatch(embed.Footer.Value.Text))
                {
                    return;
                }
            }

            //
            if (!embed.Author.HasValue || embed.Author.Value.IconUrl != null)
            {
                return;
            }


            var description = embed.Description.Split('\n');
            var character   = embed.Author.Value.Name.Trim().ToLowerInvariant();
            var anime       = description[0].Trim().ToLowerInvariant();
            var KakeraValue = 0;

            //if length >= 2 then description includes additional info
            if (description.Length >= 2)
            {
                //46983... is emoji symbol
                if (description[description.Length - 1].Contains("469835869059153940"))
                {
                    String KakeraValueString = new String(description[description.Length - 1].SkipWhile(c => !Char.IsDigit(c)).TakeWhile(Char.IsDigit).ToArray());
                    KakeraValue = Convert.ToInt32(KakeraValueString);
                }
            }

            // matching by character and name
            var matched         = false;
            var kakeraThreshold = _config.KakeraThreshold;

            matched |= _config.WishedCharacterRegex?.IsMatch(character) ?? false;
            matched |= _config.WishedAnimeRegex?.IsMatch(anime) ?? false;

            // matching by wishlist
            if (message.Content.StartsWith("Wished by"))
            {
                matched |= message.GetUserIds().Any(_config.ClaimWishlistUserIds.Contains);
            }

            if (matched)
            {
                var state = _state.Get(guild.Id);

                // ensure we can claim right now
                if (!state.CanClaim && DateTime.Now < state.ClaimReset)
                {
                    Log.Warning($"{guild} {message.Channel}: Found character '{character}' but cannot claim it due to cooldown.");
                    return;
                }
                //check and see if character's kakera value is at or above threshold
                if (KakeraValue >= kakeraThreshold)
                {
                    Log.Warning($"{guild} {message.Channel}: Found character '{character}', trying marriage.");
                }
                else
                {
                    Log.Warning($"{guild} {message.Channel}: Found character '{character}' but cannot claim it due to character's kakera value '{KakeraValue}' not greater than or equal to threshold. '{kakeraThreshold}'");
                    return;
                }
                // reactions may not have been attached when we received this message
                // remember this message so we can attach an appropriate reaction later when we receive it
                _claimQueue[message.Id] = new ClaimQueueItem
                {
                    Message   = message,
                    Character = new CharacterInfo(character, anime),
                    Measure   = new MeasureContext()
                };
            }
            else
            {
                Log.Info($"{guild} #{message.Channel}: Ignored character '{character}', not wished.");
            }
        }