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)); } }
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())); }
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(); }
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)); }
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); } }