Ejemplo n.º 1
0
        public async Task <ModifyEntityResult> MakeCharacterCurrentOnServerAsync
        (
            [NotNull] ICommandContext context,
            [NotNull] IGuild discordServer,
            [NotNull] Character character
        )
        {
            var getInvokerResult = await _users.GetOrRegisterUserAsync(context.User);

            if (!getInvokerResult.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getInvokerResult));
            }

            var user = getInvokerResult.Entity;

            if (character.IsCurrent)
            {
                return(ModifyEntityResult.FromError("The character is already current on the server."));
            }

            await ClearCurrentCharacterOnServerAsync(user, discordServer);

            character.IsCurrent = true;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 2
0
        public async Task <ModifyEntityResult> SetDefaultCharacterForUserAsync
        (
            [NotNull] ICommandContext context,
            [NotNull] Character newDefaultCharacter,
            [NotNull] User targetUser
        )
        {
            var getDefaultCharacterResult = await GetDefaultCharacterAsync(targetUser, context.Guild);

            if (getDefaultCharacterResult.IsSuccess)
            {
                var currentDefault = getDefaultCharacterResult.Entity;
                if (currentDefault == newDefaultCharacter)
                {
                    var isCurrentUser = context.Message.Author.Id == (ulong)newDefaultCharacter.Owner.DiscordID;

                    var errorMessage = isCurrentUser
                        ? "That's already your default character."
                        : "That's already the user's default character.";

                    return(ModifyEntityResult.FromError(errorMessage));
                }

                currentDefault.IsDefault = false;
            }

            newDefaultCharacter.IsDefault = true;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Sets the contents of the given note.
        /// </summary>
        /// <param name="note">The note.</param>
        /// <param name="content">The content.</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> SetNoteContentsAsync
        (
            UserNote note,
            string content,
            CancellationToken ct = default
        )
        {
            if (content.IsNullOrWhitespace())
            {
                return(ModifyEntityResult.FromError("You must provide some content for the note."));
            }

            if (content.Length > 1024)
            {
                return(ModifyEntityResult.FromError
                       (
                           "The note is too long. It can be at most 1024 characters."
                       ));
            }

            if (note.Content == content)
            {
                return(ModifyEntityResult.FromError("That's already the note's contents."));
            }

            note.Content = content;
            note.NotifyUpdate();

            await _database.SaveChangesAsync(ct);

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 4
0
        public async Task <ModifyEntityResult> GrantPermissionAsync
        (
            [NotNull] IRole discordRole,
            [NotNull] IPermission grantedPermission,
            PermissionTarget target
        )
        {
            // Special All target handling
            if (target == PermissionTarget.All)
            {
                var grantSelfResult = await GrantPermissionAsync
                                      (
                    discordRole,
                    grantedPermission,
                    PermissionTarget.Self
                                      );

                var grantOtherResult = await GrantPermissionAsync
                                       (
                    discordRole,
                    grantedPermission,
                    PermissionTarget.Other
                                       );

                if (grantSelfResult.IsSuccess || grantOtherResult.IsSuccess)
                {
                    return(ModifyEntityResult.FromSuccess());
                }

                // Both are false, so we'll just inherit the self result.
                return(ModifyEntityResult.FromError(grantSelfResult));
            }

            var getPermissionResult = await GetOrCreateRolePermissionAsync
                                      (
                discordRole,
                grantedPermission,
                target
                                      );

            if (!getPermissionResult.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getPermissionResult));
            }

            var permission = getPermissionResult.Entity;

            if (permission.IsGranted)
            {
                return(ModifyEntityResult.FromError("The user already has permission to do that."));
            }

            permission.IsGranted = true;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 5
0
        public async Task <ModifyEntityResult> RevokePermissionAsync
        (
            [NotNull] IRole discordRole,
            [NotNull] IPermission revokedPermission,
            PermissionTarget target
        )
        {
            // Special All target handling
            if (target == PermissionTarget.All)
            {
                var revokeSelfResult = await RevokePermissionAsync
                                       (
                    discordRole,
                    revokedPermission,
                    PermissionTarget.Self
                                       );

                var revokeOtherResult = await RevokePermissionAsync
                                        (
                    discordRole,
                    revokedPermission,
                    PermissionTarget.Other
                                        );

                if (revokeSelfResult.IsSuccess || revokeOtherResult.IsSuccess)
                {
                    return(ModifyEntityResult.FromSuccess());
                }

                // Both are false, so we'll just inherit the self result.
                return(ModifyEntityResult.FromError(revokeSelfResult));
            }

            var getPermissionResult = await GetOrCreateRolePermissionAsync
                                      (
                discordRole,
                revokedPermission,
                target
                                      );

            if (!getPermissionResult.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getPermissionResult));
            }

            var permission = getPermissionResult.Entity;

            if (!permission.IsGranted)
            {
                return(ModifyEntityResult.FromError("The role is already prohibited from doing that."));
            }

            permission.IsGranted = false;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Sets the PDF data of a given dossier. This overwrites existing data.
        /// </summary>
        /// <param name="dossier">The dosser for which to set the data.</param>
        /// <param name="message">The message containing the PDF data.</param>
        /// <param name="ct">The cancellation token in use.</param>
        /// <returns>An entity modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> SetDossierDataAsync
        (
            Dossier dossier,
            IUserMessage message,
            CancellationToken ct = default
        )
        {
            if (message.Attachments.Count <= 0)
            {
                return(ModifyEntityResult.FromError("No file provided. Please attach a PDF with the dossier data."));
            }

            var dossierAttachment = message.Attachments.First();

            if (!dossierAttachment.Filename.EndsWith(".pdf", StringComparison.OrdinalIgnoreCase))
            {
                return(ModifyEntityResult.FromError("Invalid dossier format. PDF files are accepted."));
            }

            using var client = new HttpClient
                  {
                      Timeout = TimeSpan.FromSeconds(2)
                  };

            try
            {
                var dossierPath = GetDossierDataPath(dossier);
                await using var dataStream = await client.GetStreamAsync(dossierAttachment.Url);

                try
                {
                    await using var dataFile = _content.FileSystem.CreateFile(dossierPath);
                    await dataStream.CopyToAsync(dataFile, ct);

                    if (!await dataFile.HasSignatureAsync(FileSignatures.PDF))
                    {
                        return(ModifyEntityResult.FromError
                               (
                                   "Invalid dossier format. PDF files are accepted."
                               ));
                    }
                }
                catch (Exception e)
                {
                    return(ModifyEntityResult.FromError(e));
                }
            }
            catch (TaskCanceledException)
            {
                return(ModifyEntityResult.FromError
                       (
                           "The download operation timed out. The data file was not added."
                       ));
            }

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Blacklists the given user, preventing them from transforming the <paramref name="discordUser"/>.
        /// </summary>
        /// <param name="discordUser">The user to modify.</param>
        /// <param name="blacklistedUser">The user to add to the blacklist.</param>
        /// <returns>An entity modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> BlacklistUserAsync
        (
            IUser discordUser,
            IUser blacklistedUser
        )
        {
            if (discordUser == blacklistedUser)
            {
                return(ModifyEntityResult.FromError("You can't blacklist yourself."));
            }

            var getGlobalProtectionResult = await GetOrCreateGlobalUserProtectionAsync(discordUser);

            if (!getGlobalProtectionResult.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getGlobalProtectionResult));
            }

            var protection = getGlobalProtectionResult.Entity;

            if (protection.Blacklist.Any(u => u.DiscordID == (long)blacklistedUser.Id))
            {
                return(ModifyEntityResult.FromError("You've already blacklisted that user."));
            }

            var protectionEntry = protection.UserListing.FirstOrDefault(u => u.User.DiscordID == (long)discordUser.Id);

            if (protectionEntry is null)
            {
                var getUserResult = await _users.GetOrRegisterUserAsync(blacklistedUser);

                if (!getUserResult.IsSuccess)
                {
                    return(ModifyEntityResult.FromError(getUserResult));
                }

                var user = getUserResult.Entity;

                protectionEntry = new UserProtectionEntry(protection, user)
                {
                    Type = ListingType.Blacklist
                };

                // Ensure we don't try to add the user we got from another context
                _database.Update(protectionEntry);
                protection.UserListing.Add(protectionEntry);
            }
            else
            {
                protectionEntry.Type = ListingType.Blacklist;
            }

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
        private async Task <ModifyEntityResult> ConfigureDefaultUserRolePermissions
        (
            IGuild guild,
            IGuildChannel dedicatedChannel
        )
        {
            var getServer = await _servers.GetOrRegisterServerAsync(guild);

            if (!getServer.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getServer));
            }

            var server      = getServer.Entity;
            var getSettings = await _serverSettings.GetOrCreateServerRoleplaySettingsAsync(server);

            if (!getSettings.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getSettings));
            }

            var settings = getSettings.Entity;

            var denyView = OverwritePermissions.InheritAll.Modify
                           (
                viewChannel: PermValue.Deny,
                sendMessages: PermValue.Deny,
                addReactions: PermValue.Deny
                           );

            // Configure visibility for everyone
            // viewChannel starts off as deny, since starting or stopping the RP will set the correct permissions.
            IRole defaultUserRole;

            if (settings.DefaultUserRole.HasValue)
            {
                var defaultRole = guild.GetRole((ulong)settings.DefaultUserRole.Value);
                defaultUserRole = defaultRole ?? guild.EveryoneRole;
            }
            else
            {
                defaultUserRole = guild.EveryoneRole;
            }

            await dedicatedChannel.AddPermissionOverwriteAsync(defaultUserRole, denyView);

            if (defaultUserRole != guild.EveryoneRole)
            {
                // Also override @everyone so it can't see anything
                await dedicatedChannel.AddPermissionOverwriteAsync(guild.EveryoneRole, denyView);
            }

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 9
0
        /// <summary>
        /// Sets whether or not a roleplay is public.
        /// </summary>
        /// <param name="roleplay">The roleplay to set the value in.</param>
        /// <param name="isPublic">The new value.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> SetRoleplayIsPublicAsync(Roleplay roleplay, bool isPublic)
        {
            if (roleplay.IsPublic == isPublic)
            {
                return(ModifyEntityResult.FromError($"The roleplay is already {(isPublic ? "public" : "private")}."));
            }

            roleplay.IsPublic = isPublic;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 10
0
        /// <summary>
        /// Sets the summary of the given roleplay.
        /// </summary>
        /// <param name="roleplay">The roleplay to set the summary of.</param>
        /// <param name="newRoleplaySummary">The new summary.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> SetRoleplaySummaryAsync(Roleplay roleplay, string newRoleplaySummary)
        {
            if (string.IsNullOrWhiteSpace(newRoleplaySummary))
            {
                return(ModifyEntityResult.FromError("You need to provide a new summary."));
            }

            roleplay.Summary = newRoleplaySummary;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 11
0
        /// <summary>
        /// Sets the access conditions for the given character role.
        /// </summary>
        /// <param name="role">The character role.</param>
        /// <param name="access">The access conditions.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> SetCharacterRoleAccessAsync(CharacterRole role, RoleAccess access)
        {
            if (role.Access == access)
            {
                return(ModifyEntityResult.FromError("The role already has those access conditions."));
            }

            role.Access = access;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 12
0
        /// <summary>
        /// Clears the first-join message, if one is set.
        /// </summary>
        /// <param name="server">The server.</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> ClearJoinMessageAsync(Server server, CancellationToken ct = default)
        {
            if (server.JoinMessage is null)
            {
                return(ModifyEntityResult.FromError("No join message has been set."));
            }

            server.JoinMessage = null;
            await _database.SaveChangesAsync(ct);

            return(ModifyEntityResult.FromSuccess());
        }
        /// <summary>
        /// Resets the channel permissions for the given roleplay to their default values.
        /// </summary>
        /// <param name="guild">The guild.</param>
        /// <param name="roleplay">The roleplay.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> ResetChannelPermissionsAsync(IGuild guild, Roleplay roleplay)
        {
            var getChannel = await GetDedicatedChannelAsync(guild, roleplay);

            if (!getChannel.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getChannel));
            }

            var channel = getChannel.Entity;

            return(await ResetChannelPermissionsAsync(channel, roleplay));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Disables the given autorole.
        /// </summary>
        /// <param name="autorole">The autorole.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> DisableAutoroleAsync(AutoroleConfiguration autorole)
        {
            if (!autorole.IsEnabled)
            {
                return(ModifyEntityResult.FromError("The autorole is already disabled."));
            }

            autorole.IsEnabled = false;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
        /// <summary>
        /// Invites the given user to the given roleplay.
        /// </summary>
        /// <param name="roleplay">The roleplay to invite the user to.</param>
        /// <param name="discordUser">The user to invite.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> InviteUserToRoleplayAsync(Roleplay roleplay, IGuildUser discordUser)
        {
            var getUser = await _users.GetOrRegisterUserAsync(discordUser);

            if (!getUser.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getUser));
            }

            var user = getUser.Entity;

            return(await _roleplays.InviteUserToRoleplayAsync(roleplay, user));
        }
        /// <summary>
        /// Makes the given character the given user's current character.
        /// </summary>
        /// <param name="guildUser">The user.</param>
        /// <param name="character">The character.</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> MakeCharacterCurrentAsync
        (
            IGuildUser guildUser,
            Character character,
            CancellationToken ct = default
        )
        {
            var getUser = await _users.GetOrRegisterUserAsync(guildUser, ct);

            if (!getUser.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getUser));
            }

            var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild, ct);

            if (!getServer.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getServer));
            }

            var user   = getUser.Entity;
            var server = getServer.Entity;

            var getOriginalCharacter = await _characters.GetCurrentCharacterAsync(user, server, ct);

            var makeCurrent = await _characters.MakeCharacterCurrentAsync(user, server, character, ct);

            if (!makeCurrent.IsSuccess)
            {
                return(makeCurrent);
            }

            // Update the user's nickname
            var updateNickname = await UpdateUserNickname(guildUser, ct);

            if (!updateNickname.IsSuccess)
            {
                return(updateNickname);
            }

            var originalCharacter = getOriginalCharacter.IsSuccess ? getOriginalCharacter.Entity : null;
            var updateRoles       = await _characterRoles.UpdateUserRolesAsync(guildUser, originalCharacter, ct);

            if (!updateRoles.IsSuccess)
            {
                return(updateRoles);
            }

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 17
0
        /// <summary>
        /// Stops the given roleplay.
        /// </summary>
        /// <param name="roleplay">The roleplay to stop.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task <ModifyEntityResult> StopRoleplayAsync(Roleplay roleplay)
        {
            if (!roleplay.IsActive)
            {
                return(ModifyEntityResult.FromError("The roleplay is not active."));
            }

            roleplay.IsActive        = false;
            roleplay.ActiveChannelID = null;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 18
0
        public async Task <ModifyEntityResult> AddToOrUpdateMessageInRoleplayAsync
        (
            [NotNull] Roleplay roleplay,
            [NotNull] IMessage message
        )
        {
            if (!roleplay.HasJoined(message.Author))
            {
                return(ModifyEntityResult.FromError("The given message was not authored by a participant of the roleplay."));
            }

            var userNick = message.Author.Username;

            if (message.Author is SocketGuildUser guildUser && !string.IsNullOrEmpty(guildUser.Nickname))
            {
                userNick = guildUser.Nickname;
            }

            if (roleplay.Messages.Any(m => m.DiscordMessageID == (long)message.Id))
            {
                // Edit the existing message
                var existingMessage = roleplay.Messages.Find(m => m.DiscordMessageID == (long)message.Id);

                if (existingMessage.Contents.Equals(message.Content))
                {
                    return(ModifyEntityResult.FromError("Nothing to do; message content match."));
                }

                existingMessage.Contents = message.Content;

                // Update roleplay timestamp
                roleplay.LastUpdated = DateTime.Now;

                await _database.SaveChangesAsync();

                return(ModifyEntityResult.FromSuccess());
            }

            var roleplayMessage = UserMessage.FromDiscordMessage(message, userNick);

            roleplay.Messages.Add(roleplayMessage);

            // Update roleplay timestamp
            roleplay.LastUpdated = DateTime.Now;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 19
0
        public async Task <ModifyEntityResult> SetCharacterNameAsync
        (
            [NotNull] ICommandContext context,
            [NotNull] Character character,
            [NotNull] string newCharacterName
        )
        {
            if (string.IsNullOrWhiteSpace(newCharacterName))
            {
                return(ModifyEntityResult.FromError("You need to provide a name."));
            }

            if (string.Equals(character.Name, newCharacterName, StringComparison.OrdinalIgnoreCase))
            {
                return(ModifyEntityResult.FromError("The character already has that name."));
            }

            if (newCharacterName.Contains("\""))
            {
                return(ModifyEntityResult.FromError("The name may not contain double quotes."));
            }

            var isCurrentUser = context.Message.Author.Id == (ulong)character.Owner.DiscordID;

            if (!await IsCharacterNameUniqueForUserAsync(character.Owner, newCharacterName, context.Guild))
            {
                var errorMessage = isCurrentUser
                    ? "You already have a character with that name."
                    : "The user already has a character with that name.";

                return(ModifyEntityResult.FromError(errorMessage));
            }

            var commandModule = _commands.Modules.FirstOrDefault(m => m.Name == "character");

            if (!(commandModule is null))
            {
                var validNameResult = _ownedEntities.IsEntityNameValid(commandModule.GetAllCommandNames(), newCharacterName);
                if (!validNameResult.IsSuccess)
                {
                    return(ModifyEntityResult.FromError(validNameResult));
                }
            }

            character.Name = newCharacterName;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 20
0
        /// <summary>
        /// Starts the given roleplay.
        /// </summary>
        /// <param name="roleplay">The roleplay.</param>
        /// <param name="channelID">The Discord ID of the channel.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> StartRoleplayAsync(Roleplay roleplay, long channelID)
        {
            if (roleplay.IsActive && roleplay.ActiveChannelID == channelID)
            {
                return(ModifyEntityResult.FromError("The roleplay is already running."));
            }

            roleplay.ActiveChannelID = channelID;
            roleplay.IsActive        = true;
            roleplay.LastUpdated     = DateTime.Now;

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 21
0
        /// <summary>
        /// Sets the custom role of a character.
        /// </summary>
        /// <param name="guildUser">The owner of the character.</param>
        /// <param name="character">The character.</param>
        /// <param name="characterRole">The role to set.</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> SetCharacterRoleAsync
        (
            IGuildUser guildUser,
            Character character,
            CharacterRole characterRole,
            CancellationToken ct = default
        )
        {
            if (character.Role == characterRole)
            {
                return(ModifyEntityResult.FromError("The character already has that role."));
            }

            if (character.IsCurrent)
            {
                if (!(character.Role is null))
                {
                    var oldRole = guildUser.Guild.GetRole((ulong)character.Role.DiscordID);
                    if (!(oldRole is null))
                    {
                        var removeRole = await _discord.RemoveUserRoleAsync(guildUser, oldRole);

                        if (!removeRole.IsSuccess)
                        {
                            return(removeRole);
                        }
                    }
                }

                var newRole = guildUser.Guild.GetRole((ulong)characterRole.DiscordID);
                if (newRole is null)
                {
                    return(ModifyEntityResult.FromError("Failed to get the new role."));
                }

                var addRole = await _discord.AddUserRoleAsync(guildUser, newRole);

                if (!addRole.IsSuccess)
                {
                    return(addRole);
                }
            }

            character.Role = characterRole;
            await _database.SaveChangesAsync(ct);

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 22
0
        public async Task <ModifyEntityResult> InviteUserAsync
        (
            [NotNull] Roleplay roleplay,
            [NotNull] IUser invitedUser
        )
        {
            if (roleplay.IsPublic && !roleplay.IsKicked(invitedUser))
            {
                return(ModifyEntityResult.FromError("The roleplay is not set to private."));
            }

            if (roleplay.InvitedUsers.Any(p => p.User.DiscordID == (long)invitedUser.Id))
            {
                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 == (long)invitedUser.Id);

            if (participantEntry is null)
            {
                var getUserResult = await _users.GetOrRegisterUserAsync(invitedUser);

                if (!getUserResult.IsSuccess)
                {
                    return(ModifyEntityResult.FromError(getUserResult));
                }

                var user = getUserResult.Entity;

                // Ensure the user is attached, so we don't create any conflicts.
                _database.Attach(user);
                participantEntry = new RoleplayParticipant(roleplay, user)
                {
                    Status = ParticipantStatus.Invited
                };

                roleplay.ParticipatingUsers.Add(participantEntry);
            }
            else
            {
                participantEntry.Status = ParticipantStatus.Invited;
            }

            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 23
0
        /// <summary>
        /// Sets the summary of the dossier.
        /// </summary>
        /// <param name="dossier">The dossier to modify.</param>
        /// /// <param name="newSummary">The new summary.</param>
        /// <returns>An entity modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> SetDossierSummaryAsync
        (
            Dossier dossier,
            string newSummary
        )
        {
            if (newSummary.IsNullOrWhitespace())
            {
                return(ModifyEntityResult.FromError("You need to provide a summary."));
            }

            dossier.Summary = newSummary;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 24
0
        public async Task <ModifyEntityResult> SetRoleplayIsNSFWAsync
        (
            [NotNull] Roleplay roleplay,
            bool isNSFW
        )
        {
            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();

            return(ModifyEntityResult.FromSuccess());
        }
        /// <summary>
        /// Consumes a message, adding it to the active roleplay in its channel if the author is a participant.
        /// </summary>
        /// <param name="message">The received message.</param>
        /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns>
        public async Task <ModifyEntityResult> ConsumeMessageAsync(IUserMessage message)
        {
            if (!(message.Channel is ITextChannel textChannel))
            {
                return(ModifyEntityResult.FromError("The message did not come from a text channel."));
            }

            var result = await GetActiveRoleplayAsync(textChannel);

            if (!result.IsSuccess)
            {
                return(ModifyEntityResult.FromError(result));
            }

            var roleplay = result.Entity;

            if (!roleplay.HasJoined(message.Author))
            {
                return(ModifyEntityResult.FromError("The given message was not authored by a participant of the roleplay."));
            }

            var userNick = message.Author.Username;

            if (message.Author is IGuildUser guildUser && !string.IsNullOrEmpty(guildUser.Nickname))
            {
                userNick = guildUser.Nickname;
            }

            var getAuthor = await _users.GetOrRegisterUserAsync(message.Author);

            if (!getAuthor.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getAuthor));
            }

            var author = getAuthor.Entity;

            return(await _roleplays.AddOrUpdateMessageInRoleplayAsync
                   (
                       roleplay,
                       author,
                       (long)message.Id,
                       message.Timestamp,
                       userNick,
                       message.Content
                   ));
        }
        /// <summary>
        /// Updates the user's current nickname based on their character.
        /// </summary>
        /// <param name="guildUser">The user.</param>
        /// <param name="ct">The cancellation token in use.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        private async Task <ModifyEntityResult> UpdateUserNickname
        (
            IGuildUser guildUser,
            CancellationToken ct = default
        )
        {
            var getUser = await _users.GetOrRegisterUserAsync(guildUser, ct);

            if (!getUser.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getUser));
            }

            var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild, ct);

            if (!getServer.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getServer));
            }

            var user   = getUser.Entity;
            var server = getServer.Entity;

            string newNick;
            var    getNewCharacter = await _characters.GetCurrentCharacterAsync(user, server, ct);

            if (getNewCharacter.IsSuccess)
            {
                var newCharacter = getNewCharacter.Entity;
                newNick = newCharacter.Nickname.IsNullOrWhitespace()
                    ? guildUser.Username
                    : newCharacter.Nickname;
            }
            else
            {
                newNick = guildUser.Username;
            }

            var setNick = await _discord.SetUserNicknameAsync(guildUser, newNick);

            if (!setNick.IsSuccess)
            {
                return(setNick);
            }

            return(ModifyEntityResult.FromSuccess());
        }
        /// <summary>
        /// Transfers ownership of the given roleplay to the given user.
        /// </summary>
        /// <param name="newDiscordOwner">The new owner.</param>
        /// <param name="roleplay">The roleplay to transfer.</param>
        /// <returns>An execution result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> TransferRoleplayOwnershipAsync
        (
            IGuildUser newDiscordOwner,
            Roleplay roleplay
        )
        {
            var getNewOwner = await _users.GetOrRegisterUserAsync(newDiscordOwner);

            if (!getNewOwner.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getNewOwner));
            }

            var newOwner = getNewOwner.Entity;

            return(await _roleplays.TransferRoleplayOwnershipAsync(newOwner, roleplay));
        }
