protected Personnage(DiscordMember me, DiscordGuildEmoji emoji) { Id = me.Id; Emoji = emoji; Alive = true; //NbPoints = GetNbPoints(me.Id); // TODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODOTODO ChannelV = Global.Game.Guild.CreateChannelAsync(Me.Username.RemoveSpecialChars(), ChannelType.Voice, Global.Game.DiscordChannels[GameChannel.PersoGroup]).GetAwaiter().GetResult(); ChannelT = Global.Game.Guild.CreateChannelAsync(Me.Username.RemoveSpecialChars(), ChannelType.Text, Global.Game.DiscordChannels[GameChannel.PersoGroup]).GetAwaiter().GetResult(); ChannelT.AddOverwriteAsync(Me, GameBuilder.UsrPerms); ChannelV.AddOverwriteAsync(Me, GameBuilder.UsrPerms); Global.Game.DiscordChannels[GameChannel.TownText].AddOverwriteAsync(Me, GameBuilder.UsrPerms); Global.Game.DiscordChannels[GameChannel.TownVoice].AddOverwriteAsync(Me, GameBuilder.UsrPerms); var embed = new DiscordEmbedBuilder { Title = Global.Game.Texts.GameRoles.RoleString, Color = Color.InfoColor }; embed.AddField("Role", ToString()); ChannelT.SendMessageAsync(embed: embed.Build()).GetAwaiter().GetResult(); me.PlaceInAsync(ChannelV); }
public async Task CreateEmote(CommandContext ctx, [Description("emote name.\n" + "Default: will give a png filename if empty.")] string emoteName = "") { if (ctx.Channel.IsPrivate) { await ctx.RespondAsync(":x: This command is only for server use."); return; } var emotepath = "D:\\source\\emotes\\temp\\"; await ctx.TriggerTypingAsync(); if (ctx.Message.Attachments == null) { await ctx.RespondAsync("No new emote attached. Cancelling."); } else { try { DiscordAttachment newemote = ctx.Message.Attachments[0]; string filetype = newemote.FileName.Substring(newemote.FileName.LastIndexOf(".", StringComparison.Ordinal), 4); bool isImage = filetype is ".png" or ".gif"; if (!isImage) { await ctx.RespondAsync("Wrong file type. Cancelling."); } else if (newemote.FileSize > 256 * 1024) { await ctx.RespondAsync("New emote file size more that 256Kb. Cancelling."); } else { if (emoteName.Length == 0) { emoteName = newemote.FileName.Substring(0, newemote.FileName.LastIndexOf(".", StringComparison.Ordinal)); } await FileHandler.DownloadUrlFile(newemote.Url, emotepath, ctx.Client, $"{emoteName}{filetype}"); await Task.Delay(1000); // little delay for our file stream await using (FileStream fileStream = File.OpenRead($"{emotepath}{emoteName}{filetype}")) { DiscordGuildEmoji createdEmote = await ctx.Guild.CreateEmojiAsync(emoteName, fileStream); await ctx.RespondAsync($"Created new emote: {createdEmote}"); fileStream.Close(); } File.Delete($"{emotepath}{emoteName}{filetype}"); } } catch { // ignored } } }
public async Task AddAsync(CommandContext ctx, [Description("desc-emoji-name")] string name, [Description("desc-emoji-url")] Uri?url = null) { if (string.IsNullOrWhiteSpace(name) || name.Length < 2 || name.Length > DiscordLimits.EmojiNameLimit) { throw new InvalidCommandUsageException(ctx, "cmd-err-emoji-name", 2, DiscordLimits.EmojiNameLimit); } if (url is null) { if (!ctx.Message.Attachments.Any() || !Uri.TryCreate(ctx.Message.Attachments[0].Url, UriKind.Absolute, out url)) { throw new InvalidCommandUsageException(ctx, "cmd-err-image-url"); } } if (!await url.ContentTypeHeaderIsImageAsync(DiscordLimits.EmojiSizeLimit)) { throw new InvalidCommandUsageException(ctx, "cmd-err-image-url-fail", DiscordLimits.EmojiSizeLimit.ToMetric()); } try { using Stream stream = await HttpService.GetStreamAsync(url); DiscordGuildEmoji emoji = await ctx.Guild.CreateEmojiAsync(name, stream, reason : ctx.BuildInvocationDetailsString()); await ctx.InfoAsync(this.ModuleColor, "fmt-emoji-add", emoji.GetDiscordName()); } catch (WebException e) { throw new CommandFailedException(ctx, e, "err-url-image-fail"); } }
public async Task Weekly(CommandContext ctx, params DiscordEmoji[] emoji) { //learn how to auto post every friday //emojis for reaction var dpsEmoji = DiscordGuildEmoji.FromName(ctx.Client, ":dps:"); var tankEmoji = DiscordGuildEmoji.FromName(ctx.Client, ":tank:"); var supportEmoji = DiscordGuildEmoji.FromName(ctx.Client, ":support:"); var weeklySchedule = await ctx.Channel.SendMessageAsync("<@&[Player Role ID]> <@&[Coach Role ID]> \nPlease react for scheduling:\n" + "(Tank =" + tankEmoji + ")(DPS =" + dpsEmoji + ")(Support =" + supportEmoji + ")(myPP = :eggplant:)"); for (int i = 3; i < 10; i++) { DayOfWeek dayName = DateTime.Today.AddDays(i).DayOfWeek; string monthNum = DateTime.Today.AddDays(i).Month.ToString(); string dayNum = DateTime.Today.AddDays(i).Day.ToString(); var scheduleMessage = await ctx.Channel.SendMessageAsync("React if you can vod review/scrim " + dayName + " [" + monthNum + "/" + dayNum + "] between 8-10pm ET*"); await scheduleMessage.CreateReactionAsync(tankEmoji); await scheduleMessage.CreateReactionAsync(dpsEmoji); await scheduleMessage.CreateReactionAsync(supportEmoji); } await ctx.Channel.SendMessageAsync("*7-9pm CT, 6-8pm MT, 5-7pm PT"); await weeklySchedule.PinAsync(); }
protected Personnage(Game game, DiscordMember me, DiscordGuildEmoji emoji) { Me = me; Emoji = emoji; Alive = true; Game = game; var name = Me.Username.RemoveSpecialChars() ?? "jesaispasquoi"; ChannelV = Game.Guild.CreateChannelAsync(Me.Username.RemoveSpecialChars(), ChannelType.Voice, Game.DiscordChannels[GameChannel.PersoGroup]).GetAwaiter().GetResult(); ChannelT = Game.Guild.CreateChannelAsync(Me.Username.RemoveSpecialChars(), ChannelType.Text, Game.DiscordChannels[GameChannel.PersoGroup]).GetAwaiter().GetResult(); // ReSharper disable once VirtualMemberCallInConstructor ChannelT.AddOverwriteAsync(Me, GameBuilder.UsrPerms); ChannelV.AddOverwriteAsync(Me, GameBuilder.UsrPerms); Game.DiscordChannels[GameChannel.TownText].AddOverwriteAsync(Me, GameBuilder.UsrPerms); Game.DiscordChannels[GameChannel.TownVoice].AddOverwriteAsync(Me, GameBuilder.UsrPerms); var embed = new DiscordEmbedBuilder { Title = Game.Texts.RoleString, Color = Color.InfoColor }; embed.AddField("Role", ToString()); ChannelT.SendMessageAsync(embed: embed.Build()).GetAwaiter().GetResult(); me.PlaceInAsync(ChannelV); }
public async Task RemoveEmoji(CommandContext c, [Description("Name of the emoji to remove")] string name) { if (c.Guild == null) { throw new InvalidOperationException("You cannot modify emojis in a DM."); } IReadOnlyList <DiscordGuildEmoji> emojis = await c.Guild.GetEmojisAsync(); if (!emojis.Any()) { await c.RespondAsync("You have no emoji on this server to remove."); return; } DiscordGuildEmoji toRemove = emojis.FirstOrDefault(x => x.Name == name); if (toRemove == null) { await c.RespondAsync("I did not find any emoji by that name on this server to remove."); return; } try { await c.Guild.DeleteEmojiAsync(toRemove); } catch (BadRequestException) { await c.RespondAsync("I failed to remove the emoji. Discord gave me a bad response."); return; } await c.RespondAsync("Emoji successfully removed!"); }
public async Task InstallAsync(CommandContext ctx, string name, [RemainingText] string url = null) { url = string.IsNullOrWhiteSpace(url) ? null : url; if (url == null && !ctx.Message.Attachments.Any()) { throw new ArgumentNullException(nameof(url), "Need to specify a URL or add an attachment."); } if (url == null) { var att = ctx.Message.Attachments.First(); var fn = att.FileName.ToLowerInvariant(); if (!(fn.EndsWith(".png") || fn.EndsWith(".gif"))) { throw new ArgumentException("Attachment needs to be a GIF or PNG image.", nameof(url)); } url = att.Url; } DiscordGuildEmoji nemoji = null; using (var res = await this.Http.GetAsync(url).ConfigureAwait(false)) using (var rss = await res.Content.ReadAsStreamAsync().ConfigureAwait(false)) nemoji = await ctx.Guild.CreateEmojiAsync(name, rss, reason : $"{ctx.User.Username}#{ctx.User.Discriminator} ({ctx.User.Id}) installed a meme.").ConfigureAwait(false); await ctx.RespondAsync($"{DiscordEmoji.FromName(ctx.Client, ":msokhand:")} {nemoji}").ConfigureAwait(false); }
internal static string ConvertEmoji(DiscordGuildEmoji Emoji) { string StringEmoji = "<"; StringEmoji += Emoji.GetDiscordName(); StringEmoji += Emoji.Id; StringEmoji += ">"; return(StringEmoji); }
[RequireChannel(ChannelCheckMode.Any, "confirmed-scrims", "scrim-vod-scheduling")] //only these named channels will post the command public async Task Confirmed(CommandContext ctx, int startTime) { //create emojis for reaction emojis var dpsEmoji = DiscordGuildEmoji.FromName(ctx.Client, ":dps:"); var tankEmoji = DiscordGuildEmoji.FromName(ctx.Client, ":tank:"); var supportEmoji = DiscordGuildEmoji.FromName(ctx.Client, ":support:"); //variables for interactivity, dates, and time var interactivity = ctx.Client.GetInteractivity(); DayOfWeek currentDay = DateTime.Today.DayOfWeek; string monthNum = DateTime.Today.Month.ToString(); string dayNum = DateTime.Today.Day.ToString(); var finishTime = startTime + 2; //prompt user for input and store into separate variables await ctx.Member.SendMessageAsync("Input team name: "); var teamName = await interactivity.WaitForMessageAsync(x => x.Author == ctx.Member); await ctx.Member.SendMessageAsync("Input team SR: "); var teamSR = await interactivity.WaitForMessageAsync(x => x.Author == ctx.Member); await ctx.Member.SendMessageAsync("Team Contact: "); var teamContact = await interactivity.WaitForMessageAsync(x => x.Author == ctx.Member); await ctx.Member.SendMessageAsync("Contact Battletag: "); var contactBT = await interactivity.WaitForMessageAsync(x => x.Author == ctx.Member); await ctx.Member.SendMessageAsync("Contact Discord: "); var contactDiscord = await interactivity.WaitForMessageAsync(x => x.Author == ctx.Member); //outputs mesage in confirmed-scrim or scheduling channel, pings roles, adds reactions to the end var confirmedScrim = await ctx.Channel.SendMessageAsync("<@&[Player Role ID]> <@&[Coach Role ID]>\n" + //add role IDs "**__" + currentDay.ToString() + " " + monthNum + "/" + dayNum + "__**\n" + "Time: " + startTime.ToString() + "-" + finishTime.ToString() + "pm ET\n" + teamName.Result.Content.ToString() + " | " + teamSR.Result.Content.ToString() + "k" + "\nContact Battletag: " + contactBT.Result.Content.ToString() + "\nContact Discord: " + contactDiscord.Result.Content.ToString()); await confirmedScrim.CreateReactionAsync(tankEmoji); await confirmedScrim.CreateReactionAsync(dpsEmoji); await confirmedScrim.CreateReactionAsync(supportEmoji); //automatically pins message await confirmedScrim.PinAsync(); //full proof it later....still needs data validation, way to cancel, change dates? }
public async Task DeleteAsync(CommandContext ctx, [Description("Emoji to delete.")] DiscordEmoji emoji) { try { DiscordGuildEmoji gemoji = await ctx.Guild.GetEmojiAsync(emoji.Id); string name = gemoji.Name; await ctx.Guild.DeleteEmojiAsync(gemoji, ctx.BuildInvocationDetailsString()); await this.InformAsync(ctx, $"Successfully deleted emoji: {Formatter.Bold(name)}", important : false); } catch (NotFoundException) { throw new CommandFailedException("Can't find that emoji in list of emoji that I made for this guild."); } }
public async Task StealAsync(CommandContext ctx, DiscordEmoji emoji, string name) { if (emoji.Id == 0) { throw new InvalidOperationException("Cannot steal a unicode emoji."); } DiscordGuildEmoji nemoji = null; using (var res = await this.Http.GetAsync(emoji.Url).ConfigureAwait(false)) using (var rss = await res.Content.ReadAsStreamAsync().ConfigureAwait(false)) nemoji = await ctx.Guild.CreateEmojiAsync(name, rss, reason : $"{ctx.User.Username}#{ctx.User.Discriminator} ({ctx.User.Id}) stole a meme.").ConfigureAwait(false); await ctx.RespondAsync($"{DiscordEmoji.FromName(ctx.Client, ":msokhand:")} {nemoji}").ConfigureAwait(false); }
public async Task DeleteAsync(CommandContext ctx, [Description("desc-emoji-del")] DiscordEmoji emoji, [RemainingText, Description("desc-rsn")] string?reason = null) { try { DiscordGuildEmoji gemoji = await ctx.Guild.GetEmojiAsync(emoji.Id); string name = gemoji.Name; await gemoji.DeleteAsync(ctx.BuildInvocationDetailsString(reason)); await ctx.InfoAsync(this.ModuleColor, "fmt-emoji-del", Formatter.Bold(name)); } catch (NotFoundException) { throw new CommandFailedException(ctx, "cmd-err-emoji-del-404"); } }
public async Task InfoAsync(CommandContext ctx, [Description("Emoji.")] DiscordEmoji emoji) { DiscordGuildEmoji gemoji = await ctx.Guild.GetEmojiAsync(emoji.Id); var emb = new DiscordEmbedBuilder { Title = "Emoji details:", Description = gemoji, Color = this.ModuleColor, ThumbnailUrl = gemoji.Url }; emb.AddField("Name", Formatter.InlineCode(gemoji.Name), inline: true); emb.AddField("Created by", gemoji.User is null ? "<unknown>" : gemoji.User.Username, inline: true); emb.AddField("Integration managed", gemoji.IsManaged.ToString(), inline: true); await ctx.RespondAsync(embed : emb.Build()); }
public async Task DeleteEmojiAsync(DiscordMember member) { BoostEmoji be = new BoostEmoji(member); if (!await be.LoadAsync(DbContext)) { throw new ArgumentNullException("Member does not have an emoji set."); } //Delete it and then remove its thingy Logger.Log("Deleting {0}'s emoji", member); await be.DeleteAsync(DbContext); //Remove from the server DiscordGuildEmoji emoji = await member.Guild.GetEmojiAsync(be.EmojiId); await member.Guild.DeleteEmojiAsync(emoji, "Unboosted."); }
public async Task ModifyAsync(CommandContext ctx, [Description("Emoji to rename.")] DiscordEmoji emoji, [Description("New name.")] string newname) { if (string.IsNullOrWhiteSpace(newname)) { throw new InvalidCommandUsageException("Name missing."); } try { DiscordGuildEmoji gemoji = await ctx.Guild.GetEmojiAsync(emoji.Id); gemoji = await ctx.Guild.ModifyEmojiAsync(gemoji, name : newname, reason : ctx.BuildInvocationDetailsString()); await this.InformAsync(ctx, $"Successfully modified emoji: {gemoji}", important : false); } catch (NotFoundException) { throw new CommandFailedException("Can't find that emoji in list of emoji that I made for this guild."); } }
internal override async Task Execute(CommandObjects CommandObject) { string[] msgs = CommandObject.CommandArgs.Remove(0); if (msgs.Length == 0) { await CommandObject.Message.Channel.SendMessageAsync(CommandObject.Language.EmptyText); return; } if (string.IsNullOrWhiteSpace(msgs[0])) { await CommandObject.Message.Channel.SendMessageAsync(CommandObject.Language.EmptyName); return; } string EmojiName = msgs[0]; try { IEnumerator <DiscordAttachment> Attachment = CommandObject.Message.Attachments.GetEnumerator(); Uri ImageUrl; if (Attachment.MoveNext()) { ImageUrl = new Uri(Attachment.Current.Url); } else { throw new UrlNotFoundException(); } WebClient GetImage = new WebClient(); byte[] Imagebyte = await GetImage.DownloadDataTaskAsync(ImageUrl); Stream Image = new MemoryStream(Imagebyte); DiscordGuildEmoji Emoji = await CommandObject.Guild.CreateEmojiAsync(EmojiName, Image); await CommandObject.Channel.SendMessageAsync(string.Format(CommandObject.Language.EmojiSuccess, ConvertEmoji(Emoji), Emoji.Name)); } catch (UrlNotFoundException) { await CommandObject.Channel.SendMessageAsync(CommandObject.Language.ImageNotFound); } }
public async Task ModifyAsync(CommandContext ctx, [Description("desc-emoji-edit")] DiscordEmoji emoji, [Description("str-name")] string newname, [RemainingText, Description("desc-rsn")] string?reason = null) { if (string.IsNullOrWhiteSpace(newname) || newname.Length < 2 || newname.Length > DiscordLimits.EmojiNameLimit) { throw new InvalidCommandUsageException(ctx, "cmd-err-emoji-name", 2, DiscordLimits.EmojiNameLimit); } try { DiscordGuildEmoji gemoji = await ctx.Guild.GetEmojiAsync(emoji.Id); string name = gemoji.GetDiscordName(); await ctx.Guild.ModifyEmojiAsync(gemoji, name : newname, reason : ctx.BuildInvocationDetailsString(reason)); await ctx.InfoAsync(this.ModuleColor, "fmt-emoji-edit", Formatter.Bold(name)); } catch (NotFoundException) { throw new CommandFailedException(ctx, "cmd-err-emoji-del-404"); } }
public async Task DeleteEmote(CommandContext ctx, [Description("emote to delete.")] DiscordEmoji emote) { if (ctx.Channel.IsPrivate) { await ctx.RespondAsync(":x: This command is only for server use."); return; } await ctx.TriggerTypingAsync(); DiscordGuildEmoji guildemote = null; if (emote.IsManaged) { await ctx.RespondAsync("You can't delete an integration-managed emote."); } else { if (ctx.Guild.Emojis.Any(guildemoji => guildemoji.Value == emote)) { guildemote = ctx.Guild.GetEmojiAsync(emote.Id).Result; } if (guildemote == null) { await ctx.RespondAsync("This emote is not from this server."); } else { await FileHandler.DownloadUrlFile($"https://cdn.discordapp.com/emojis/{guildemote.Id}.png", "D:\\source\\emotes\\backup\\", ctx.Client, $"{guildemote.Name}.png"); await ctx.Guild.DeleteEmojiAsync(guildemote, $"Emote {guildemote.Name} deleted by {ctx.User.Username} ({ctx.User.Id})."); await ctx.RespondAsync($"Emote {guildemote.Name} deleted."); } } }
public async Task AddAsync(CommandContext ctx, [Description("Name for the emoji.")] string name, [Description("Image URL.")] Uri url = null) { if (name.Length < 2 || name.Length > 50) { throw new InvalidCommandUsageException("Emoji name length must be between 2 and 50 characters."); } if (url == null) { if (!ctx.Message.Attachments.Any() || !Uri.TryCreate(ctx.Message.Attachments.First().Url, UriKind.Absolute, out url)) { throw new InvalidCommandUsageException("Please specify a name and URL pointing to an emoji image or attach an image."); } } if (!await this.IsValidImageUriAsync(url)) { throw new InvalidCommandUsageException("URL must point to an image and use HTTP or HTTPS protocols."); } try { using (var response = await _http.GetAsync(url)) using (var stream = await response.Content.ReadAsStreamAsync()) { if (stream.Length >= 256000) { throw new CommandFailedException("The specified emoji is too large. Maximum allowed image size is 256KB."); } DiscordGuildEmoji emoji = await ctx.Guild.CreateEmojiAsync(name, stream, reason : ctx.BuildInvocationDetailsString()); await this.InformAsync(ctx, $"Successfully added emoji: {emoji}", important : false); } } catch (WebException e) { throw new CommandFailedException("An error occured while fetching the image.", e); } catch (BadRequestException e) { throw new CommandFailedException("Discord prevented the emoji from being added. Possibly emoji slots are full for this guild or the image format is not supported?", e); } }
public async Task InfoAsync(CommandContext ctx, [Description("desc-emoji-info")] DiscordEmoji emoji) { try { DiscordGuildEmoji gemoji = await ctx.Guild.GetEmojiAsync(emoji.Id); var emb = new LocalizedEmbedBuilder(this.Localization, ctx.Guild.Id); emb.WithColor(this.ModuleColor); emb.WithLocalizedTitle("str-emoji-details"); emb.WithDescription($"{gemoji.GetDiscordName()} ({gemoji.Id})"); emb.WithThumbnail(gemoji.Url); emb.AddLocalizedTitleField("str-created-by", gemoji.User?.ToDiscriminatorString(), inline: true); emb.AddLocalizedTitleField("str-animated", gemoji.IsAnimated, inline: true); emb.AddLocalizedTitleField("str-managed", gemoji.IsManaged, inline: true); emb.AddLocalizedTitleField("str-url", gemoji.Url); emb.AddLocalizedTimestampField("str-created-at", gemoji.CreationTimestamp); await ctx.RespondAsync(embed : emb.Build()); } catch (NotFoundException) { throw new CommandFailedException(ctx, "cmd-err-emoji-404"); } }
public static DiscordMember Voted(this Dictionary <DiscordMember, DiscordGuildEmoji> dico) { var counter = new Dictionary <DiscordGuildEmoji, int>(); foreach (var(_, value) in dico) { if (counter.TryAdd(value, 1) == false) { counter[value] += 1; } } // On recupère le max DiscordGuildEmoji max = null; var count = 0; foreach (var(key, value) in counter) { if (max == null) { max = key; count = value; } else { if (count < value) { max = key; count = value; } } } var per = Global.Game.PersonnagesList.Find(p => p.Emoji == max); return(count == 0 ? null : per.Me); }
public async Task RenameEmote(CommandContext ctx, [Description("emote to rename.")] DiscordEmoji emote, [Description("new emote name.")] string newEmoteName) { if (ctx.Channel.IsPrivate) { await ctx.RespondAsync(":x: This command is only for server use."); return; } await ctx.TriggerTypingAsync(); DiscordGuildEmoji guildemote = null; if (emote.IsManaged) { await ctx.RespondAsync("You can't modify an integration-managed emote."); } else { if (ctx.Guild.Emojis.Any(guildemoji => guildemoji.Value == emote)) { guildemote = ctx.Guild.GetEmojiAsync(emote.Id).Result; } if (guildemote == null) { await ctx.RespondAsync("This emote is not from this server."); } else { await ctx.Guild.ModifyEmojiAsync(guildemote, newEmoteName, reason : $"Emote name changed to {newEmoteName} by {ctx.User.Username} ({ctx.User.Id}). Was: {guildemote.Name}"); await ctx.RespondAsync($"Emote {guildemote} modified."); } } }
public Citizen(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { }
public Salvator(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { }
public TalkativeSeer(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { }
public Hunter(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { }
public Wolf(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { Game.DiscordChannels[GameChannel.WolfText].AddOverwriteAsync(me, GameBuilder.UsrPerms); Game.DiscordChannels[GameChannel.WolfVoice].AddOverwriteAsync(me, GameBuilder.UsrPerms); }
public LittleGirl(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { }
public Witch(Game game, DiscordMember me, DiscordGuildEmoji emoji) : base(game, me, emoji) { }
public Hunter(DiscordMember me, DiscordGuildEmoji emoji) : base(me, emoji) { }