예제 #1
0
        public static async Task MessageTextReactionEventHandlerAsync(KioskAppShard shard, MessageCreateEventArgs e)
        {
            if (e.Author.IsBot || e.Channel.IsPrivate || string.IsNullOrWhiteSpace(e.Message?.Content))
            {
                return;
            }

            if (e.Message.Content.StartsWith(shard.SharedData.GetGuildPrefix(e.Guild.Id)))
            {
                return;
            }

            if (shard.SharedData.BlockedChannels.Contains(e.Channel.Id) || shard.SharedData.BlockedUsers.Contains(e.Author.Id))
            {
                return;
            }

            if (!e.Channel.PermissionsFor(e.Guild.CurrentMember).HasFlag(Permissions.SendMessages))
            {
                return;
            }

            if (!shard.SharedData.TextReactions.TryGetValue(e.Guild.Id, out ConcurrentHashSet <TextReaction> treactions))
            {
                return;
            }

            TextReaction tr = treactions?.FirstOrDefault(r => r.IsMatch(e.Message.Content));

            if (!tr?.IsCooldownActive() ?? false)
            {
                await e.Channel.SendMessageAsync(tr.Response.Replace("%user%", e.Author.Mention));
            }
        }
예제 #2
0
        public Task ListAsync(CommandContext ctx,
                              [RemainingText, Description("Specific trigger.")] string trigger)
        {
            if (!this.Shared.TextReactions.TryGetValue(ctx.Guild.Id, out ConcurrentHashSet <TextReaction> treactions) || !treactions.Any())
            {
                throw new CommandFailedException("This guild has no text reactions registered.");
            }

            TextReaction tr = treactions.SingleOrDefault(t => t.IsMatch(trigger));

            if (tr is null)
            {
                throw new CommandFailedException("None of the reactions respond to such trigger.");
            }

            var emb = new DiscordEmbedBuilder {
                Title       = "Text reaction that matches the trigger",
                Description = string.Join(" | ", tr.TriggerStrings),
                Color       = this.ModuleColor
            };

            emb.AddField("ID", tr.Id.ToString(), inline: true);
            emb.AddField("Response", tr.Response, inline: true);
            return(ctx.RespondAsync(embed: emb.Build()));
        }
예제 #3
0
        public static async Task MessageTextReactionEventHandlerAsync(TheGodfatherShard shard, MessageCreateEventArgs e)
        {
            if (e.Author.IsBot || e.Channel.IsPrivate || string.IsNullOrWhiteSpace(e.Message?.Content))
            {
                return;
            }

            if (shard.SharedData.BlockedChannels.Contains(e.Channel.Id) || shard.SharedData.BlockedUsers.Contains(e.Author.Id))
            {
                return;
            }

            if (!e.Channel.PermissionsFor(e.Guild.CurrentMember).HasFlag(Permissions.SendMessages))
            {
                return;
            }

            if (!shard.SharedData.TextReactions.ContainsKey(e.Guild.Id))
            {
                return;
            }

            TextReaction tr = shard.SharedData.TextReactions[e.Guild.Id]?.FirstOrDefault(r => r.IsMatch(e.Message.Content));

            if (tr != null && !tr.IsCooldownActive())
            {
                await e.Channel.SendMessageAsync(tr.Response.Replace("%user%", e.Author.Mention));
            }
        }
    void IterateScenes()
    {
        var assets = AssetDatabase.FindAssets("t:Scene");

        for (int i = 0; i < assets.Length; ++i)
        {
            EditorUtility.DisplayProgressBar("Processing Scenes", i.ToString() + "/" + assets.Length, (float)i / assets.Length);
            var path = AssetDatabase.GUIDToAssetPath(assets[i]);
            EditorSceneManager.OpenScene(path, OpenSceneMode.Single);

            // UI Text
            var textObjects = Object.FindObjectsOfType <UnityEngine.UI.Text> ();
            foreach (var to in textObjects)
            {
                if (!string.IsNullOrEmpty(to.text))
                {
                    AddKey(to.text, path + "::" + GetGameObjectPath(to.gameObject) + "/Text:text");
                }
            }

            // UI Inout
            var inputObjects = Object.FindObjectsOfType <UnityEngine.UI.InputField> ();
            foreach (var io in inputObjects)
            {
                if (!string.IsNullOrEmpty(io.text))
                {
                    AddKey(io.text, path + "::" + GetGameObjectPath(io.gameObject) + "/InputField:text");
                }
            }

            // Text Mesh
            var textMeshObjects = Object.FindObjectsOfType <UnityEngine.TextMesh> ();
            foreach (var tm in textMeshObjects)
            {
                if (!string.IsNullOrEmpty(tm.text))
                {
                    AddKey(tm.text, path + "::" + GetGameObjectPath(tm.gameObject) + "/TextMesh:text");
                }
            }

            // Reaction Collection - specific to this project. We should do relfection here for user scripts.
            var reactions = Object.FindObjectsOfType <ReactionCollection> ();
            foreach (var r in reactions)
            {
                foreach (var currentReaction in r.reactions)
                {
                    TextReaction tr = currentReaction as TextReaction;
                    if (tr)
                    {
                        AddKey(tr.message, path + "::" + GetGameObjectPath(r.gameObject) + "/TextReaction:message");
                    }
                }
            }
        }

        EditorUtility.ClearProgressBar();

        UpdateDB();
    }
