/// <summary> /// Gets or creates a set of statistics for a given user. /// </summary> /// <param name="discordUser">The user.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserStatistics> > GetOrCreateUserStatisticsAsync ( IUser discordUser ) { var existingStatistics = await _database.UserStatistics.AsQueryable().FirstOrDefaultAsync ( s => s.User.DiscordID == (long)discordUser.Id ); if (!(existingStatistics is null)) { return(existingStatistics); } var getUser = await _users.GetOrRegisterUserAsync(discordUser); if (!getUser.IsSuccess) { return(CreateEntityResult <UserStatistics> .FromError(getUser)); } var user = getUser.Entity; var newStatistics = _database.CreateProxy <UserStatistics>(user); _database.UserStatistics.Update(newStatistics); await _database.SaveChangesAsync(); return(newStatistics); }
/// <summary> /// Gets or creates a set of statistics for a given user. /// </summary> /// <param name="discordUser">The user.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserStatistics> > GetOrCreateUserStatisticsAsync ( IUser discordUser, CancellationToken ct = default ) { var statistics = await _database.UserStatistics.ServersideQueryAsync ( q => q .Where(s => s.User.DiscordID == (long)discordUser.Id) .SingleOrDefaultAsync(ct) ); if (!(statistics is null)) { return(statistics); } var getUser = await _users.GetOrRegisterUserAsync(discordUser, ct); if (!getUser.IsSuccess) { return(CreateEntityResult <UserStatistics> .FromError(getUser)); } var user = getUser.Entity; var newStatistics = _database.CreateProxy <UserStatistics>(user); _database.UserStatistics.Update(newStatistics); await _database.SaveChangesAsync(ct); return(newStatistics); }
/// <summary> /// Packs the given stream into a base64-encoded string, type-prefixed string. /// </summary> /// <param name="stream">The stream.</param> /// <param name="ct">The cancellation token for this operation.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public static async Task <CreateEntityResult <Optional <string?> > > PackImageAsync ( Optional <Stream?> stream, CancellationToken ct = default ) { Optional <string?> imageData = default; if (!stream.HasValue) { return(imageData); } if (stream.Value is null) { imageData = new Optional <string?>(null); } else { var packImage = await PackImageAsync(stream.Value, ct); if (!packImage.IsSuccess) { return(CreateEntityResult <Optional <string?> > .FromError(packImage)); } imageData = packImage.Entity; } return(imageData); }
/// <summary> /// Creates the settings for the given Discord guild. /// </summary> /// <param name="discordServer">The server.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <ServerModerationSettings> > CreateServerSettingsAsync ( IGuild discordServer ) { var existingEntity = await GetServerSettingsAsync(discordServer); if (existingEntity.IsSuccess) { return(CreateEntityResult <ServerModerationSettings> .FromError("That server already has settings.")); } var getServer = await _servers.GetOrRegisterServerAsync(discordServer); if (!getServer.IsSuccess) { return(CreateEntityResult <ServerModerationSettings> .FromError(getServer)); } var server = getServer.Entity; var settings = new ServerModerationSettings(server); _database.ServerSettings.Update(settings); await _database.SaveChangesAsync(); return(settings); }
public async Task <CreateEntityResult <CharacterRole> > CreateCharacterRoleAsync ( [NotNull] IRole role, RoleAccess access ) { var getExistingRoleResult = await GetCharacterRoleAsync(role); if (getExistingRoleResult.IsSuccess) { return(CreateEntityResult <CharacterRole> .FromError ( "That role is already registered as a character role." )); } var getServerResult = await _servers.GetOrRegisterServerAsync(role.Guild); if (!getServerResult.IsSuccess) { return(CreateEntityResult <CharacterRole> .FromError(getServerResult)); } var server = getServerResult.Entity; var characterRole = new CharacterRole(server, (long)role.Id, access); _database.CharacterRoles.Update(characterRole); await _database.SaveChangesAsync(); return(CreateEntityResult <CharacterRole> .FromSuccess(characterRole)); }
/// <summary> /// Creates a new dossier with the given title, summary, and data. /// </summary> /// <param name="title">The title of the dossier.</param> /// <param name="summary">The summary of the dossier.</param> /// <returns>A creation task which may or may not have succeeded.</returns> public async Task <CreateEntityResult <Dossier> > CreateDossierAsync ( string title, string summary ) { var dossier = new Dossier(title, summary); var setTitleResult = await SetDossierTitleAsync(dossier, title); if (!setTitleResult.IsSuccess) { return(CreateEntityResult <Dossier> .FromError(setTitleResult)); } var setSummary = await SetDossierSummaryAsync(dossier, summary); if (!setSummary.IsSuccess) { return(CreateEntityResult <Dossier> .FromError(setSummary)); } await _database.Dossiers.AddAsync(dossier); await _database.SaveChangesAsync(); return(CreateEntityResult <Dossier> .FromSuccess((await GetDossierByTitleAsync(title)).Entity)); }
/// <summary> /// Creates a new autorole configuration. /// </summary> /// <param name="discordRole">The role to create the configuration for.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <AutoroleConfiguration> > CreateAutoroleAsync(IRole discordRole) { if (await HasAutoroleAsync(discordRole)) { return(CreateEntityResult <AutoroleConfiguration> .FromError ( "That role already has an autorole configuration." )); } var getServer = await _servers.GetOrRegisterServerAsync(discordRole.Guild); if (!getServer.IsSuccess) { return(CreateEntityResult <AutoroleConfiguration> .FromError(getServer)); } var server = getServer.Entity; var autorole = _database.CreateProxy <AutoroleConfiguration>(server, discordRole); if (autorole is null) { return(CreateEntityResult <AutoroleConfiguration> .FromError ( "Failed to create a valid proxy for the autorole." )); } _database.Autoroles.Update(autorole); await _database.SaveChangesAsync(); return(autorole); }
/// <summary> /// Creates a new character role from the given Discord role and access condition. /// </summary> /// <param name="role">The discord role.</param> /// <param name="access">The access conditions.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <CharacterRole> > CreateCharacterRoleAsync ( IRole role, RoleAccess access, CancellationToken ct = default ) { var getExistingRoleResult = await GetCharacterRoleAsync(role, ct); if (getExistingRoleResult.IsSuccess) { return(CreateEntityResult <CharacterRole> .FromError ( "That role is already registered as a character role." )); } var getServerResult = await _servers.GetOrRegisterServerAsync(role.Guild, ct); if (!getServerResult.IsSuccess) { return(CreateEntityResult <CharacterRole> .FromError(getServerResult)); } var server = getServerResult.Entity; var characterRole = _database.CreateProxy <CharacterRole>(server, (long)role.Id, access); _database.CharacterRoles.Update(characterRole); await _database.SaveChangesAsync(ct); return(characterRole); }
/// <summary> /// Packs the given stream into a base64-encoded string, type-prefixed string. /// </summary> /// <param name="stream">The stream.</param> /// <param name="ct">The cancellation token for this operation.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public static async Task <CreateEntityResult <string> > PackImageAsync ( Stream stream, CancellationToken ct = default ) { await using var memoryStream = new MemoryStream(); await stream.CopyToAsync(memoryStream, ct); var imageData = memoryStream.ToArray(); string?mediaType = null; if (imageData.IsPNG()) { mediaType = "png"; } else if (imageData.IsJPG()) { mediaType = "jpeg"; } else if (imageData.IsGIF()) { mediaType = "gif"; } if (mediaType is null) { return(CreateEntityResult <string> .FromError("Unknown or unsupported image format.")); } return($"data:image/{mediaType};base64,{Convert.ToBase64String(imageData)}"); }
/// <summary> /// Gets or creates a set of per-channel statistics for a given user. /// </summary> /// <param name="discordUser">The user.</param> /// <param name="discordChannel">The channel.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserChannelStatistics> > GetOrCreateUserChannelStatisticsAsync ( IGuildUser discordUser, ITextChannel discordChannel, CancellationToken ct = default ) { var getServerStats = await GetOrCreateUserServerStatisticsAsync(discordUser, ct); if (!getServerStats.IsSuccess) { return(CreateEntityResult <UserChannelStatistics> .FromError(getServerStats)); } var serverStats = getServerStats.Entity; var existingStats = serverStats.ChannelStatistics.FirstOrDefault ( s => s.ChannelID == (long)discordChannel.Id ); if (!(existingStats is null)) { return(existingStats); } var newStats = _database.CreateProxy <UserChannelStatistics>(discordChannel); _database.Update(newStats); serverStats.ChannelStatistics.Add(newStats); await _database.SaveChangesAsync(ct); return(newStats); }
/// <summary> /// Registers the given permission type, making it available to the system. /// </summary> /// <param name="permissionType">The permission type.</param> /// <param name="services">The application's services.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public CreateEntityResult <IPermission> RegisterPermission ( Type permissionType, IServiceProvider services ) { if (_registeredPermissions.ContainsKey(permissionType)) { return(CreateEntityResult <IPermission> .FromError("The given permission has already been registered.")); } IPermission permissionInstance; try { permissionInstance = (IPermission)ActivatorUtilities.CreateInstance(services, permissionType); } catch (Exception e) { return(CreateEntityResult <IPermission> .FromError(e)); } if (_registeredPermissions.Values.Any(p => p.UniqueIdentifier == permissionInstance.UniqueIdentifier)) { return(CreateEntityResult <IPermission> .FromError ( "A permission with that identifier has already been registered." )); } _registeredPermissions.Add(permissionType, permissionInstance); return(CreateEntityResult <IPermission> .FromSuccess(permissionInstance)); }
/// <summary> /// Creates a new autorole configuration. /// </summary> /// <param name="discordRole">The role to create the configuration for.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <AutoroleConfiguration> > CreateAutoroleAsync ( IRole discordRole, CancellationToken ct = default ) { if (await HasAutoroleAsync(discordRole, ct)) { return(CreateEntityResult <AutoroleConfiguration> .FromError ( "That role already has an autorole configuration." )); } var getServer = await _servers.GetOrRegisterServerAsync(discordRole.Guild, ct); if (!getServer.IsSuccess) { return(CreateEntityResult <AutoroleConfiguration> .FromError(getServer)); } var server = getServer.Entity; var autorole = _database.CreateProxy <AutoroleConfiguration>(server, discordRole); _database.Autoroles.Update(autorole); await _database.SaveChangesAsync(ct); return(autorole); }
public static async Task <CreateEntityResult <Appearance> > CreateDefaultAsync ( [NotNull] Character character, [NotNull] TransformationService transformations ) { var getSpeciesResult = await transformations.GetSpeciesByNameAsync("template"); if (!getSpeciesResult.IsSuccess) { return(CreateEntityResult <Appearance> .FromError("Could not find the default species.")); } var templateSpecies = getSpeciesResult.Entity; var templateTransformations = new List <Transformation>(); var templateParts = new List <Bodypart> { Head, Body, Arms, Legs }; // Explode the composite parts into their components templateParts = templateParts.SelectMany(p => p.GetComposingParts()).Distinct().ToList(); foreach (var part in templateParts) { var getTFResult = await transformations.GetTransformationsByPartAndSpeciesAsync(part, templateSpecies); if (!getTFResult.IsSuccess) { // Allow skipping of missing composing parts - a composite part might not have all of them in a TF. if (part.IsComposingPart()) { continue; } return(CreateEntityResult <Appearance> .FromError(getTFResult)); } templateTransformations.AddRange(getTFResult.Entity); } var templateComponents = new List <AppearanceComponent>(); foreach (var tf in templateTransformations) { if (tf.Part.IsChiral()) { templateComponents.AddRange(AppearanceComponent.CreateFromChiral(tf)); } else { templateComponents.Add(AppearanceComponent.CreateFrom(tf)); } } var appearance = new Appearance(character); appearance.Components.AddRange(templateComponents); return(CreateEntityResult <Appearance> .FromSuccess(appearance)); }
/// <summary> /// Creates a new dossier with the given title, summary, and data. /// </summary> /// <param name="title">The title of the dossier.</param> /// <param name="summary">The summary of the dossier.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation task which may or may not have succeeded.</returns> public async Task <CreateEntityResult <Dossier> > CreateDossierAsync ( string title, string summary, CancellationToken ct = default ) { var dossier = _database.CreateProxy <Dossier>(title, summary); _database.Dossiers.Update(dossier); var setTitleResult = await SetDossierTitleAsync(dossier, title, ct); if (!setTitleResult.IsSuccess) { return(CreateEntityResult <Dossier> .FromError(setTitleResult)); } var setSummary = await SetDossierSummaryAsync(dossier, summary, ct); if (!setSummary.IsSuccess) { return(CreateEntityResult <Dossier> .FromError(setSummary)); } await _database.SaveChangesAsync(ct); return(dossier); }
/// <summary> /// Displays the message in the given channel. /// </summary> /// <param name="channel">The channel.</param> /// <returns>The displayed message.</returns> private async Task <CreateEntityResult <IUserMessage> > DisplayAsync(IMessageChannel channel) { if (this.IsDeleting) { return(CreateEntityResult <IUserMessage> .FromError("The message is being deleted.")); } return(await OnDisplayAsync(channel)); }
/// <summary> /// Creates a note for the given user. /// </summary> /// <param name="authorUser">The author of the note.</param> /// <param name="guildUser">The user.</param> /// <param name="content">The content of the note.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserNote> > CreateNoteAsync ( IUser authorUser, IGuildUser guildUser, string content ) { var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild); if (!getServer.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getServer)); } var server = getServer.Entity; var getUser = await _users.GetOrRegisterUserAsync(guildUser); if (!getUser.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getUser)); } var user = getUser.Entity; var getAuthor = await _users.GetOrRegisterUserAsync(authorUser); if (!getAuthor.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getAuthor)); } var author = getAuthor.Entity; var note = new UserNote(server, user, author, string.Empty); var setContent = await SetNoteContentsAsync(note, content); if (!setContent.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(setContent)); } _database.UserNotes.Update(note); await _database.SaveChangesAsync(); // Requery the database var getNote = await GetNoteAsync(guildUser.Guild, note.ID); if (!getNote.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getNote)); } return(CreateEntityResult <UserNote> .FromSuccess(getNote.Entity)); }
/// <summary> /// Registers the given permission type, making it available to the system. /// </summary> /// <param name="services">The application's services.</param> /// <typeparam name="TPermission">The permission type.</typeparam> /// <returns>A creation result which may or may not have succeeded.</returns> public CreateEntityResult <TPermission> RegisterPermission <TPermission>(IServiceProvider services) where TPermission : class, IPermission { var permissionType = typeof(TPermission); var registerPermissionResult = RegisterPermission(permissionType, services); if (!registerPermissionResult.IsSuccess) { return(CreateEntityResult <TPermission> .FromError(registerPermissionResult)); } return(CreateEntityResult <TPermission> .FromSuccess((TPermission)registerPermissionResult.Entity)); }
/// <inheritdoc /> protected override async Task <CreateEntityResult <IUserMessage> > OnDisplayAsync(IMessageChannel channel) { if (!(this.Message is null)) { return(CreateEntityResult <IUserMessage> .FromError("The wizard is already active in a channel.")); } _categories = (await _kinks.GetKinkCategoriesAsync()).ToList(); _state = KinkWizardState.CategorySelection; var message = await channel.SendMessageAsync(string.Empty, embed : _loadingEmbed); return(CreateEntityResult <IUserMessage> .FromSuccess(message)); }
/// <summary> /// Adds the given user to the given roleplay. /// </summary> /// <param name="roleplay">The roleplay to add the user to.</param> /// <param name="newUser">The user to add to the roleplay.</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 <CreateEntityResult <RoleplayParticipant> > AddUserToRoleplayAsync ( Roleplay roleplay, User newUser, CancellationToken ct = default ) { newUser = _database.NormalizeReference(newUser); if (roleplay.HasJoined(newUser)) { return(CreateEntityResult <RoleplayParticipant> .FromError("The user is already in that roleplay.")); } if (roleplay.IsKicked(newUser)) { return(CreateEntityResult <RoleplayParticipant> .FromError ( "The user has been kicked from that roleplay, and can't rejoin unless invited." )); } // Check the invite list for nonpublic roleplays. if (!roleplay.IsPublic && !roleplay.IsInvited(newUser)) { return(CreateEntityResult <RoleplayParticipant> .FromError ( "The user hasn't been invited to that roleplay." )); } var participantEntry = roleplay.ParticipatingUsers.FirstOrDefault(p => p.User == newUser); if (participantEntry is null) { participantEntry = _database.CreateProxy <RoleplayParticipant>(roleplay, newUser); _database.Update(participantEntry); participantEntry.Status = ParticipantStatus.Joined; roleplay.ParticipatingUsers.Add(participantEntry); } else { participantEntry.Status = ParticipantStatus.Joined; } await _database.SaveChangesAsync(ct); return(participantEntry); }
/// <summary> /// Creates a note for the given user. /// </summary> /// <param name="authorUser">The author of the note.</param> /// <param name="guildUser">The user.</param> /// <param name="content">The content of the note.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserNote> > CreateNoteAsync ( IUser authorUser, IGuildUser guildUser, string content, CancellationToken ct = default ) { var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild, ct); if (!getServer.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getServer)); } var server = getServer.Entity; var getUser = await _users.GetOrRegisterUserAsync(guildUser, ct); if (!getUser.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getUser)); } var user = getUser.Entity; var getAuthor = await _users.GetOrRegisterUserAsync(authorUser, ct); if (!getAuthor.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(getAuthor)); } var author = getAuthor.Entity; var note = _database.CreateProxy <UserNote>(server, user, author, string.Empty); _database.UserNotes.Update(note); var setContent = await SetNoteContentsAsync(note, content, ct); if (!setContent.IsSuccess) { return(CreateEntityResult <UserNote> .FromError(setContent)); } await _database.SaveChangesAsync(ct); return(note); }
/// <summary> /// Creates a roleplay with the given parameters. /// </summary> /// <param name="owner">The user that owns the roleplay.</param> /// <param name="server">The server that the roleplay is associated with.</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 ( User owner, Server server, string roleplayName, string roleplaySummary, bool isNSFW, bool isPublic ) { owner = _database.NormalizeReference(owner); server = _database.NormalizeReference(server); // Use a dummy name, since we'll be setting it using the service. var roleplay = _database.CreateProxy <Roleplay>(server, owner, string.Empty, string.Empty); _database.Attach(roleplay); var ownerParticipant = _database.CreateProxy <RoleplayParticipant>(roleplay, owner); ownerParticipant.Status = ParticipantStatus.Joined; roleplay.ParticipatingUsers.Add(ownerParticipant); var setNameResult = await SetRoleplayNameAsync(roleplay, roleplayName); if (!setNameResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(setNameResult)); } var setSummaryResult = await SetRoleplaySummaryAsync(roleplay, roleplaySummary); if (!setSummaryResult.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(setSummaryResult)); } roleplay.IsNSFW = isNSFW; roleplay.IsPublic = isPublic; _database.Roleplays.Update(roleplay); await _database.SaveChangesAsync(); return(roleplay); }
/// <inheritdoc /> public async Task <CreateEntityResult <Image> > AddImageToCharacterAsync ( Character character, string imageName, string imageUrl, string?imageCaption = null, bool isNSFW = false, CancellationToken ct = default ) { var isImageNameUnique = !character.Images.Any(i => string.Equals(i.Name.ToLower(), imageName.ToLower())); if (!isImageNameUnique) { return(CreateEntityResult <Image> .FromError("The character already has an image with that name.")); } if (imageName.IsNullOrWhitespace()) { return(CreateEntityResult <Image> .FromError("You need to specify a name.")); } if (imageCaption.IsNullOrWhitespace()) { imageCaption = "No caption set."; } if (!Uri.IsWellFormedUriString(imageUrl, UriKind.RelativeOrAbsolute)) { return(CreateEntityResult <Image> .FromError ( $"That URL doesn't look valid. Please check \"{imageUrl}\" for errors." )); } var image = _database.CreateProxy <Image>(imageName, imageUrl, imageCaption); _database.Images.Update(image); image.IsNSFW = isNSFW; character.Images.Add(image); await _database.SaveChangesAsync(ct); return(image); }
/// <summary> /// Creates a new roleplay with the given owner and parameters. /// </summary> /// <param name="owner">The owner.</param> /// <param name="name">The name of the roleplay.</param> /// <param name="summary">A short summary.</param> /// <param name="isNSFW">Whether the roleplay is NSFW.</param> /// <param name="isPublic">Whether the roleplay is public.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <Roleplay> > CreateRoleplayAsync ( IGuildUser owner, string name, string summary, bool isNSFW, bool isPublic ) { var getUser = await _users.GetOrRegisterUserAsync(owner); if (!getUser.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(getUser)); } var user = getUser.Entity; var getServer = await _servers.GetOrRegisterServerAsync(owner.Guild); if (!getServer.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(getServer)); } var server = getServer.Entity; var createRoleplay = await _roleplays.CreateRoleplayAsync(user, server, name, summary, isNSFW, isPublic); if (!createRoleplay.IsSuccess) { return(createRoleplay); } var roleplay = createRoleplay.Entity; var createChannel = await _dedicatedChannels.CreateDedicatedChannelAsync(owner.Guild, roleplay); if (!createChannel.IsSuccess) { return(CreateEntityResult <Roleplay> .FromError(createChannel)); } return(roleplay); }
public async Task <CreateEntityResult <string> > GenerateCharacterDescriptionAsync(Character character) { var getCurrentAppearance = await GetOrCreateCurrentAppearanceAsync ( character ); if (!getCurrentAppearance.IsSuccess) { return(CreateEntityResult <string> .FromError(getCurrentAppearance)); } var currentAppearance = getCurrentAppearance.Entity; var visualDescription = _descriptionBuilder.BuildVisualDescription(currentAppearance); return(CreateEntityResult <string> .FromSuccess(visualDescription)); }
/// <summary> /// Gets or creates a set of per-server statistics for a given user. /// </summary> /// <param name="discordUser">The user.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserServerStatistics> > GetOrCreateUserServerStatisticsAsync ( IGuildUser discordUser ) { var getStatistics = await GetOrCreateUserStatisticsAsync(discordUser); if (!getStatistics.IsSuccess) { return(CreateEntityResult <UserServerStatistics> .FromError(getStatistics)); } var statistics = getStatistics.Entity; var existingServerStatistics = statistics.ServerStatistics.FirstOrDefault ( s => s.Server.DiscordID == (long)discordUser.Guild.Id ); if (!(existingServerStatistics is null)) { return(existingServerStatistics); } var getServer = await _servers.GetOrRegisterServerAsync(discordUser.Guild); if (!getServer.IsSuccess) { return(CreateEntityResult <UserServerStatistics> .FromError(getServer)); } var server = getServer.Entity; // Since we're adding to the database indirectly, an attach is required here. _database.Attach(server); var newServerStatistics = _database.CreateProxy <UserServerStatistics>(server); statistics.ServerStatistics.Add(newServerStatistics); await _database.SaveChangesAsync(); return(newServerStatistics); }
/// <summary> /// Gets or creates a set of per-server statistics for a given user. /// </summary> /// <param name="discordUser">The user.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserServerStatistics> > GetOrCreateUserServerStatisticsAsync ( IGuildUser discordUser, CancellationToken ct = default ) { var getStatistics = await GetOrCreateUserStatisticsAsync(discordUser, ct); if (!getStatistics.IsSuccess) { return(CreateEntityResult <UserServerStatistics> .FromError(getStatistics)); } var statistics = getStatistics.Entity; var existingServerStatistics = statistics.ServerStatistics.FirstOrDefault ( s => s.Server.DiscordID == (long)discordUser.Guild.Id ); if (!(existingServerStatistics is null)) { return(existingServerStatistics); } var getServer = await _servers.GetOrRegisterServerAsync(discordUser.Guild, ct); if (!getServer.IsSuccess) { return(CreateEntityResult <UserServerStatistics> .FromError(getServer)); } var server = getServer.Entity; var newServerStatistics = _database.CreateProxy <UserServerStatistics>(server); _database.Update(newServerStatistics); statistics.ServerStatistics.Add(newServerStatistics); await _database.SaveChangesAsync(ct); return(newServerStatistics); }
/// <inheritdoc/> protected override async Task <CreateEntityResult <IUserMessage> > OnDisplayAsync(IMessageChannel channel) { if (!this.Pages.Any()) { return(CreateEntityResult <IUserMessage> .FromError("The pager is empty.")); } var embed = BuildEmbed(_currentPage - 1); var message = await channel.SendMessageAsync(string.Empty, embed : embed); if (this.Pages.Count > 1) { await message.AddReactionAsync(this.Appearance.First); await message.AddReactionAsync(this.Appearance.Back); await message.AddReactionAsync(this.Appearance.Next); await message.AddReactionAsync(this.Appearance.Last); var manageMessages = await CanManageMessages(); var canJump = this.Appearance.JumpDisplayCondition == JumpDisplayCondition.Always || (this.Appearance.JumpDisplayCondition == JumpDisplayCondition.WithManageMessages && manageMessages); if (canJump) { await message.AddReactionAsync(this.Appearance.Jump); } if (this.Appearance.DisplayInformationIcon) { await message.AddReactionAsync(this.Appearance.Help); } } await message.AddReactionAsync(this.Appearance.Stop); return(CreateEntityResult <IUserMessage> .FromSuccess(message)); }
/// <summary> /// Creates a character with the given parameters. /// </summary> /// <param name="guildUser">The owner of the character..</param> /// <param name="name">The name of the character.</param> /// <param name="avatarUrl">The character's avatar url.</param> /// <param name="nickname">The nickname that should be applied to the user when the character is active.</param> /// <param name="summary">The summary of the character.</param> /// <param name="description">The full description of the character.</param> /// <param name="pronounFamily">The pronoun family of the character.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have been successful.</returns> public async Task <CreateEntityResult <Character> > CreateCharacterAsync ( IGuildUser guildUser, string name, string?avatarUrl = null, string?nickname = null, string?summary = null, string?description = null, string?pronounFamily = null, CancellationToken ct = default ) { var getUser = await _users.GetOrRegisterUserAsync(guildUser, ct); if (!getUser.IsSuccess) { return(CreateEntityResult <Character> .FromError(getUser)); } var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild, ct); if (!getServer.IsSuccess) { return(CreateEntityResult <Character> .FromError(getServer)); } var user = getUser.Entity; var server = getServer.Entity; return(await _characters.CreateCharacterAsync ( user, server, name, avatarUrl, nickname, summary, description, pronounFamily, ct )); }
/// <summary> /// Adds the given user to the given roleplay. /// </summary> /// <param name="roleplay">The roleplay.</param> /// <param name="discordUser">The discord user.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <RoleplayParticipant> > AddUserToRoleplayAsync ( Roleplay roleplay, IGuildUser discordUser ) { var getUser = await _users.GetOrRegisterUserAsync(discordUser); if (!getUser.IsSuccess) { return(CreateEntityResult <RoleplayParticipant> .FromError(getUser)); } var user = getUser.Entity; var addUserAsync = await _roleplays.AddUserToRoleplayAsync(roleplay, user); if (!addUserAsync.IsSuccess) { return(addUserAsync); } if (!roleplay.DedicatedChannelID.HasValue) { return(addUserAsync); } var updatePermissions = await _dedicatedChannels.UpdateParticipantPermissionsAsync ( discordUser.Guild, roleplay ); if (!updatePermissions.IsSuccess) { return(CreateEntityResult <RoleplayParticipant> .FromError(updatePermissions)); } return(addUserAsync); }
/// <summary> /// Adds a kink to a user's preference list. /// </summary> /// <param name="discordUser">The user.</param> /// <param name="kink">The kink.</param> /// <param name="ct">The cancellation token in use.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserKink> > AddUserKinkAsync ( IUser discordUser, Kink kink, CancellationToken ct = default ) { var getUserKinksResult = await GetUserKinksAsync(discordUser, ct : ct); if (!getUserKinksResult.IsSuccess) { return(CreateEntityResult <UserKink> .FromError(getUserKinksResult)); } var userKinks = getUserKinksResult.Entity; if (userKinks.Any(k => k.Kink.FListID == kink.FListID)) { return(CreateEntityResult <UserKink> .FromError("The user already has a preference for that kink.")); } var getUserResult = await _users.GetOrRegisterUserAsync(discordUser, ct); if (!getUserResult.IsSuccess) { return(CreateEntityResult <UserKink> .FromError(getUserResult)); } var user = getUserResult.Entity; var userKink = _database.CreateProxy <UserKink>(user, kink); _database.UserKinks.Update(userKink); await _database.SaveChangesAsync(ct); return(userKink); }