Ejemplo n.º 28
0
        /// <summary>
        /// Clears the default character from the given user.
        /// </summary>
        /// <param name="user">The user to clear the default character of.</param>
        /// <param name="server">The server the user is on.</param>
        /// <returns>A modification result which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> ClearDefaultCharacterAsync(User user, Server server)
        {
            user   = _database.NormalizeReference(user);
            server = _database.NormalizeReference(server);

            var getDefaultCharacterResult = await GetDefaultCharacterAsync(user, server);

            if (!getDefaultCharacterResult.IsSuccess)
            {
                return(ModifyEntityResult.FromError("That user doesn't have a default character."));
            }

            getDefaultCharacterResult.Entity.IsDefault = false;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 29
0
        /// <summary>
        /// Revokes consent to store user data for a given user.
        /// </summary>
        /// <param name="discordUser">The user that has revoked consent.</param>
        /// <returns>A task that must be awaited.</returns>
        public async Task <ModifyEntityResult> RevokeUserConsentAsync(IUser discordUser)
        {
            var userConsent = await _database.UserConsents.FirstOrDefaultAsync
                              (
                uc => uc.DiscordID == (long)discordUser.Id
                              );

            if (userConsent is null)
            {
                return(ModifyEntityResult.FromError("The user has not consented."));
            }

            userConsent.HasConsented = false;
            await _database.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess());
        }
Ejemplo n.º 30
0
        /// <summary>
        /// Logs the ambassador into Discord.
        /// </summary>
        /// <returns>A task representing the login action.</returns>
        public async Task <ModifyEntityResult> LoginAsync()
        {
            var contentService = _services.GetRequiredService <ContentService>();

            var getTokenResult = await contentService.GetBotTokenAsync();

            if (!getTokenResult.IsSuccess)
            {
                return(ModifyEntityResult.FromError(getTokenResult));
            }

            var token = getTokenResult.Entity.Trim();

            await _client.LoginAsync(TokenType.Bot, token);

            return(ModifyEntityResult.FromSuccess());
        }