예제 #5
0
        public static async Task <IReadOnlyDictionary <ulong, List <TextReaction> > > GetTextReactionsForAllGuildsAsync(this DBService db)
        {
            var treactions = new Dictionary <ulong, List <TextReaction> >();

            await db.ExecuteCommandAsync(async (cmd) => {
                cmd.CommandText = "SELECT id, gid, trigger, response FROM gf.text_reactions;";

                using (var reader = await cmd.ExecuteReaderAsync().ConfigureAwait(false)) {
                    while (await reader.ReadAsync().ConfigureAwait(false))
                    {
                        ulong gid = (ulong)(long)reader["gid"];
                        if (treactions.ContainsKey(gid))
                        {
                            if (treactions[gid] == null)
                            {
                                treactions[gid] = new List <TextReaction>();
                            }
                        }
                        else
                        {
                            treactions.Add(gid, new List <TextReaction>());
                        }

                        int id          = (int)reader["id"];
                        string trigger  = (string)reader["trigger"];
                        string response = (string)reader["response"];

                        TextReaction conflict = treactions[gid].FirstOrDefault(tr => tr.Response == response);
                        if (conflict != null)
                        {
                            conflict.AddTrigger(trigger, isRegex: true);
                        }
                        else
                        {
                            treactions[gid].Add(new TextReaction(id, trigger, response, isRegex: true));
                        }
                    }
                }
            });

            return(new ReadOnlyDictionary <ulong, List <TextReaction> >(treactions));
        }
예제 #6
0
        private async Task AddTextReactionAsync(CommandContext ctx, string trigger, string response, bool regex)
        {
            if (string.IsNullOrWhiteSpace(response))
            {
                throw new InvalidCommandUsageException("Response missing or invalid.");
            }

            if (trigger.Length < 2 || response.Length < 2)
            {
                throw new CommandFailedException("Trigger or response cannot be shorter than 2 characters.");
            }

            if (trigger.Length > 120 || response.Length > 120)
            {
                throw new CommandFailedException("Trigger or response cannot be longer than 120 characters.");
            }

            if (!this.Shared.TextReactions.ContainsKey(ctx.Guild.Id))
            {
                this.Shared.TextReactions.TryAdd(ctx.Guild.Id, new ConcurrentHashSet <TextReaction>());
            }

            if (regex && !trigger.IsValidRegex())
            {
                throw new CommandFailedException($"Trigger {Formatter.Bold(trigger)} is not a valid regular expression.");
            }

            if (this.Shared.GuildHasTextReaction(ctx.Guild.Id, trigger))
            {
                throw new CommandFailedException($"Trigger {Formatter.Bold(trigger)} already exists.");
            }

            if (this.Shared.Filters.TryGetValue(ctx.Guild.Id, out ConcurrentHashSet <Administration.Common.Filter> filters) && filters.Any(f => f.Trigger.IsMatch(trigger)))
            {
                throw new CommandFailedException($"Trigger {Formatter.Bold(trigger)} collides with an existing filter in this guild.");
            }

            int id;

            using (DatabaseContext db = this.Database.CreateContext()) {
                DatabaseTextReaction dbtr = db.TextReactions.FirstOrDefault(tr => tr.GuildId == ctx.Guild.Id && tr.Response == response);
                if (dbtr is null)
                {
                    dbtr = new DatabaseTextReaction {
                        GuildId  = ctx.Guild.Id,
                        Response = response,
                    };
                    db.TextReactions.Add(dbtr);
                    await db.SaveChangesAsync();
                }

                dbtr.DbTriggers.Add(new DatabaseTextReactionTrigger {
                    ReactionId = dbtr.Id, Trigger = regex ? trigger : Regex.Escape(trigger)
                });

                await db.SaveChangesAsync();

                id = dbtr.Id;
            }

            var eb = new StringBuilder();

            ConcurrentHashSet <TextReaction> treactions = this.Shared.TextReactions[ctx.Guild.Id];
            TextReaction reaction = treactions.FirstOrDefault(tr => tr.Response == response);

            if (reaction is null)
            {
                if (!treactions.Add(new TextReaction(id, trigger, response, regex)))
                {
                    throw new CommandFailedException($"Failed to add trigger {Formatter.Bold(trigger)}.");
                }
            }
            else
            {
                if (!reaction.AddTrigger(trigger, regex))
                {
                    throw new CommandFailedException($"Failed to add trigger {Formatter.Bold(trigger)}.");
                }
            }

            DiscordChannel logchn = this.Shared.GetLogChannelForGuild(ctx.Client, ctx.Guild);

            if (!(logchn is null))
            {
                var emb = new DiscordEmbedBuilder {
                    Title = "New text reaction added",
                    Color = this.ModuleColor
                };
                emb.AddField("User responsible", ctx.User.Mention, inline: true);
                emb.AddField("Invoked in", ctx.Channel.Mention, inline: true);
                emb.AddField("Response", response, inline: true);
                emb.AddField("Trigger", trigger);
                if (eb.Length > 0)
                {
                    emb.AddField("With errors", eb.ToString());
                }
                await logchn.SendMessageAsync(embed : emb.Build());
            }

            if (eb.Length > 0)
            {
                await this.InformFailureAsync(ctx, eb.ToString());
            }
            else
            {
                await this.InformAsync(ctx, "Successfully added given text reaction.", important : false);
            }
        }