public async Task <RuntimeResult> AddConditionAsync ( AutoroleConfiguration autorole, [OverrideTypeReader(typeof(UncachedMessageTypeReader <IMessage>))] IMessage message, IEmote emote ) { var condition = _autoroles.CreateConditionProxy <ReactionCondition> ( message, emote ); if (condition is null) { return(RuntimeCommandResult.FromError("Failed to create a condition object. Yikes!")); } var addCondition = await _autoroles.AddConditionAsync(autorole, condition); if (!addCondition.IsSuccess) { return(addCondition.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Condition added.")); }
public async Task <RuntimeResult> CreateRoleplayAsync ( string roleplayName, string roleplaySummary = "No summary set.", bool isNSFW = false, bool isPublic = true ) { if (!(this.Context.User is IGuildUser guildUser)) { return(RuntimeCommandResult.FromError("The current user isn't a guild user.")); } var result = await _discordRoleplays.CreateRoleplayAsync ( guildUser, roleplayName, roleplaySummary, isNSFW, isPublic ); if (!result.IsSuccess) { return(result.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess($"Roleplay \"{result.Entity.Name}\" created.")); }
public async Task <RuntimeResult> ShowKinksByPreferenceAsync ( IUser otherUser, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <KinkPreference>))] KinkPreference preference ) { var getUserKinksResult = await _kinks.GetUserKinksAsync(otherUser); if (!getUserKinksResult.IsSuccess) { return(getUserKinksResult.ToRuntimeResult()); } var userKinks = getUserKinksResult.Entity; var withPreference = userKinks.Where(k => k.Preference == preference).ToList(); if (!withPreference.Any()) { return(RuntimeCommandResult.FromError("The user doesn't have any kinks with that preference.")); } var paginatedKinkPages = _kinks.BuildPaginatedUserKinkEmbeds(withPreference); var paginatedMessage = new PaginatedEmbed(_feedback, _interactivity, this.Context.User) .WithPages(paginatedKinkPages); await _interactivity.SendPrivateInteractiveMessageAsync(this.Context, _feedback, paginatedMessage); return(RuntimeCommandResult.FromSuccess()); }
public async Task <RuntimeResult> IncludePreviousMessagesAsync ( [RequireEntityOwnerOrPermission(typeof(EditRoleplay), PermissionTarget.Other)] Roleplay roleplay, [OverrideTypeReader(typeof(UncachedMessageTypeReader <IMessage>))] IMessage startMessage, [OverrideTypeReader(typeof(UncachedMessageTypeReader <IMessage>))] IMessage?finalMessage = null ) { finalMessage ??= this.Context.Message; if (startMessage.Channel != finalMessage.Channel) { return(RuntimeCommandResult.FromError("The messages are not in the same channel.")); } var addedOrUpdatedMessageCount = 0; var latestMessage = startMessage; while (latestMessage.Timestamp < finalMessage.Timestamp) { var messages = (await this.Context.Channel.GetMessagesAsync ( latestMessage, Direction.After ).FlattenAsync()).OrderBy(m => m.Timestamp).ToList(); latestMessage = messages.Last(); foreach (var message in messages) { // Jump out if we've passed the final message if (message.Timestamp > finalMessage.Timestamp) { break; } if (!(message is IUserMessage userMessage)) { continue; } var modifyResult = await _discordRoleplays.ConsumeMessageAsync(userMessage); if (modifyResult.IsSuccess) { ++addedOrUpdatedMessageCount; } } } return(RuntimeCommandResult.FromSuccess ( $"{addedOrUpdatedMessageCount} messages added to \"{roleplay.Name}\"." )); }
public async Task <RuntimeResult> ShowAvailablePronounFamiliesAsync() { EmbedFieldBuilder CreatePronounField(IPronounProvider pronounProvider) { var ef = new EmbedFieldBuilder(); ef.WithName(pronounProvider.Family); var value = $"{pronounProvider.GetSubjectForm()} ate {pronounProvider.GetPossessiveAdjectiveForm()} " + $"pie that {pronounProvider.GetSubjectForm()} brought with " + $"{pronounProvider.GetReflexiveForm()}."; value = value.Transform(To.SentenceCase); ef.WithValue($"*{value}*"); return(ef); } var pronounProviders = _pronouns.GetAvailablePronounProviders().ToList(); if (!pronounProviders.Any()) { return(RuntimeCommandResult.FromError("There doesn't seem to be any pronouns available.")); } var fields = pronounProviders.Select(CreatePronounField); var description = "Each field below represents a pronoun that can be used with a character. The title of " + "each field is the pronoun family that you use when selecting the pronoun, and below it" + "is a short example of how it might be used."; var paginatedEmbedPages = PageFactory.FromFields ( fields, description: description ); var paginatedEmbed = new PaginatedEmbed(_feedback, _interactivity, this.Context.User).WithPages ( paginatedEmbedPages.Select ( p => p.WithColor(Color.DarkPurple).WithTitle("Available pronouns") ) ); await _interactivity.SendInteractiveMessageAndDeleteAsync ( this.Context.Channel, paginatedEmbed, TimeSpan.FromMinutes(5.0) ); return(RuntimeCommandResult.FromSuccess()); }
public async Task <RuntimeResult> UpdateKinkDatabaseAsync() { await _feedback.SendConfirmationAsync(this.Context, "Updating kinks..."); var updatedKinkCount = 0; // Get the latest JSON from F-list string json; using (var web = new HttpClient()) { web.Timeout = TimeSpan.FromSeconds(3); var cts = new CancellationTokenSource(); cts.CancelAfter(web.Timeout); try { using var response = await web.GetAsync ( new Uri ("https://www.f-list.net/json/api/kink-list.php"), cts.Token ); json = await response.Content.ReadAsStringAsync(); } catch (OperationCanceledException) { return(RuntimeCommandResult.FromError("Could not connect to F-list: Operation timed out.")); } } var kinkCollection = JsonConvert.DeserializeObject <KinkCollection>(json); if (kinkCollection.KinkCategories is null) { return(RuntimeCommandResult.FromError($"Received an error from F-List: {kinkCollection.Error}")); } foreach (var kinkSection in kinkCollection.KinkCategories) { if (!Enum.TryParse <KinkCategory>(kinkSection.Key, out var kinkCategory)) { return(RuntimeCommandResult.FromError("Failed to parse kink category.")); } updatedKinkCount += await _kinks.UpdateKinksAsync(kinkSection.Value.Kinks.Select ( k => new Kink(k.Name, k.Description, k.KinkId, kinkCategory) )); } return(RuntimeCommandResult.FromSuccess($"Done. {updatedKinkCount} kinks updated.")); }
public async Task <RuntimeResult> ContactUserAsync(IUser discordUser) { if (this.Context.User is IGuildUser guildUser && !guildUser.GuildPermissions.MentionEveryone) { return(RuntimeCommandResult.FromError("You need to be able to mention everyone to do that.")); } if (discordUser.Id == this.Context.Client.CurrentUser.Id) { return(RuntimeCommandResult.FromError ( "That's a splendid idea - at least then, I'd get an intelligent reply." )); } if (discordUser.IsBot) { return(RuntimeCommandResult.FromError("I could do that, but I doubt I'd get a reply.")); } var contactMessage = $"Hello there, {discordUser.Mention}. I've been instructed to initiate... " + $"negotiations... with you. \nA good place to start would be the \"!help <topic>\" " + $"command."; var eb = _feedback.CreateFeedbackEmbed ( discordUser, Color.DarkPurple, contactMessage ); var userDMChannel = await discordUser.GetOrCreateDMChannelAsync(); try { await userDMChannel.SendMessageAsync(string.Empty, false, eb); } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { return(RuntimeCommandResult.FromError(hex.Message)); } finally { await userDMChannel.CloseAsync(); } return(RuntimeCommandResult.FromSuccess("User contacted.")); }
public async Task <RuntimeResult> ListOwnedRoleplaysAsync(IGuildUser?discordUser = null) { if (discordUser is null) { var authorUser = this.Context.User; if (!(authorUser is IGuildUser guildUser)) { return(RuntimeCommandResult.FromError("The owner isn't a guild user.")); } discordUser = guildUser; } var getUserRoleplays = await _discordRoleplays.GetUserRoleplaysAsync(discordUser); if (!getUserRoleplays.IsSuccess) { return(getUserRoleplays.ToRuntimeResult()); } var roleplays = getUserRoleplays.Entity.ToList(); var appearance = PaginatedAppearanceOptions.Default; appearance.Title = "Your roleplays"; appearance.Author = discordUser; var paginatedEmbed = PaginatedEmbedFactory.SimpleFieldsFromCollection ( _feedback, _interactivity, this.Context.User, roleplays, r => r.Name, r => r.Summary, "You don't have any roleplays.", appearance ); await _interactivity.SendInteractiveMessageAndDeleteAsync ( this.Context.Channel, paginatedEmbed, TimeSpan.FromMinutes(5.0) ); return(RuntimeCommandResult.FromSuccess()); }
public async Task <RuntimeResult> SetCharacterRoleAsync ( [RequireEntityOwnerOrPermission(typeof(EditCharacter), PermissionTarget.Other)] Character character, IRole discordRole ) { var getRoleResult = await _characterRoles.GetCharacterRoleAsync(discordRole); if (!getRoleResult.IsSuccess) { return(getRoleResult.ToRuntimeResult()); } var commandInvoker = (IGuildUser)this.Context.User; var role = getRoleResult.Entity; if (role.Access == RoleAccess.Restricted) { if (!commandInvoker.GuildPermissions.ManageRoles) { return(RuntimeCommandResult.FromError ( "That role is restricted, and you must be able to manage roles to use it." )); } } var owner = await this.Context.Guild.GetUserAsync((ulong)character.Owner.DiscordID); if (owner is null) { return(RuntimeCommandResult.FromError("Failed to get the owner as a guild user.")); } var setRoleResult = await _characterRoles.SetCharacterRoleAsync(owner, character, role); if (!setRoleResult.IsSuccess) { return(setRoleResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Character role set.")); }
public async Task <RuntimeResult> AddConditionAsync(AutoroleConfiguration autorole, ITextChannel channel, long count) { var condition = _autoroles.CreateConditionProxy <MessageCountInChannelCondition>(channel, count); if (condition is null) { return(RuntimeCommandResult.FromError("Failed to create a condition object. Yikes!")); } var addCondition = await _autoroles.AddConditionAsync(autorole, condition); if (!addCondition.IsSuccess) { return(addCondition.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Condition added.")); }
public async Task <RuntimeResult> RefreshRoleplayAsync(Roleplay roleplay) { var isOwner = roleplay.IsOwner(this.Context.User); var isParticipant = roleplay.HasJoined(this.Context.User); if (!(isOwner || isParticipant)) { return(RuntimeCommandResult.FromError("You don't own that roleplay, nor are you a participant.")); } var refreshResult = await _discordRoleplays.RefreshRoleplayAsync(roleplay); if (!refreshResult.IsSuccess) { return(refreshResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Timeout refreshed.")); }
public async Task <RuntimeResult> SetCharacterDescriptionAsync ( [RequireEntityOwnerOrPermission(typeof(EditCharacter), PermissionTarget.Other)] Character character, string?newCharacterDescription = null ) { if (newCharacterDescription is null) { if (!this.Context.Message.Attachments.Any()) { return(RuntimeCommandResult.FromError ( "You need to attach a plaintext document or provide an in-message description." )); } var newDescription = this.Context.Message.Attachments.First(); var getAttachmentStreamResult = await _discord.GetAttachmentStreamAsync(newDescription); if (!getAttachmentStreamResult.IsSuccess) { return(getAttachmentStreamResult.ToRuntimeResult()); } using var sr = new StreamReader(getAttachmentStreamResult.Entity); newCharacterDescription = await sr.ReadToEndAsync(); } var setDescriptionResult = await _characters.SetCharacterDescriptionAsync ( character, newCharacterDescription ); if (!setDescriptionResult.IsSuccess) { return(setDescriptionResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Character description set.")); }
public async Task <RuntimeResult> SetAffirmationNotificationChannel(IChannel channel) { if (!(channel is ITextChannel textChannel)) { return(RuntimeCommandResult.FromError("That's not a text channel.")); } var setResult = await _autoroles.SetAffirmationNotificationChannelAsync ( this.Context.Guild, textChannel ); if (!setResult.IsSuccess) { return(setResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Channel set.")); }
public async Task <RuntimeResult> SetCharacterAvatarAsync ( [RequireEntityOwnerOrPermission(typeof(EditCharacter), PermissionTarget.Other)] Character character, string?newCharacterAvatarUrl = null ) { if (newCharacterAvatarUrl is null) { if (!this.Context.Message.Attachments.Any()) { return(RuntimeCommandResult.FromError("You need to attach an image or provide a url.")); } var newAvatar = this.Context.Message.Attachments.First(); newCharacterAvatarUrl = newAvatar.Url; } var galleryImage = character.Images.FirstOrDefault ( i => i.Name.ToLower().Equals(newCharacterAvatarUrl.ToLower()) ); if (!(galleryImage is null)) { newCharacterAvatarUrl = galleryImage.Url; } var result = await _characters.SetCharacterAvatarAsync ( character, newCharacterAvatarUrl ?? throw new ArgumentNullException(nameof(newCharacterAvatarUrl)) ); if (!result.IsSuccess) { return(result.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Character avatar set.")); }
public async Task <RuntimeResult> LeaveRoleplayAsync(Roleplay roleplay) { if (!(this.Context.User is IGuildUser guildUser)) { return(RuntimeCommandResult.FromError("The current user isn't a guild user.")); } var removeUserResult = await _discordRoleplays.RemoveUserFromRoleplayAsync(roleplay, guildUser); if (!removeUserResult.IsSuccess) { return(removeUserResult.ToRuntimeResult()); } var roleplayOwnerUser = await this.Context.Guild.GetUserAsync((ulong)roleplay.Owner.DiscordID); return(RuntimeCommandResult.FromSuccess ( $"Left {roleplayOwnerUser.Mention}'s roleplay \"{roleplay.Name}\"" )); }
public async Task <RuntimeResult> AddConditionAsync(AutoroleConfiguration autorole, TimeSpan time) { var condition = _autoroles.CreateConditionProxy <TimeSinceLastActivityCondition> ( time ); if (condition is null) { return(RuntimeCommandResult.FromError("Failed to create a condition object. Yikes!")); } var addCondition = await _autoroles.AddConditionAsync(autorole, condition); if (!addCondition.IsSuccess) { return(addCondition.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess("Condition added.")); }
public async Task <RuntimeResult> ShowRoleplayAsync() { if (!(this.Context.Channel is ITextChannel textChannel)) { return(RuntimeCommandResult.FromError("This channel isn't a text channel.")); } var getCurrentRoleplayResult = await _discordRoleplays.GetActiveRoleplayAsync(textChannel); if (!getCurrentRoleplayResult.IsSuccess) { return(getCurrentRoleplayResult.ToRuntimeResult()); } var roleplay = getCurrentRoleplayResult.Entity; var eb = await CreateRoleplayInfoEmbedAsync(roleplay); await _feedback.SendEmbedAsync(this.Context.Channel, eb); return(RuntimeCommandResult.FromSuccess()); }
public async Task <RuntimeResult> DroneAsync(IGuildUser user) { if (!(this.Context.User is IGuildUser target)) { return(RuntimeCommandResult.FromError("The target user wasn't a guild user.")); } var droneMessage = user == target ? _content.GetRandomSelfDroneMessage() : _content.GetRandomTurnTheTablesMessage(); await _feedback.SendConfirmationAsync(this.Context, droneMessage); var droneResult = await _drone.DroneUserAsync(target); if (!droneResult.IsSuccess) { return(droneResult.ToRuntimeResult()); } return(RuntimeCommandResult.FromSuccess(_content.GetRandomConfirmationMessage())); }
public async Task <RuntimeResult> HideRoleplayAsync(Roleplay roleplay) { var getDedicatedChannelResult = await _dedicatedChannels.GetDedicatedChannelAsync ( this.Context.Guild, roleplay ); if (!getDedicatedChannelResult.IsSuccess) { return(RuntimeCommandResult.FromError ( "The given roleplay doesn't have a dedicated channel." )); } var user = this.Context.User; var dedicatedChannel = getDedicatedChannelResult.Entity; await _dedicatedChannels.SetChannelVisibilityForUserAsync(dedicatedChannel, user, false); return(RuntimeCommandResult.FromSuccess("Roleplay hidden.")); }
public async Task <RuntimeResult> ExportRoleplayAsync ( [RequireEntityOwnerOrPermission(typeof(ExportRoleplay), PermissionTarget.Other)] Roleplay roleplay, [OverrideTypeReader(typeof(HumanizerEnumTypeReader <ExportFormat>))] ExportFormat format = ExportFormat.PDF ) { IRoleplayExporter exporter; switch (format) { case ExportFormat.PDF: { exporter = new PDFRoleplayExporter(this.Context.Guild); break; } case ExportFormat.Plaintext: { exporter = new PlaintextRoleplayExporter(this.Context.Guild); break; } default: { return(RuntimeCommandResult.FromError("That export format hasn't been implemented yet.")); } } await _feedback.SendConfirmationAsync(this.Context, "Compiling the roleplay..."); using var output = await exporter.ExportAsync(roleplay); await this.Context.Channel.SendFileAsync(output.Data, $"{output.Title}.{output.Format.GetFileExtension()}"); return(RuntimeCommandResult.FromSuccess()); }
public async Task <RuntimeResult> ViewRoleplayAsync(Roleplay roleplay) { var getDedicatedChannelResult = await _dedicatedChannels.GetDedicatedChannelAsync ( this.Context.Guild, roleplay ); if (!getDedicatedChannelResult.IsSuccess) { return(RuntimeCommandResult.FromError ( "The given roleplay doesn't have a dedicated channel. Try using \"!rp export\" instead." )); } var user = this.Context.User; if (!roleplay.IsPublic && roleplay.ParticipatingUsers.All(p => p.User.DiscordID != (long)user.Id)) { return(RuntimeCommandResult.FromError ( "You don't have permission to view that roleplay." )); } var dedicatedChannel = getDedicatedChannelResult.Entity; await _dedicatedChannels.SetChannelVisibilityForUserAsync(dedicatedChannel, user, true); var channelMention = MentionUtils.MentionChannel(dedicatedChannel.Id); return(RuntimeCommandResult.FromSuccess ( $"The roleplay \"{roleplay.Name}\" is now visible in {channelMention}." )); }
public async Task <RuntimeResult> MoveRoleplayIntoChannelAsync(string newName, params IGuildUser[] participants) { if (!(this.Context.User is IGuildUser guildUser)) { return(RuntimeCommandResult.FromError("The current user isn't a guild user.")); } var createRoleplayAsync = await _discordRoleplays.CreateRoleplayAsync ( guildUser, newName, "No summary set.", false, true ); if (!createRoleplayAsync.IsSuccess) { return(createRoleplayAsync.ToRuntimeResult()); } var roleplay = createRoleplayAsync.Entity; foreach (var participant in participants) { if (participant == this.Context.User) { // Already added continue; } var addParticipantAsync = await _discordRoleplays.AddUserToRoleplayAsync(roleplay, participant); if (addParticipantAsync.IsSuccess) { continue; } var message = $"I couldn't add {participant.Mention} to the roleplay ({addParticipantAsync.ErrorReason}. " + $"Please try to invite them manually."; await _feedback.SendWarningAsync ( this.Context, message ); } var participantMessages = new List <IMessage>(); // Copy the last messages from the participants foreach (var participant in participants) { // Find the last message in the current channel from the user var channel = this.Context.Channel; var messageBatch = await channel.GetMessagesAsync(this.Context.Message, Direction.Before) .FlattenAsync(); foreach (var message in messageBatch) { if (message.Author != participant) { continue; } participantMessages.Add(message); break; } } var getDedicatedChannel = await _dedicatedChannels.GetDedicatedChannelAsync(this.Context.Guild, roleplay); if (!getDedicatedChannel.IsSuccess) { return(getDedicatedChannel.ToRuntimeResult()); } var dedicatedChannel = getDedicatedChannel.Entity; foreach (var participantMessage in participantMessages.OrderByDescending(m => m.Timestamp)) { var messageLink = participantMessage.GetJumpUrl(); await dedicatedChannel.SendMessageAsync(messageLink); } var startRoleplayAsync = await _discordRoleplays.StartRoleplayAsync ( (ITextChannel)this.Context.Channel, roleplay ); if (!startRoleplayAsync.IsSuccess) { return(startRoleplayAsync.ToRuntimeResult()); } var joinedUsers = roleplay.JoinedUsers.Select(async p => await this.Context.Client.GetUserAsync((ulong)p.User.DiscordID)); var joinedMentions = joinedUsers.Select(async u => (await u).Mention); var participantList = (await Task.WhenAll(joinedMentions)).Humanize(); await dedicatedChannel.SendMessageAsync($"Calling {participantList}!"); return(RuntimeCommandResult.FromSuccess ( $"All done! Your roleplay is now available in {MentionUtils.MentionChannel(dedicatedChannel.Id)}." )); }