/// <summary>
        /// Gets a user's kink preferences by the F-List kink ID.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <param name="discordUser">The discord user.</param>
        /// <param name="onlineKinkID">The F-List kink ID.</param>
        /// <returns>The user's kink preference.</returns>
        public async Task <RetrieveEntityResult <UserKink> > GetUserKinkByFListIDAsync([NotNull] GlobalInfoContext db, IUser discordUser, int onlineKinkID)
        {
            var getKinkResult = await GetKinkByFListIDAsync(db, onlineKinkID);

            if (!getKinkResult.IsSuccess)
            {
                return(RetrieveEntityResult <UserKink> .FromError(getKinkResult));
            }

            var user = await db.GetOrRegisterUserAsync(discordUser);

            var userKink = user.Kinks.FirstOrDefault(k => k.Kink.FListID == onlineKinkID);

            if (!(userKink is null))
            {
                return(RetrieveEntityResult <UserKink> .FromSuccess(userKink));
            }

            var kink          = getKinkResult.Entity;
            var addKinkResult = await AddUserKinkAsync(db, discordUser, kink);

            if (!addKinkResult.IsSuccess)
            {
                return(RetrieveEntityResult <UserKink> .FromError(addKinkResult));
            }

            return(RetrieveEntityResult <UserKink> .FromSuccess(addKinkResult.Entity));
        }
        /// <summary>
        /// Resets the user's kink preferences.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <param name="discordUser">The user.</param>
        /// <returns>A task that must be awaited.</returns>
        public async Task ResetUserKinksAsync([NotNull] GlobalInfoContext db, [NotNull] IUser discordUser)
        {
            var user = await db.GetOrRegisterUserAsync(discordUser);

            user.Kinks.Clear();

            await db.SaveChangesAsync();
        }
Example #3
0
        /// <summary>
        /// Adds the given user to 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 add the user to.</param>
        /// <param name="newUser">The user to add to the roleplay.</param>
        /// <returns>An execution result which may or may not have succeeded.</returns>
        public async Task <ExecuteResult> AddUserToRoleplayAsync
        (
            [NotNull] GlobalInfoContext db,
            [NotNull] SocketCommandContext context,
            [NotNull] Roleplay roleplay,
            [NotNull] IUser newUser
        )
        {
            var isCurrentUser = context.Message.Author.Id == newUser.Id;

            if (roleplay.HasJoined(newUser))
            {
                var errorMessage = isCurrentUser
                                        ? "You're already in that roleplay."
                                        : "The user is aleady in that roleplay.";

                return(ExecuteResult.FromError(CommandError.Unsuccessful, errorMessage));
            }

            if (roleplay.IsKicked(newUser))
            {
                var errorMessage = isCurrentUser
                                        ? "You've been kicked from that roleplay, and can't rejoin unless invited."
                                        : "The user has been kicked from that roleplay, and can't rejoin unless invited.";

                return(ExecuteResult.FromError(CommandError.UnmetPrecondition, errorMessage));
            }

            // Check the invite list for nonpublic roleplays.
            if (!roleplay.IsPublic && !roleplay.IsInvited(newUser))
            {
                var errorMessage = isCurrentUser
                                        ? "You haven't been invited to that roleplay."
                                        : "The user hasn't been invited to that roleplay.";

                return(ExecuteResult.FromError(CommandError.UnmetPrecondition, errorMessage));
            }

            var participantEntry = roleplay.ParticipatingUsers.FirstOrDefault(p => p.User.DiscordID == (long)newUser.Id);

            if (participantEntry is null)
            {
                var user = await db.GetOrRegisterUserAsync(newUser);

                participantEntry = new RoleplayParticipant(roleplay, user, ParticipantStatus.Joined);
                roleplay.ParticipatingUsers.Add(participantEntry);
            }
            else
            {
                participantEntry.Status = ParticipantStatus.Joined;
            }

            await db.SaveChangesAsync();

            return(ExecuteResult.FromSuccess());
        }
        /// <summary>
        /// Adds a kink to a user's preference list.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <param name="discordUser">The user.</param>
        /// <param name="kink">The kink.</param>
        /// <returns>A creation result which may or may not have succeeded.</returns>
        public async Task <CreateEntityResult <UserKink> > AddUserKinkAsync([NotNull] GlobalInfoContext db, [NotNull] IUser discordUser, Kink kink)
        {
            var user = await db.GetOrRegisterUserAsync(discordUser);

            if (user.Kinks.Any(k => k.Kink.FListID == kink.FListID))
            {
                return(CreateEntityResult <UserKink> .FromError(CommandError.MultipleMatches, "The user already has a preference for that kink."));
            }

            var userKink = UserKink.CreateFrom(kink);

            user.Kinks.Add(userKink);

            await db.SaveChangesAsync();

            return(CreateEntityResult <UserKink> .FromSuccess(userKink));
        }
        /// <summary>
        /// Transfers ownership of the given entity to the specified user.
        /// </summary>
        /// <param name="db">The database where the entities are stored.</param>
        /// <param name="newOwner">The new owner.</param>
        /// <param name="newOwnerEntities">The entities that the user already owns.</param>
        /// <param name="entity">The entity to transfer.</param>
        /// <returns>An entity modification result, which may or may not have succeeded.</returns>
        public async Task <ModifyEntityResult> TransferEntityOwnershipAsync
        (
            [NotNull] GlobalInfoContext db,
            [NotNull] IUser newOwner,
            [NotNull] IQueryable <IOwnedNamedEntity> newOwnerEntities,
            [NotNull] IOwnedNamedEntity entity
        )
        {
            if (entity.IsOwner(newOwner))
            {
                return(ModifyEntityResult.FromError
                       (
                           CommandError.Unsuccessful,
                           $"That person already owns the {entity.EntityTypeDisplayName}."
                           .Humanize().Transform(To.SentenceCase)
                       ));
            }

            if (newOwnerEntities.Any(e => string.Equals(e.Name, entity.Name, StringComparison.OrdinalIgnoreCase)))
            {
                return(ModifyEntityResult.FromError
                       (
                           CommandError.MultipleMatches,
                           $"That user already owns a {entity.EntityTypeDisplayName} named {entity.Name}. Please rename it first."
                           .Humanize().Transform(To.SentenceCase)
                       ));
            }

            var newUser = await db.GetOrRegisterUserAsync(newOwner);

            entity.Owner = newUser;

            await db.SaveChangesAsync();

            return(ModifyEntityResult.FromSuccess(ModifyEntityAction.Edited));
        }
