protected virtual void Dispose(bool disposing) { if (!_disposedValue) { if (disposing) { Fights.Dispose(); Bid.Dispose(); Roleplay.Dispose(); Flood.Dispose(); CharacterCreation.Dispose(); } Fights = null; Bid = null; Roleplay = null; Flood = null; CharacterCreation = null; _disposedValue = true; } }
public async Task TransferRoleplayOwnershipAsync ( IGuildUser newOwner, [RequireEntityOwnerOrPermission(typeof(TransferRoleplay), PermissionTarget.Other)] Roleplay roleplay ) { var transferResult = await _discordRoleplays.TransferRoleplayOwnershipAsync ( newOwner, roleplay ); if (!transferResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, transferResult.ErrorReason); return; } await _feedback.SendConfirmationAsync(this.Context, "Roleplay ownership transferred."); }
public async Task InvitePlayerAsync ( [NotNull] IUser playerToInvite, [NotNull] [RequireEntityOwnerOrPermission(typeof(EditRoleplay), PermissionTarget.Other)] Roleplay roleplay ) { var invitePlayerResult = await _roleplays.InviteUserAsync(roleplay, playerToInvite); if (!invitePlayerResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, invitePlayerResult.ErrorReason); return; } await _feedback.SendConfirmationAsync(this.Context, $"Invited {playerToInvite.Mention} to {roleplay.Name}."); var userDMChannel = await playerToInvite.GetOrCreateDMChannelAsync(); try { var roleplayName = roleplay.Name.Contains(" ") ? roleplay.Name.Quote() : roleplay.Name; await userDMChannel.SendMessageAsync ( $"You've been invited to join {roleplay.Name}. Use `!rp join {roleplayName}` to join." ); } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { } finally { await userDMChannel.CloseAsync(); } }
/// <summary> /// Removes the given user from the given roleplay. /// </summary> /// <param name="roleplay">The roleplay to remove the user from.</param> /// <param name="removedUser">The user to remove from the roleplay.</param> /// <returns>An execution result which may or may not have succeeded.</returns> public async Task <DeleteEntityResult> RemoveUserFromRoleplayAsync(Roleplay roleplay, User removedUser) { removedUser = _database.NormalizeReference(removedUser); if (!roleplay.HasJoined(removedUser)) { return(DeleteEntityResult.FromError("No matching user found in the roleplay.")); } if (roleplay.IsOwner(removedUser)) { return(DeleteEntityResult.FromError("The owner of a roleplay can't be removed from it.")); } var participantEntry = roleplay.JoinedUsers.FirstOrDefault(p => p.User == removedUser); roleplay.ParticipatingUsers.Remove(participantEntry); await _database.SaveChangesAsync(); return(DeleteEntityResult.FromSuccess()); }
public async Task <RuntimeResult> InvitePlayerAsync ( IGuildUser playerToInvite, [RequireEntityOwnerOrPermission(typeof(EditRoleplay), PermissionTarget.Other)] Roleplay roleplay ) { var invitePlayerResult = await _discordRoleplays.InviteUserToRoleplayAsync(roleplay, playerToInvite); if (!invitePlayerResult.IsSuccess) { return(invitePlayerResult.ToRuntimeResult()); } var userDMChannel = await playerToInvite.GetOrCreateDMChannelAsync(); try { var roleplayName = roleplay.Name.Contains(" ") ? roleplay.Name.Quote() : roleplay.Name; await userDMChannel.SendMessageAsync ( $"You've been invited to join {roleplay.Name}. Use `!rp join {roleplayName}` to join." ); } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { } finally { await userDMChannel.CloseAsync(); } return(RuntimeCommandResult.FromSuccess ( $"Invited {playerToInvite.Mention} to {roleplay.Name}." )); }
public async Task SetRoleplayIsPublic ( bool isPublic, [NotNull] [RequireEntityOwnerOrPermission(typeof(EditRoleplay), PermissionTarget.Other)] Roleplay roleplay ) { var result = await _roleplays.SetRoleplayIsPublicAsync(roleplay, isPublic); if (!result.IsSuccess) { await _feedback.SendErrorAsync(this.Context, result.ErrorReason); return; } var getDedicatedChannelResult = await _roleplays.GetDedicatedRoleplayChannelAsync ( this.Context.Guild, roleplay ); if (getDedicatedChannelResult.IsSuccess) { var dedicatedChannel = getDedicatedChannelResult.Entity; var everyoneRole = this.Context.Guild.EveryoneRole; await _roleplays.SetDedicatedChannelVisibilityForRoleAsync ( dedicatedChannel, everyoneRole, isPublic ); } await _feedback.SendConfirmationAsync(this.Context, $"Roleplay set to {(isPublic ? "public" : "private")}"); }
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 <Result <FeedbackMessage> > StartRoleplayAsync ( [RequireEntityOwner] [AutocompleteProvider("roleplay::owned")] Roleplay roleplay ) { var startRoleplayResult = await _discordRoleplays.StartRoleplayAsync ( _context.ChannelID, roleplay ); if (!startRoleplayResult.IsSuccess) { return(Result <FeedbackMessage> .FromError(startRoleplayResult)); } var activationMessage = $"The roleplay \"{roleplay.Name}\" is now active in " + $"<#{roleplay.ActiveChannelID!.Value}>."; return(new FeedbackMessage(activationMessage, _feedback.Theme.Secondary)); }
public async Task MakeRoleplayCurrentAsync ( [NotNull] [RequireEntityOwnerOrPermission(Permission.StartStopRoleplay, PermissionTarget.Other)] Roleplay roleplay ) { this.Database.Attach(roleplay); var isNsfwChannel = this.Context.Channel is ITextChannel textChannel && textChannel.IsNsfw; if (roleplay.IsNSFW && !isNsfwChannel) { await this.Feedback.SendErrorAsync(this.Context, "This channel is not marked as NSFW, while your roleplay is... naughty!"); return; } roleplay.ActiveChannelID = (long)this.Context.Channel.Id; await this.Database.SaveChangesAsync(); await this.Feedback.SendConfirmationAsync(this.Context, $"The roleplay \"{roleplay.Name}\" is now current in #{this.Context.Channel.Name}."); }
/// <summary> /// Sets the summary of the given roleplay. /// </summary> /// <param name="roleplay">The roleplay to set the summary of.</param> /// <param name="summary">The new summary.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> SetRoleplaySummaryAsync(Roleplay roleplay, string summary) { var setSummary = await _roleplays.SetRoleplaySummaryAsync(roleplay, summary); if (!setSummary.IsSuccess) { return(setSummary); } if (!roleplay.DedicatedChannelID.HasValue) { return(ModifyEntityResult.FromSuccess()); } var setChannelSummary = await _dedicatedChannels.UpdateChannelSummaryAsync(roleplay); if (!setChannelSummary.IsSuccess) { return(setChannelSummary); } return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Sets the NSFW status of the roleplay. /// </summary> /// <param name="roleplay">The roleplay.</param> /// <param name="isNSFW">Whether the roleplay is NSFW.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> SetRoleplayIsNSFWAsync(Roleplay roleplay, bool isNSFW) { var setNSFW = await _roleplays.SetRoleplayIsNSFWAsync(roleplay, isNSFW); if (!setNSFW.IsSuccess) { return(setNSFW); } if (!roleplay.DedicatedChannelID.HasValue) { return(setNSFW); } var setChannelNSFW = await _dedicatedChannels.UpdateChannelNSFWStatus(roleplay); if (!setChannelNSFW.IsSuccess) { return(setChannelNSFW); } return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Sets whether or not a roleplay is NSFW. /// </summary> /// <param name="roleplay">The roleplay to set the value in.</param> /// <param name="isNSFW">The new value.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> SetRoleplayIsNSFWAsync ( Roleplay roleplay, bool isNSFW, CancellationToken ct = default ) { if (roleplay.IsNSFW == isNSFW) { return(ModifyEntityResult.FromError($"The roleplay is already {(isNSFW ? "NSFW" : "SFW")}.")); } if (roleplay.Messages.Count > 0 && roleplay.IsNSFW && !isNSFW) { return(ModifyEntityResult.FromError("You can't mark a NSFW roleplay with messages in it as non-NSFW.")); } roleplay.IsNSFW = isNSFW; await _database.SaveChangesAsync(ct); return(ModifyEntityResult.FromSuccess()); }
public async Task RefreshRoleplayAsync(Roleplay roleplay) { var isOwner = roleplay.IsOwner(this.Context.User); var isParticipant = roleplay.HasJoined(this.Context.User); if (!(isOwner || isParticipant)) { await _feedback.SendErrorAsync(this.Context, "You don't own that roleplay, nor are you a participant."); return; } var refreshResult = await _roleplays.RefreshRoleplayAsync(roleplay); if (!refreshResult.IsSuccess) { await _feedback.SendErrorAsync(this.Context, refreshResult.ErrorReason); return; } await _feedback.SendConfirmationAsync(this.Context, "Timeout refreshed."); }
/// <summary> /// Invites the user to the given roleplay. /// </summary> /// <param name="roleplay">The roleplay to invite the user to.</param> /// <param name="invitedUser">The user to invite.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>An execution result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> InviteUserToRoleplayAsync ( Roleplay roleplay, User invitedUser, CancellationToken ct = default ) { invitedUser = _database.NormalizeReference(invitedUser); if (roleplay.InvitedUsers.Any(p => p.User.DiscordID == invitedUser.DiscordID)) { return(ModifyEntityResult.FromError("The user has already been invited to that roleplay.")); } // Remove the invited user from the kick list, if they're on it var participantEntry = roleplay.ParticipatingUsers.FirstOrDefault ( p => p.User.DiscordID == invitedUser.DiscordID ); if (participantEntry is null) { participantEntry = _database.CreateProxy <RoleplayParticipant>(roleplay, invitedUser); _database.Update(participantEntry); participantEntry.Status = ParticipantStatus.Invited; roleplay.ParticipatingUsers.Add(participantEntry); } else { participantEntry.Status = ParticipantStatus.Invited; } await _database.SaveChangesAsync(ct); return(ModifyEntityResult.FromSuccess()); }
public async Task <RuntimeResult> KickRoleplayParticipantAsync ( IGuildUser discordUser, [RequireEntityOwnerOrPermission(typeof(KickRoleplayMember), PermissionTarget.Other)] Roleplay roleplay ) { var kickUserResult = await _discordRoleplays.KickUserFromRoleplayAsync(roleplay, discordUser); if (!kickUserResult.IsSuccess) { return(kickUserResult.ToRuntimeResult()); } var userDMChannel = await discordUser.GetOrCreateDMChannelAsync(); try { await userDMChannel.SendMessageAsync ( $"You've been removed from the roleplay \"{roleplay.Name}\" by " + $"{this.Context.Message.Author.Username}." ); } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { } finally { await userDMChannel.CloseAsync(); } return(RuntimeCommandResult.FromSuccess ( $"{discordUser.Mention} has been kicked from {roleplay.Name}." )); }
public async Task InvitePlayerAsync ( [NotNull] IUser playerToInvite, [NotNull] [RequireEntityOwnerOrPermission(Permission.EditRoleplay, PermissionTarget.Other)] Roleplay roleplay ) { this.Database.Attach(roleplay); var invitePlayerResult = await this.Roleplays.InviteUserAsync(this.Database, roleplay, playerToInvite); if (!invitePlayerResult.IsSuccess) { await this.Feedback.SendErrorAsync(this.Context, invitePlayerResult.ErrorReason); return; } await this.Feedback.SendConfirmationAsync(this.Context, $"Invited {playerToInvite.Mention} to {roleplay.Name}."); var userDMChannel = await playerToInvite.GetOrCreateDMChannelAsync(); try { await userDMChannel.SendMessageAsync( $"You've been invited to join {roleplay.Name}. Use \"!rp join {roleplay.Name}\" to join."); } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { } finally { await userDMChannel.CloseAsync(); } }
/// <summary> /// Notifies the owner of the roleplay that it was stopped because it timed out. /// </summary> /// <param name="roleplay">The roleplay.</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> private async Task <OperationResult> NotifyOwnerAsync(Roleplay roleplay) { var owner = this.Client.GetUser((ulong)roleplay.Owner.DiscordID); if (owner is null) { return(OperationResult.FromError("Could not retrieve the owner of the roleplay.")); } var notification = _feedback.CreateEmbedBase(); notification.WithDescription ( $"Your roleplay \"{roleplay.Name}\" has been inactive for more than 28 days, and has been " + $"archived.\n" + $"\n" + $"This means that the dedicated channel that the roleplay had has been deleted. All messages in the " + $"roleplay have been saved, and can be exported or replayed as normal." ); notification.WithFooter ( $"You can export it by running !rp export \"{roleplay.Name}\"." ); try { await owner.SendMessageAsync(string.Empty, embed : notification.Build()); } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { // Nom nom nom } return(OperationResult.FromSuccess()); }
/// <summary> /// Invites the user to the given roleplay. /// </summary> /// <param name="db">The database where the roleplays are stored.</param> /// <param name="roleplay">The roleplay to invite the user to.</param> /// <param name="invitedUser">The user to invite.</param> /// <returns>An execution result which may or may not have succeeded.</returns> public async Task <ExecuteResult> InviteUserAsync ( [NotNull] GlobalInfoContext db, [NotNull] Roleplay roleplay, [NotNull] IUser invitedUser ) { if (roleplay.IsPublic) { return(ExecuteResult.FromError(CommandError.UnmetPrecondition, "The roleplay is not set to private.")); } if (roleplay.InvitedUsers.Any(p => p.User.DiscordID == (long)invitedUser.Id)) { return(ExecuteResult.FromError(CommandError.Unsuccessful, "The user has already been invited to that roleplay.")); } // Remove the invited user from the kick list, if they're on it var participantEntry = roleplay.ParticipatingUsers.FirstOrDefault(p => p.User.DiscordID == (long)invitedUser.Id); if (participantEntry is null) { var user = await db.GetOrRegisterUserAsync(invitedUser); participantEntry = new RoleplayParticipant(roleplay, user, ParticipantStatus.Invited); roleplay.ParticipatingUsers.Add(participantEntry); } else { participantEntry.Status = ParticipantStatus.Invited; } await db.SaveChangesAsync(); return(ExecuteResult.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}." )); }
private static async Task <Result> ArchiveRoleplayAsync ( IServiceProvider services, FeedbackService feedback, RoleplayDiscordService roleplayService, DedicatedChannelService dedicatedChannels, RoleplayServerSettingsService serverSettings, Roleplay roleplay ) { if (roleplay.DedicatedChannelID is null) { return(new UserError("The roleplay doesn't have a dedicated channel.")); } var ensureLogged = await roleplayService.EnsureAllMessagesAreLoggedAsync(roleplay); if (!ensureLogged.IsSuccess) { return(Result.FromError(ensureLogged)); } if (!roleplay.IsPublic) { return(await dedicatedChannels.DeleteChannelAsync(roleplay)); } var postResult = await PostArchivedRoleplayAsync(services, feedback, serverSettings, roleplay); if (!postResult.IsSuccess) { return(postResult); } return(await dedicatedChannels.DeleteChannelAsync(roleplay)); }
/// <summary> /// Updates the summary of the roleplay channel. /// </summary> /// <param name="roleplay">The roleplay.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> UpdateChannelSummaryAsync(Roleplay roleplay) { var guild = await _client.GetGuildAsync((ulong)roleplay.Server.DiscordID); if (guild is null) { return(ModifyEntityResult.FromError("Could not retrieve a valid guild.")); } var getChannel = await GetDedicatedChannelAsync(guild, roleplay); if (!getChannel.IsSuccess) { return(ModifyEntityResult.FromError(getChannel)); } var channel = getChannel.Entity; await channel.ModifyAsync ( m => m.Topic = $"Dedicated roleplay channel for {roleplay.Name}. {roleplay.Summary}" ); return(ModifyEntityResult.FromSuccess()); }
/// <summary> /// Removes the given user from the given roleplay. /// </summary> /// <param name="db">The database where the roleplays are stored.</param> /// <param name="context">The context of the user.</param> /// <param name="roleplay">The roleplay to remove the user from.</param> /// <param name="removedUser">The user to remove from the roleplay.</param> /// <returns>An execution result which may or may not have succeeded.</returns> public async Task <ExecuteResult> RemoveUserFromRoleplayAsync ( [NotNull] GlobalInfoContext db, [NotNull] SocketCommandContext context, [NotNull] Roleplay roleplay, [NotNull] IUser removedUser ) { var isCurrentUser = context.Message.Author.Id == removedUser.Id; if (!roleplay.HasJoined(removedUser)) { var errorMessage = isCurrentUser ? "You're not in that roleplay." : "No matching user found in the roleplay."; return(ExecuteResult.FromError(CommandError.Unsuccessful, errorMessage)); } if (roleplay.IsOwner(removedUser)) { var errorMessage = isCurrentUser ? "You can't leave a roleplay you own." : "The owner of a roleplay can't be removed from it."; return(ExecuteResult.FromError(CommandError.Unsuccessful, errorMessage)); } var participantEntry = roleplay.JoinedUsers.First(p => p.User.DiscordID == (long)removedUser.Id); participantEntry.Status = ParticipantStatus.None; await db.SaveChangesAsync(); return(ExecuteResult.FromSuccess()); }
/// <summary> /// Refreshes the timestamp on the given roleplay. /// </summary> /// <param name="roleplay">The roleplay.</param> /// <returns>A <see cref="Task{TResult}"/> representing the result of the asynchronous operation.</returns> public Task <ModifyEntityResult> RefreshRoleplayAsync(Roleplay roleplay) { return(_roleplays.RefreshRoleplayAsync(roleplay)); }
/// <summary> /// Creates a roleplay with the given parameters. /// </summary> /// <param name="db">The database where the roleplays are stored.</param> /// <param name="context">The context of the command.</param> /// <param name="roleplayName">The name of the roleplay.</param> /// <param name="roleplaySummary">The summary of the roleplay.</param> /// <param name="isNSFW">Whether or not the roleplay is NSFW.</param> /// <param name="isPublic">Whether or not the roleplay is public.</param> /// <returns>A creation result which may or may not have been successful.</returns> public async Task <CreateEntityResult <Roleplay> > CreateRoleplayAsync ( [NotNull] GlobalInfoContext db, [NotNull] SocketCommandContext context, [NotNull] string roleplayName, [NotNull] string roleplaySummary, bool isNSFW, bool isPublic) { var owner = await db.GetOrRegisterUserAsync(context.Message.Author); var roleplay = new Roleplay { Owner = owner, ServerID = (long)context.Guild.Id, IsActive = false, ActiveChannelID = (long)context.Channel.Id, ParticipatingUsers = new List <RoleplayParticipant>(), Messages = new List <UserMessage>() }; roleplay.ParticipatingUsers.Add(new RoleplayParticipant(roleplay, owner, ParticipantStatus.Joined)); var setNameResult = await SetRoleplayNameAsync(db, context, roleplay, roleplayName); if (!setNameResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(setNameResult)); } var setSummaryResult = await SetRoleplaySummaryAsync(db, roleplay, roleplaySummary); if (!setSummaryResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(setSummaryResult)); } var setIsNSFWResult = await SetRoleplayIsNSFWAsync(db, roleplay, isNSFW); if (!setIsNSFWResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(setIsNSFWResult)); } var setIsPublicResult = await SetRoleplayIsPublicAsync(db, roleplay, isPublic); if (!setIsPublicResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(setIsPublicResult)); } await db.Roleplays.AddAsync(roleplay); await db.SaveChangesAsync(); var roleplayResult = await GetUserRoleplayByNameAsync(db, context, context.Message.Author, roleplayName); if (!roleplayResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(roleplayResult)); } return(CreateEntityResult <Roleplay> .FromSuccess(roleplayResult.Entity)); }
/// <inheritdoc /> public override async Task <ExportedRoleplay> ExportAsync(Roleplay roleplay) { // Create our document var pdfDoc = new Document(); var filePath = Path.GetTempFileName(); using (var of = File.Create(filePath)) { var writer = PdfWriter.GetInstance(pdfDoc, of); writer.Open(); pdfDoc.Open(); var owner = await this.Guild.GetUserAsync((ulong)roleplay.Owner.DiscordID); pdfDoc.AddAuthor(owner.Nickname); pdfDoc.AddCreationDate(); pdfDoc.AddCreator("DIGOS Ambassador"); pdfDoc.AddTitle(roleplay.Name); var joinedUsers = await Task.WhenAll ( roleplay.JoinedUsers.Select ( async p => { var guildUser = await this.Guild.GetUserAsync((ulong)p.User.DiscordID); if (guildUser is null) { var messageByUser = roleplay.Messages.FirstOrDefault ( m => m.AuthorDiscordID == p.User.DiscordID ); if (messageByUser is null) { return($"Unknown user ({p.User.DiscordID})"); } return(messageByUser.AuthorNickname); } return(guildUser.Username); } ) ); pdfDoc.Add(CreateTitle(roleplay.Name)); pdfDoc.Add(CreateParticipantList(joinedUsers)); pdfDoc.NewPage(); var messages = roleplay.Messages.OrderBy(m => m.Timestamp).DistinctBy(m => m.Contents); foreach (var message in messages) { pdfDoc.Add(CreateMessage(message.AuthorNickname, message.Contents)); } pdfDoc.Close(); writer.Flush(); writer.Close(); } var resultFile = File.OpenRead(filePath); var exported = new ExportedRoleplay(roleplay.Name, ExportFormat.PDF, resultFile); return(exported); }
/// <summary> /// Starts the given roleplay in the current channel, or the dedicated channel if one exists. /// </summary> /// <param name="currentChannel">The current channel.</param> /// <param name="roleplay">The roleplay.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <ModifyEntityResult> StartRoleplayAsync(ITextChannel currentChannel, Roleplay roleplay) { var guild = currentChannel.Guild; var getDedicatedChannelResult = await _dedicatedChannels.GetDedicatedChannelAsync ( guild, roleplay ); // Identify the channel to start the RP in. Preference is given to the roleplay's dedicated channel. var channel = getDedicatedChannelResult.IsSuccess ? getDedicatedChannelResult.Entity : currentChannel; if (roleplay.IsNSFW && !channel.IsNsfw) { return(ModifyEntityResult.FromError ( "This channel is not marked as NSFW, while your roleplay is... naughty!" )); } if (await HasActiveRoleplayAsync(channel)) { var currentRoleplayResult = await GetActiveRoleplayAsync(channel); if (!currentRoleplayResult.IsSuccess) { return(ModifyEntityResult.FromError(currentRoleplayResult)); } var currentRoleplay = currentRoleplayResult.Entity; var timeOfLastMessage = currentRoleplay.Messages.Last().Timestamp; var currentTime = DateTimeOffset.Now; if (timeOfLastMessage < currentTime.AddHours(-4)) { currentRoleplay.IsActive = false; } else { return(ModifyEntityResult.FromError("There's already a roleplay active in this channel.")); } } var start = await _roleplays.StartRoleplayAsync(roleplay, (long)channel.Id); if (!start.IsSuccess) { return(start); } // If the channel in question is the roleplay's dedicated channel, enable it if (!roleplay.DedicatedChannelID.HasValue) { return(ModifyEntityResult.FromSuccess()); } var enableChannel = await _dedicatedChannels.UpdateParticipantPermissionsAsync(guild, roleplay); if (!enableChannel.IsSuccess) { return(enableChannel); } return(ModifyEntityResult.FromSuccess()); }
public async Task ReplayRoleplayAsync ( [NotNull] Roleplay roleplay, DateTimeOffset from = default, DateTimeOffset to = default ) { if (from == default) { from = DateTimeOffset.MinValue; } if (to == default) { to = DateTimeOffset.Now; } var userDMChannel = await this.Context.Message.Author.GetOrCreateDMChannelAsync(); var eb = CreateRoleplayInfoEmbed(roleplay); try { await userDMChannel.SendMessageAsync(string.Empty, false, eb); var messages = roleplay.Messages.Where ( m => m.Timestamp > from && m.Timestamp < to ) .OrderBy(msg => msg.Timestamp).ToList(); var timestampEmbed = this.Feedback.CreateFeedbackEmbed ( this.Context.User, Color.DarkPurple, $"Roleplay began at {messages.First().Timestamp.ToUniversalTime()}" ); await userDMChannel.SendMessageAsync(string.Empty, false, timestampEmbed); if (messages.Count <= 0) { await userDMChannel.SendMessageAsync("No messages found in the specified timeframe."); return; } await this.Feedback.SendConfirmationAsync ( this.Context, $"Replaying \"{roleplay.Name}\". Please check your private messages." ); const int messageCharacterLimit = 2000; var sb = new StringBuilder(messageCharacterLimit); foreach (var message in messages) { var newContent = $"**{message.AuthorNickname}** {message.Contents}\n"; if (sb.Length + newContent.Length >= messageCharacterLimit) { await userDMChannel.SendMessageAsync(sb.ToString()); await Task.Delay(TimeSpan.FromSeconds(2)); sb.Clear(); sb.AppendLine(); } sb.Append(newContent); if (message.ID == messages.Last().ID) { await userDMChannel.SendMessageAsync(sb.ToString()); } } } catch (HttpException hex) when(hex.WasCausedByDMsNotAccepted()) { await this.Feedback.SendWarningAsync ( this.Context, "I can't do that, since you don't accept DMs from non-friends on this server." ); } finally { await userDMChannel.CloseAsync(); } }
public async Task StartRoleplayAsync ( [NotNull] [RequireEntityOwnerOrPermission(Permission.StartStopRoleplay, PermissionTarget.Other)] Roleplay roleplay ) { this.Database.Attach(roleplay); var isNsfwChannel = this.Context.Channel is ITextChannel textChannel && textChannel.IsNsfw; if (roleplay.IsNSFW && !isNsfwChannel) { await this.Feedback.SendErrorAsync(this.Context, "This channel is not marked as NSFW, while your roleplay is... naughty!"); return; } if (await this.Roleplays.HasActiveRoleplayAsync(this.Database, this.Context.Channel)) { await this.Feedback.SendWarningAsync(this.Context, "There's already a roleplay active in this channel."); var currentRoleplayResult = await this.Roleplays.GetActiveRoleplayAsync(this.Database, this.Context); if (!currentRoleplayResult.IsSuccess) { await this.Feedback.SendErrorAsync(this.Context, currentRoleplayResult.ErrorReason); return; } var currentRoleplay = currentRoleplayResult.Entity; var timeOfLastMessage = currentRoleplay.Messages.Last().Timestamp; var currentTime = DateTimeOffset.Now; if (timeOfLastMessage < currentTime.AddHours(-4)) { await this.Feedback.SendConfirmationAsync(this.Context, "However, that roleplay has been inactive for over four hours."); currentRoleplay.IsActive = false; } else { return; } } if (roleplay.ActiveChannelID != (long)this.Context.Channel.Id) { roleplay.ActiveChannelID = (long)this.Context.Channel.Id; } roleplay.IsActive = true; await this.Database.SaveChangesAsync(); var joinedUsers = roleplay.JoinedUsers.Select(p => this.Context.Client.GetUser((ulong)p.User.DiscordID)); var joinedMentions = joinedUsers.Select(u => u.Mention); var participantList = joinedMentions.Humanize(); await this.Feedback.SendConfirmationAsync(this.Context, $"The roleplay \"{roleplay.Name}\" is now active in {MentionUtils.MentionChannel(this.Context.Channel.Id)}."); await this.Context.Channel.SendMessageAsync($"Calling {participantList}!"); }
public async Task <Result <FeedbackMessage> > ShowOrCreateDedicatedRoleplayChannel ( [RequireEntityOwner] [AutocompleteProvider("roleplay::owned")] Roleplay roleplay ) { var getDedicatedChannelResult = DedicatedChannelService.GetDedicatedChannel(roleplay); if (getDedicatedChannelResult.IsSuccess) { var existingDedicatedChannel = getDedicatedChannelResult.Entity; var message = $"\"{roleplay.Name}\" has a dedicated channel at " + $"<#{existingDedicatedChannel}>"; return(new FeedbackMessage(message, _feedback.Theme.Secondary)); } var workingMessage = new Embed { Colour = _feedback.Theme.Secondary, Description = "Setting up dedicated channel..." }; var send = await _feedback.SendContextualEmbedAsync(workingMessage); if (!send.IsSuccess) { return(Result <FeedbackMessage> .FromError(send)); } // The roleplay either doesn't have a channel, or the one it has has been deleted or is otherwise invalid. var result = await _dedicatedChannels.CreateDedicatedChannelAsync(roleplay); if (!result.IsSuccess) { return(Result <FeedbackMessage> .FromError(result)); } var dedicatedChannel = result.Entity; if (!roleplay.IsActive || roleplay.ActiveChannelID == dedicatedChannel.ID) { return(new FeedbackMessage ( $"All done! Your roleplay now has a dedicated channel at <#{dedicatedChannel}>.", _feedback.Theme.Secondary )); } var stopResult = await StopRoleplayAsync(roleplay); if (!stopResult.IsSuccess) { return(stopResult); } var startResult = await StartRoleplayAsync(roleplay); if (!startResult.IsSuccess) { return(startResult); } return(new FeedbackMessage ( $"All done! Your roleplay now has a dedicated channel at <#{dedicatedChannel}>.", _feedback.Theme.Secondary )); }
public async Task ShowRoleplayAsync([NotNull] Roleplay roleplay) { var eb = CreateRoleplayInfoEmbed(roleplay); await this.Feedback.SendEmbedAsync(this.Context, eb); }