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> /// <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)); }
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> /// Adds a kink to a user's preference list. /// </summary> /// <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 ( IUser discordUser, Kink kink ) { var getUserKinksResult = await GetUserKinksAsync(discordUser); 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); if (!getUserResult.IsSuccess) { return(CreateEntityResult <UserKink> .FromError(getUserResult)); } var user = getUserResult.Entity; var userKink = new UserKink(user, kink); _database.UserKinks.Update(userKink); await _database.SaveChangesAsync(); return(CreateEntityResult <UserKink> .FromSuccess(userKink)); }
/// <summary> /// Creates a dedicated channel for the roleplay. /// </summary> /// <param name="guild">The guild in which the request was made.</param> /// <param name="roleplay">The roleplay to create the channel for.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <ITextChannel> > CreateDedicatedChannelAsync ( IGuild guild, Roleplay roleplay ) { var getServerResult = await _servers.GetOrRegisterServerAsync(guild); if (!getServerResult.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError(getServerResult)); } var server = getServerResult.Entity; if (!(await guild.GetUserAsync(_client.CurrentUser.Id)).GuildPermissions.ManageChannels) { return(CreateEntityResult <ITextChannel> .FromError ( "I don't have permission to manage channels, so I can't create dedicated RP channels." )); } var getExistingChannelResult = await GetDedicatedChannelAsync(guild, roleplay); if (getExistingChannelResult.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError ( "The roleplay already has a dedicated channel." )); } var getSettingsResult = await _serverSettings.GetOrCreateServerRoleplaySettingsAsync(server); if (!getSettingsResult.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError(getSettingsResult)); } var settings = getSettingsResult.Entity; if (!(settings.DedicatedRoleplayChannelsCategory is null)) { var categoryChannelCount = (await guild.GetTextChannelsAsync()) .Count(c => c.CategoryId == (ulong)settings.DedicatedRoleplayChannelsCategory); if (categoryChannelCount >= 50) { return(CreateEntityResult <ITextChannel> .FromError ( "The server's roleplaying category has reached its maximum number of channels. Try " + "contacting the server's owners and either removing some old roleplays or setting up " + "a new category." )); } } Optional <ulong?> categoryId; if (settings.DedicatedRoleplayChannelsCategory is null) { categoryId = null; } else { categoryId = (ulong?)settings.DedicatedRoleplayChannelsCategory; } var dedicatedChannel = await guild.CreateTextChannelAsync ( $"{roleplay.Name}-rp", properties => { properties.CategoryId = categoryId; properties.IsNsfw = roleplay.IsNSFW; properties.Topic = $"Dedicated roleplay channel for {roleplay.Name}. {roleplay.Summary}"; } ); roleplay.DedicatedChannelID = (long)dedicatedChannel.Id; var resetPermissions = await ResetChannelPermissionsAsync(dedicatedChannel, roleplay); if (!resetPermissions.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError(resetPermissions)); } await _database.SaveChangesAsync(); return(CreateEntityResult <ITextChannel> .FromSuccess(dedicatedChannel)); }
/// <summary> /// Creates a default appearance using the template species (a featureless, agendered species). /// </summary> /// <param name="db">The database.</param> /// <param name="transformations">The transformation service.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public static async Task <CreateEntityResult <Appearance> > CreateDefaultAsync ( [NotNull] GlobalInfoContext db, [NotNull] TransformationService transformations ) { var getSpeciesResult = await transformations.GetSpeciesByNameAsync(db, "template"); if (!getSpeciesResult.IsSuccess) { return(CreateEntityResult <Appearance> .FromError(CommandError.ObjectNotFound, "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.GetTransformationByPartAndSpeciesAsync(db, 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.Add(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 { Components = templateComponents, Height = 1.8, Weight = 80, GenderScale = 0, Muscularity = 0.5 }; return(CreateEntityResult <Appearance> .FromSuccess(appearance)); }
/// <summary> /// Creates a warning for the given user. /// </summary> /// <param name="authorUser">The author of the warning.</param> /// <param name="guildUser">The user.</param> /// <param name="reason">The reason of the warning.</param> /// <param name="messageID">The message that caused the warning, if any.</param> /// <param name="expiresOn">The expiry date for the warning, if any.</param> /// <returns>A creation result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <UserWarning> > CreateWarningAsync ( [NotNull] IUser authorUser, [NotNull] IGuildUser guildUser, [NotNull] string reason, [CanBeNull] long?messageID = null, [CanBeNull] DateTime?expiresOn = null ) { var getServer = await _servers.GetOrRegisterServerAsync(guildUser.Guild); if (!getServer.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(getServer)); } var server = getServer.Entity; var getUser = await _users.GetOrRegisterUserAsync(guildUser); if (!getUser.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(getUser)); } var user = getUser.Entity; var getAuthor = await _users.GetOrRegisterUserAsync(authorUser); if (!getAuthor.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(getAuthor)); } var author = getAuthor.Entity; var warning = new UserWarning(server, user, author, string.Empty); var setReason = await SetWarningReasonAsync(warning, reason); if (!setReason.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(setReason)); } if (!(messageID is null)) { var setMessage = await SetWarningContextMessageAsync(warning, messageID.Value); if (!setMessage.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(setMessage)); } } if (!(expiresOn is null)) { var setExpiry = await SetWarningExpiryDateAsync(warning, expiresOn.Value); if (!setExpiry.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(setExpiry)); } } _database.UserWarnings.Update(warning); await _database.SaveChangesAsync(); // Requery the database var getWarning = await GetWarningAsync(guildUser.Guild, warning.ID); if (!getWarning.IsSuccess) { return(CreateEntityResult <UserWarning> .FromError(getWarning)); } return(CreateEntityResult <UserWarning> .FromSuccess(getWarning.Entity)); }
/// <summary> /// Creates a dedicated channel for the roleplay. /// </summary> /// <param name="guild">The guild in which the request was made.</param> /// <param name="roleplay">The roleplay to create the channel for.</param> /// <returns>A modification result which may or may not have succeeded.</returns> public async Task <CreateEntityResult <ITextChannel> > CreateDedicatedChannelAsync ( IGuild guild, Roleplay roleplay ) { var getServerResult = await _servers.GetOrRegisterServerAsync(guild); if (!getServerResult.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError(getServerResult)); } var server = getServerResult.Entity; if (!(await guild.GetUserAsync(_client.CurrentUser.Id)).GuildPermissions.ManageChannels) { return(CreateEntityResult <ITextChannel> .FromError ( "I don't have permission to manage channels, so I can't create dedicated RP channels." )); } var getExistingChannelResult = await GetDedicatedChannelAsync(guild, roleplay); if (getExistingChannelResult.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError ( "The roleplay already has a dedicated channel." )); } var getSettingsResult = await _serverSettings.GetOrCreateServerRoleplaySettingsAsync(server); if (!getSettingsResult.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError(getSettingsResult)); } var settings = getSettingsResult.Entity; if (settings.DedicatedRoleplayChannelsCategory is null) { return(CreateEntityResult <ITextChannel> .FromError ( "No dedicated channel category has been configured." )); } var categoryChannelCount = (await guild.GetTextChannelsAsync()) .Count(c => c.CategoryId == (ulong)settings.DedicatedRoleplayChannelsCategory); if (categoryChannelCount >= 50) { return(CreateEntityResult <ITextChannel> .FromError ( "The server's roleplaying category has reached its maximum number of channels. Try " + "contacting the server's owners and either removing some old roleplays or setting up " + "a new category." )); } Optional <ulong?> categoryId = (ulong?)settings.DedicatedRoleplayChannelsCategory; var dedicatedChannel = await guild.CreateTextChannelAsync ( $"{roleplay.Name}-rp", properties => { properties.CategoryId = categoryId; properties.IsNsfw = roleplay.IsNSFW; properties.Topic = $"Dedicated roleplay channel for {roleplay.Name}. {roleplay.Summary}"; } ); roleplay.DedicatedChannelID = (long)dedicatedChannel.Id; // This can fail in all manner of ways because of Discord.NET. Try, catch, etc... try { var resetPermissions = await ResetChannelPermissionsAsync(dedicatedChannel, roleplay); if (!resetPermissions.IsSuccess) { return(CreateEntityResult <ITextChannel> .FromError(resetPermissions)); } } catch (HttpException hex) when(hex.HttpCode == HttpStatusCode.Forbidden) { return(CreateEntityResult <ITextChannel> .FromError ( "Failed to update channel permissions. Does the bot have permissions to manage permissions on " + "new channels?" )); } catch (Exception ex) { await dedicatedChannel.DeleteAsync(); return(CreateEntityResult <ITextChannel> .FromError(ex)); } await _database.SaveChangesAsync(); return(CreateEntityResult <ITextChannel> .FromSuccess(dedicatedChannel)); }
public async Task <CreateEntityResult <Character> > CreateCharacterAsync ( [NotNull] ICommandContext context, [NotNull] string characterName, [NotNull] string characterAvatarUrl, [CanBeNull] string characterNickname, [CanBeNull] string characterSummary, [CanBeNull] string characterDescription ) { // Default the nickname to the character name characterNickname = characterNickname ?? characterName; var getOwnerResult = await _users.GetOrRegisterUserAsync(context.Message.Author); if (!getOwnerResult.IsSuccess) { return(CreateEntityResult <Character> .FromError(getOwnerResult)); } var owner = getOwnerResult.Entity; // Use a dummy name here, because we'll set it using the service afterwards var character = new Character((long)context.Guild.Id, owner, string.Empty); var modifyEntityResult = await SetCharacterNameAsync(context, character, characterName); if (!modifyEntityResult.IsSuccess) { return(CreateEntityResult <Character> .FromError(modifyEntityResult)); } modifyEntityResult = await SetCharacterAvatarAsync(character, characterAvatarUrl); if (!modifyEntityResult.IsSuccess) { return(CreateEntityResult <Character> .FromError(modifyEntityResult)); } modifyEntityResult = await SetCharacterNicknameAsync(character, characterNickname); if (!modifyEntityResult.IsSuccess) { return(CreateEntityResult <Character> .FromError(modifyEntityResult)); } if (!(characterSummary is null)) { modifyEntityResult = await SetCharacterSummaryAsync(character, characterSummary); if (!modifyEntityResult.IsSuccess) { return(CreateEntityResult <Character> .FromError(modifyEntityResult)); } } if (!(characterDescription is null)) { modifyEntityResult = await SetCharacterDescriptionAsync(character, characterDescription); if (!modifyEntityResult.IsSuccess) { return(CreateEntityResult <Character> .FromError(modifyEntityResult)); } } _database.Characters.Update(character); await _database.SaveChangesAsync(); return(CreateEntityResult <Character> .FromSuccess(character)); }