Example #6
0
        /// <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());
        }
Example #7
0
        /// <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));
        }
        /// <summary>
        /// Gets a user's kink preference by the kink name.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <param name="discordUser">The user.</param>
        /// <param name="name">The kink name.</param>
        /// <returns>A retrieval result which may or may not have succeeded.</returns>
        public async Task <RetrieveEntityResult <UserKink> > GetUserKinkByNameAsync([NotNull] GlobalInfoContext db, [NotNull] IUser discordUser, string name)
        {
            var user = await db.GetOrRegisterUserAsync(discordUser);

            return(user.Kinks.SelectFromBestLevenshteinMatch(x => x, k => k.Kink.Name, name));
        }
        /// <summary>
        /// Gets the given user's kink preferences.
        /// </summary>
        /// <param name="db">The database.</param>
        /// <param name="discordUser">The user.</param>
        /// <returns>The user's kinks.</returns>
        public async Task <IEnumerable <UserKink> > GetUserKinksAsync([NotNull] GlobalInfoContext db, [NotNull] IUser discordUser)
        {
            var user = await db.GetOrRegisterUserAsync(discordUser);

            return(user.Kinks);
        }
        /// <summary>
        /// Creates a character with the given parameters.
        /// </summary>
        /// <param name="db">The database where the characters are stored.</param>
        /// <param name="context">The context of the command.</param>
        /// <param name="characterName">The name of the character.</param>
        /// <param name="characterAvatarUrl">The character's avatar url.</param>
        /// <param name="characterNickname">The nicknme that should be applied to the user when the character is active.</param>
        /// <param name="characterSummary">The summary of the character.</param>
        /// <param name="characterDescription">The full description of the character.</param>
        /// <returns>A creation result which may or may not have been successful.</returns>
        public async Task <CreateEntityResult <Character> > CreateCharacterAsync
        (
            [NotNull] GlobalInfoContext db,
            [NotNull] ICommandContext context,
            [NotNull] string characterName,
            [NotNull] string characterAvatarUrl,
            [CanBeNull] string characterNickname,
            [CanBeNull] string characterSummary,
            [CanBeNull] string characterDescription
        )
        {
            var owner = await db.GetOrRegisterUserAsync(context.Message.Author);

            var character = new Character
            {
                Owner    = owner,
                ServerID = (long)context.Guild.Id
            };

            var modifyEntityResult = await SetCharacterNameAsync(db, context, character, characterName);

            if (!modifyEntityResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(modifyEntityResult));
            }

            modifyEntityResult = await SetCharacterAvatarAsync(db, character, characterAvatarUrl);

            if (!modifyEntityResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(modifyEntityResult));
            }

            if (!(characterNickname is null))
            {
                modifyEntityResult = await SetCharacterNicknameAsync(db, character, characterNickname);

                if (!modifyEntityResult.IsSuccess)
                {
                    return(CreateEntityResult <Character> .FromError(modifyEntityResult));
                }
            }

            characterSummary   = characterSummary ?? "No summary set.";
            modifyEntityResult = await SetCharacterSummaryAsync(db, character, characterSummary);

            if (!modifyEntityResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(modifyEntityResult));
            }

            characterDescription = characterDescription ?? "No description set.";
            modifyEntityResult   = await SetCharacterDescriptionAsync(db, character, characterDescription);

            if (!modifyEntityResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(modifyEntityResult));
            }

            var defaultPronounFamilyName = this.PronounProviders.FirstOrDefault(p => p.Value is TheyPronounProvider).Value?.Family ?? new TheyPronounProvider().Family;

            modifyEntityResult = await SetCharacterPronounAsync(db, character, defaultPronounFamilyName);

            if (!modifyEntityResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(modifyEntityResult));
            }

            var getDefaultAppearanceResult = await Appearance.CreateDefaultAsync(db, this.Transformations);

            if (!getDefaultAppearanceResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(getDefaultAppearanceResult));
            }

            var defaultAppearance = getDefaultAppearanceResult.Entity;

            character.DefaultAppearance = defaultAppearance;
            character.CurrentAppearance = defaultAppearance;

            owner.Characters.Add(character);
            await db.Characters.AddAsync(character);

            await db.SaveChangesAsync();

            var getCharacterResult = await GetUserCharacterByNameAsync(db, context, context.Message.Author, characterName);

            if (!getCharacterResult.IsSuccess)
            {
                return(CreateEntityResult <Character> .FromError(getCharacterResult));
            }

            return(CreateEntityResult <Character> .FromSuccess(getCharacterResult.Entity));
        }