public async Task RemoveClaimAsync_Should_Remove_Claim_From_The_User_Claims_Collection() { string userName = "******"; using (IDocumentStore store = CreateEmbeddableStore()) using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { // Arrange ses.Advanced.UseOptimisticConcurrency = true; IUserClaimStore <RavenUser> userClaimStore = new RavenUserStore <RavenUser>(ses, false); RavenUser user = new RavenUser(userName); Claim claimToAddAndRemove = new Claim(ClaimTypes.Role, "Customer"); user.AddClaim(new RavenUserClaim(claimToAddAndRemove)); await ses.StoreAsync(user); await ses.SaveChangesAsync(); // Act await userClaimStore.RemoveClaimAsync(user, claimToAddAndRemove); // Assert Assert.Equal(0, user.Claims.Count()); } }
public async Task AddUserToRole_Should_Add_The_User_In_Roles_Consecutively_If_User_Exists_And_Is_Not_In_Role() { using (IDocumentStore store = CreateEmbeddableStore()) using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { IRoleStore roleStore = new RavenRoleStore <RavenUser, RavenUserRole>(ses); await ses.StoreAsync(new RavenUser { Id = "RavenUsers/1", UserName = "******", Roles = new List <RavenUserRole> { new RavenUserRole { Id = "Admin" }, new RavenUserRole { Id = "Guest" } } }); await ses.SaveChangesAsync(); bool result = await roleStore.AddUserToRole("Sales", "RavenUsers/1"); bool result2 = await roleStore.AddUserToRole("Accounting", "RavenUsers/1"); await ses.SaveChangesAsync(); RavenUser user = await ses.LoadAsync <RavenUser>("RavenUsers/1"); Assert.True(result); Assert.True(result2); Assert.True(user.Roles.Any(role => role.Id.Equals("Sales", StringComparison.InvariantCultureIgnoreCase))); Assert.True(user.Roles.Any(role => role.Id.Equals("Accounting", StringComparison.InvariantCultureIgnoreCase))); } }
public async Task RavenUserStore_Users_Should_Expose_IQueryable_Over_IRavenQueryable() { using (IDocumentStore store = CreateEmbeddableStore()) { const string userName = "******"; const string userNameToSearch = "TugberkUgurlu"; using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName); RavenUser userToSearch = new RavenUser(userNameToSearch); await ses.StoreAsync(user); await ses.StoreAsync(userToSearch); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { // Act ses.Advanced.UseOptimisticConcurrency = true; RavenUserStore <RavenUser> userStore = new RavenUserStore <RavenUser>(ses); RavenUser retrievedUser = await userStore.Users.FirstOrDefaultAsync(user => user.UserName == userNameToSearch); // Assert Assert.NotNull(retrievedUser); Assert.Equal(userNameToSearch, retrievedUser.UserName); } } }
public async Task GetEmailConfirmedAsync_Should_Throw_InvalidOperationException_If_Email_Is_Not_Available() { const string userName = "******"; const string userId = "RavenUsers/Tugberk"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName) { UserName = userName }; await ses.StoreAsync(user); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId); await Assert.ThrowsAsync <InvalidOperationException>(async() => { bool isConfirmed = await userEmailStore.GetEmailConfirmedAsync(ravenUser); }); } } }
public async Task SetTwoFactorEnabledAsync_Should_Set_IsTwoFactorEnabled_Value() { using (IDocumentStore store = CreateEmbeddableStore()) { const string userName = "******"; const string userId = "RavenUsers/Tugberk"; using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName); user.EnableTwoFactorAuthentication(); await ses.StoreAsync(user); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { // Act ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = await ses.LoadAsync <RavenUser>(userId); IUserTwoFactorStore <RavenUser, string> userTwoFactorStore = new RavenUserStore <RavenUser>(ses); await userTwoFactorStore.SetTwoFactorEnabledAsync(user, enabled : true); // Assert Assert.True(user.IsTwoFactorEnabled); } } }
public async Task SetEmailConfirmedAsync_Should_Throw_InvalidOperationException_If_User_Email_Property_Is_Available_But_UserEmail_Document_Not() { const string userName = "******"; const string userId = "RavenUsers/Tugberk"; const string email = "*****@*****.**"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName, email); await ses.StoreAsync(user); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId); await Assert.ThrowsAsync <InvalidOperationException>(async() => { await userEmailStore.SetEmailConfirmedAsync(ravenUser, confirmed: true); }); } } }
public async Task FindByEmailAsync_Should_Return_Null_If_User_Is_Not_Available() { const string userName = "******"; const string email = "*****@*****.**"; const string emailToLookFor = "*****@*****.**"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName, email); RavenUserEmail userEmail = new RavenUserEmail(email, user.Id); await ses.StoreAsync(user); await ses.StoreAsync(userEmail); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser user = await userEmailStore.FindByEmailAsync(emailToLookFor); Assert.Null(user); } } }
public async Task GetEmailAsync_Should_Return_User_Email_If_Available() { const string userName = "******"; const string userId = "RavenUsers/Tugberk"; const string email = "*****@*****.**"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName, email); RavenUserEmail userEmail = new RavenUserEmail(email, user.Id); await ses.StoreAsync(user); await ses.StoreAsync(userEmail); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId); string userEmail = await userEmailStore.GetEmailAsync(ravenUser); Assert.NotNull(userEmail); Assert.Equal(email, userEmail); } } }
private static Task <RestUserMessage> BlacklistDisplayUsers(RavenGuild guild, ulong userId, SocketTextChannel channel, string[] args) { if (guild.GuildSettings.BlacklistedUsers.Count == 0) { return(channel.SendMessageAsync("There are currently no blacklisted users.")); } string users = "Blacklisted Users:\n"; foreach (ulong i in guild.GuildSettings.BlacklistedUsers) { var user = channel.Guild.Users.FirstOrDefault(x => x.Id == i); if (user is null) { RavenUser deletedRavenUser = guild.Users.FirstOrDefault(x => x.UserId == i); string oldUsername = deletedRavenUser == null ? "Unknown" : deletedRavenUser.Username + "#" + deletedRavenUser.Discriminator; users += $"USER-LEFT (ID: {i} - Old Name: {oldUsername})\n"; } else { users += $"{user.Username} ({i})\n"; } } if (users.Length > 1900) { return(channel.SendMessageAsync("Too many users to list. Cutting off after 1800 characters.\n" + users.Substring(0, 1800))); } else { return(channel.SendMessageAsync("```cs\n" + users + "\n```")); } }
public Task <TUser> FindByNameAsync(string userName) { if (userName == null) { throw new ArgumentNullException("userName"); } return(_documentSession.LoadAsync <TUser>(RavenUser.GenerateKey(userName))); }
/// <summary> /// Instantiates or updates the <see cref="RavenUser"/> to be sent with every Sentry request. /// </summary> /// <param name="id">The unique identifier of this user.</param> /// <param name="username">The username of the this user.</param> /// <param name="email">The email address of this user.</param> public void SetUser(string id, string username, string email) { if (_user == null) { _user = new RavenUser(); } _user.Id = id; _user.Username = username; _user.Email = email; }
public async Task SetEmailAsync_Should_Set_Email_And_SaveChangesAsync_Should_Throw_ConcurrencyException_If_The_Email_Already_Exists() { const string userName = "******"; const string email = "*****@*****.**"; const string userName2 = "Tugberk2"; const string userId2 = "RavenUsers/Tugberk2"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName, email); RavenUser user2 = new RavenUser(userName2); RavenUserEmail userEmail = new RavenUserEmail(email, user.Id); await ses.StoreAsync(user); await ses.StoreAsync(user2); await ses.StoreAsync(userEmail); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId2); await userEmailStore.SetEmailAsync(ravenUser, email); await Assert.ThrowsAsync <ConcurrencyException>(async() => { await ses.SaveChangesAsync(); }); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId2); Assert.Null(ravenUser.Email); } } }
public async Task SetEmailAsync_Should_Set_The_Email_Correctly() { const string userName = "******"; const string userId = "RavenUsers/Tugberk"; const string emailToSave = "*****@*****.**"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName) { UserName = userName }; await ses.StoreAsync(user); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId); await userEmailStore.SetEmailAsync(ravenUser, emailToSave); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; string keyToLookFor = RavenUserEmail.GenerateKey(emailToSave); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId); RavenUserEmail userEmail = await ses.LoadAsync <RavenUserEmail>(keyToLookFor); Assert.NotNull(userEmail); Assert.Equal(emailToSave, ravenUser.Email); Assert.Equal(emailToSave, userEmail.Email); Assert.Equal(userId, userEmail.UserId); } } }
public async Task SetEmailConfirmedAsync_With_Confirmed_Param_False_Should_Set_The_Email_As_Not_Confirmed_If_Confirmed_Already() { const string userName = "******"; const string userId = "RavenUsers/Tugberk"; const string email = "*****@*****.**"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; RavenUser user = new RavenUser(userName, email); RavenUserEmail userEmail = new RavenUserEmail(email, user.Id); userEmail.SetConfirmed(); await ses.StoreAsync(user); await ses.StoreAsync(userEmail); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserEmailStore <RavenUser> userEmailStore = new RavenUserStore <RavenUser>(ses); RavenUser ravenUser = await ses.LoadAsync <RavenUser>(userId); await userEmailStore.SetEmailConfirmedAsync(ravenUser, confirmed : false); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; string keyToLookFor = RavenUserEmail.GenerateKey(email); RavenUserEmail userEmail = await ses.LoadAsync <RavenUserEmail>(keyToLookFor); Assert.Null(userEmail.ConfirmationRecord); } } }
public async Task GetProfileAsync([Remainder] string target) { RavenGuild guild = RavenDb.GetGuild(Context.Guild.Id); Regex regex = new Regex(@"<@([0-9]*)>"); Match match = regex.Match(target); if (match.Success) { // See if what they gave was a real person ulong.TryParse(match.Groups[1].Value, out ulong id); if (id is 0) { await ReplyAsync("Invalid User Mentioned."); return; } RavenUser mentionedUser = guild.GetUser(id); if (mentionedUser is null) { await ReplyAsync("The user specified doesn't exist within the system."); return; } // Gotem. await ReplyAsync(null, false, DiscordEvents.GetUserProfile(id, guild)); } else { RavenUser user = guild.Users.FirstOrDefault(x => x.Username.StartsWith(target)); if (user is null) { await ReplyAsync("Couldn't find anyone who's name was at all like that. To be fair, it's not a very indepth search."); return; } await ReplyAsync(null, false, DiscordEvents.GetUserProfile(user.UserId, guild)); } }
internal RavenUser PostLevelProcessing(RavenUser user, out Embed embed, Color?color = null, RavenGuild guild = null) { if (color == null) // If we got a null value cause they lacked a role with colour { color = new Color(114, 137, 218); // We give them a default one (an almost cornflower blue) } // Make the next amount of xp required 20% more than the previous level double percentageIncrease = user.RequiredXp * 1.2f; // Assign their previous required xp to the amount they just passed. user.PrevRequiredXp = user.RequiredXp; // Round to the nearest five to keep our percentages nice user.RequiredXp = Convert.ToUInt64(Math.Round(percentageIncrease + (double)user.RequiredXp / 5) * 5); user.Level++; // Increase their level by 1. // TODO: Setup global/guild ranks // Is this a guild level up or a global levelup if (guild != null) { } else { } // Create a new embed embed = new EmbedBuilder() { Title = "Level Up!", // They leveled up Color = color, // The colour we were provided or assigned ourselves Description = $"You've Leveled Up! Your new level is {user.Level} and you require an additional " + $"{user.RequiredXp - user.PrevRequiredXp} XP to level up again.", Footer = new EmbedFooterBuilder() { Text = $"Your current rank is: {user.Rank}" } }.Build(); return(user); }
public async Task GetUserClaims_Should_Retrieve_Correct_Claims_For_User() { string userName = "******"; using (IDocumentStore store = CreateEmbeddableStore()) { RavenUser user = new RavenUser(userName); IEnumerable <RavenUserClaim> claims = new List <RavenUserClaim> { new RavenUserClaim("Scope", "Read"), new RavenUserClaim("Scope", "Write") }; foreach (RavenUserClaim claim in claims) { user.AddClaim(claim); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserClaimStore <RavenUser> userClaimStore = new RavenUserStore <RavenUser>(ses); await ses.StoreAsync(user); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserClaimStore <RavenUser> userClaimStore = new RavenUserStore <RavenUser>(ses); IEnumerable <Claim> retrievedClaims = await userClaimStore.GetClaimsAsync(user); Assert.Equal(2, claims.Count()); Assert.Equal("Read", claims.ElementAt(0).ClaimValue); Assert.Equal("Write", claims.ElementAt(1).ClaimValue); } } }
public async Task GetUserClaims_Should_Not_Return_Null_If_User_Has_No_Claims() { string userName = "******"; using (IDocumentStore store = CreateEmbeddableStore()) using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserClaimStore <RavenUser> userClaimStore = new RavenUserStore <RavenUser>(ses, false); RavenUser user = new RavenUser(userName); await ses.StoreAsync(user); await ses.SaveChangesAsync(); // Act IEnumerable <Claim> retrievedClaims = await userClaimStore.GetClaimsAsync(user); // Assert Assert.Equal(0, retrievedClaims.Count()); } }
public async Task Add_Should_Add_New_Login_If_User_Exists() { const string userName = "******"; const string loginProvider = "Twitter"; const string providerKey = "12345678"; using (IDocumentStore store = CreateEmbeddableStore()) { using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserLoginStore <RavenUser, string> userLoginStore = new RavenUserStore <RavenUser>(ses); RavenUser user = new RavenUser(userName); await ses.StoreAsync(user); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserLoginStore <RavenUser, string> userLoginStore = new RavenUserStore <RavenUser>(ses); RavenUser user = await ses.LoadAsync <RavenUser>(RavenUser.GenerateKey(userName)); // Act UserLoginInfo loginToAdd = new UserLoginInfo(loginProvider, providerKey); await userLoginStore.AddLoginAsync(user, loginToAdd); await ses.SaveChangesAsync(); // Assert RavenUserLogin foundLogin = await ses.LoadAsync <RavenUserLogin>(RavenUserLogin.GenerateKey(loginProvider, providerKey)); Assert.Equal(1, user.Logins.Count()); Assert.NotNull(foundLogin); } } }
public async Task FindAsync_Should_Find_The_User_If_Login_Exists() { const string userName = "******"; const string loginProvider = "Twitter"; const string providerKey = "12345678"; using (IDocumentStore store = CreateEmbeddableStore()) { // Arrange using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserLoginStore <RavenUser, string> userLoginStore = new RavenUserStore <RavenUser>(ses); RavenUser user = new RavenUser(userName); RavenUserLogin userLogin = new RavenUserLogin(user.Id, new UserLoginInfo(loginProvider, providerKey)); user.AddLogin(userLogin); await ses.StoreAsync(user); await ses.StoreAsync(userLogin); await ses.SaveChangesAsync(); } using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserLoginStore <RavenUser, string> userLoginStore = new RavenUserStore <RavenUser>(ses); // Act UserLoginInfo loginInfo = new UserLoginInfo(loginProvider, providerKey); RavenUser foundUser = await userLoginStore.FindAsync(loginInfo); // Assert Assert.NotNull(foundUser); Assert.Equal(userName, foundUser.UserName); } } }
public async Task AddClaimAsync_Should_Add_The_Claim_Into_The_User_Claims_Collection() { string userName = "******"; using (IDocumentStore store = base.CreateEmbeddableStore()) using (IAsyncDocumentSession ses = store.OpenAsyncSession()) { ses.Advanced.UseOptimisticConcurrency = true; IUserClaimStore <RavenUser> userClaimStore = new RavenUserStore <RavenUser>(ses, false); RavenUser user = new RavenUser(userName); await ses.StoreAsync(user); await ses.SaveChangesAsync(); Claim claimToAdd = new Claim(ClaimTypes.Role, "Customer"); await userClaimStore.AddClaimAsync(user, claimToAdd); Assert.Equal(1, user.Claims.Count()); Assert.Equal(claimToAdd.Value, user.Claims.FirstOrDefault().ClaimValue); Assert.Equal(claimToAdd.Type, user.Claims.FirstOrDefault().ClaimType); } }
internal async Task MessageReceivedAsync(SocketMessage s) { if (!(s is SocketUserMessage msg)) { return; // If this is not a message (could be a TTS, Image, File, etc) } if (msg.Author.IsBot || msg.Author.IsWebhook) { return; // Ignore messages from bot users, which includes the bot itself. } int argPos = 0; ShardedCommandContext context = new ShardedCommandContext(discord, msg); // If DM Channel, ignore all database based things. if (msg.Channel is IDMChannel || msg.Channel is IGroupChannel) { if (msg.HasStringPrefix(GlobalConfig.Prefix, ref argPos)) { var result = await commandService.ExecuteAsync(context, argPos, service); if (!result.IsSuccess) // If not successful, reply with the error. { await context.Channel.SendMessageAsync(result.ToString()); } return; } } // Get the active database information for the current guild, or create it if it doesn't exist (for some reason) var guild = RavenDb.GetGuild(context.Guild.Id) ?? RavenDb.CreateNewGuild(context.Guild.Id, context.Guild.Name); if (!context.Guild.CurrentUser.GuildPermissions.Administrator && msg.HasStringPrefix(guild.GuildSettings.Prefix, ref argPos)) { await context.Channel.SendMessageAsync("The bot is not currently set as an administrator." + "Commands will be ignored until the bot is granted the Administrator permission."); return; } if (msg.Content.Contains("discord.gg/") && !((SocketGuildUser)context.User).GuildPermissions.ManageGuild && guild.GuildSettings.AutoblockInviteLinks) { await msg.DeleteAsync(); await context.Channel.SendMessageAsync("This server does not allow the posting of Discord server invites by non-moderators."); return; } // If the level settings are not disabled, we want to do our level processing. if (guild.GuildSettings.LevelConfig.LevelSettings != LevelSettings.Disabled) { // Get the global database entry for the user, or create it if it doesn't exist. var user = RavenDb.GetUser(context.User.Id) ?? RavenDb.CreateNewUser(context.User.Id, context.User.Username, context.User.DiscriminatorValue); // Is the user ready for extra XP? if (user.XpLastUpdated.AddSeconds(RavenDb.GlobalLevelConfig.SecondsBetweenXpGiven) < DateTime.UtcNow) { user.XpLastUpdated = DateTime.UtcNow; // We are giving them XP so let's update the time stamp user.Xp = Convert.ToUInt64(new Random().Next(RavenDb.GlobalLevelConfig.MinXpGenerated, RavenDb.GlobalLevelConfig.MaxXpGenerated + 1)) + user.Xp; // Generate a value between our two clamps, a little RNG. if (user.Xp > user.RequiredXp) // Are they ready for a level up? { user = PostLevelProcessing(user, out Embed embed); // Level them up // Don't send the global message, maybe a setting in the future? } user.Save(); // Save the global user } // Are they allowing guild leveling? if (guild.GuildSettings.LevelConfig.LevelSettings == LevelSettings.GuildLeveling) { // Get the user or create them if they don't exist. RavenUser guildUser = guild.GetUser(context.User.Id) ?? guild.CreateNewUser(context.User.Id, context.User.Username, context.User.DiscriminatorValue); if (guildUser.UserId == 0) { // This is weird unintentional behaviour, but sometimes it happens // Need to investigate further await context.Channel.SendMessageAsync("Your user ID was 0 for some reason. Please try again."); return; } // Check if they area ready for XP on a guild level if (guildUser.XpLastUpdated.AddSeconds(guild.GuildSettings.LevelConfig.SecondsBetweenXpGiven) < DateTime.UtcNow) { guildUser.XpLastUpdated = DateTime.UtcNow; // They are so we update the timestamp guildUser.Xp = Convert.ToUInt64(new Random().Next(guild.GuildSettings.LevelConfig.MinXpGenerated, guild.GuildSettings.LevelConfig.MaxXpGenerated + 1)) + guildUser.Xp; // Generate a value between our two clamps if (guildUser.Xp > guildUser.RequiredXp) // If they are ready to level up { // Get the first role they are assigned that has a non-default colour SocketRole role = ((SocketGuildUser)msg.Author).Roles.FirstOrDefault(x => x.Color.ToString() != "#0"); Color? color = role?.Color; // Get the colour from the role, or null if we didn't find a colour. guildUser = PostLevelProcessing(guildUser, out Embed embed, color); // Pass it in to get the result await context.Channel.SendMessageAsync("", false, embed); // Post it } int index = guild.Users.FindIndex(x => x.UserId == context.User.Id); if (index != -1) // I don't think this should ever happend, but better safe than sorry { guild.Users[index] = guildUser; // Update it } guild.Save(); // Save the db entry } } } // If the mention the bot directly, tell them the prefix. If they type just the word prefix, tell them. if ((msg.MentionedUsers.All(x => discord.Shards.Any(y => y.CurrentUser.Id == x.Id)) && msg.MentionedUsers.Count > 0) || msg.Content == "prefix") { await context.Channel.SendMessageAsync("This guild's prefix is: " + guild.GuildSettings.Prefix); return; } // Ignore string prefixes if the person was currently in a menu else if (msg.HasStringPrefix(guild.GuildSettings.Prefix, ref argPos)) { if (!guild.UserConfiguration.ContainsKey(context.User.Id)) { var result = await commandService.ExecuteAsync(context, argPos, service); if (!result.IsSuccess) { await context.Channel.SendMessageAsync(result.ToString()); } return; } else { await context.Channel.SendMessageAsync("You are currently in a menu. Respond to it or type 'exit' to leave it."); } } // Are they currently in a menu if (guild.UserConfiguration.ContainsKey(context.User.Id)) { string[] args = msg.Content.Split(' '); // They want off this wild ride if (msg.Content == "exit" || msg.Content.StartsWith("exit")) { guild.UserConfiguration.Remove(context.User.Id); // Remove their menu entry guild.Save(); // Save await context.Channel.SendMessageAsync("Exited out of menu."); // Goodbye user return; } else if (msg.Content == "back" || msg.Content.StartsWith("back")) { switch (guild.UserConfiguration[context.User.Id]) { case MessageBox.BaseMenu: guild.UserConfiguration.Remove(context.User.Id); // Remove their menu entry guild.Save(); // Save await context.Channel.SendMessageAsync("Exited out of menu."); // Goodbye user return; case MessageBox.LsSettingSubmenu: guild.UserConfiguration[context.User.Id] = MessageBox.LevelSettings; break; // By default we assume they are one menu deep default: guild.UserConfiguration[context.User.Id] = MessageBox.BaseMenu; break; } guild.Save(); await ConfigHandler.SelectSubMenu(guild, context.User.Id, context.Guild.GetTextChannel(context.Channel.Id), guild.UserConfiguration[context.User.Id]); return; } // Otherwise we see if they specified a valid option else if (int.TryParse(args[0], out int option)) { // Handle it a bit differently if it's a different route if (guild.UserConfiguration[context.User.Id] is MessageBox.BaseMenu) { // Normally we wouldn't use IsDefined due to it's lack of scalability, // But for the root menu it actually scales rather well. Just need to watch out for the 2000 character limit. if (Enum.IsDefined(typeof(MessageBox), option)) { // Literally makes no difference in preformance, just trying to keep this file clean. // Using this method, they can technically, if they know the submenu values, // skip the parent menus and go straight to the sub menus. I don't really see this as an issue, to be honest. await ConfigHandler.SelectSubMenu(guild, context.User.Id, context.Guild.GetTextChannel(context.Channel.Id), (MessageBox)option); return; } else // They didn't so lets give them another chance { await context.Channel.SendMessageAsync("The option you specified doesn't exist. The option should be" + " just the number of the option you are trying to pick. Try again."); return; } } else { await ConfigHandler.SelectOption(guild, context.User.Id, context.Guild.GetTextChannel(context.Channel.Id), args); } } } }
/// <summary>Called when a user joins the server. </summary> internal async Task GuildUserJoinAsync(SocketGuildUser user) { foreach (PluginInfo plugin in GlobalConfig.PluginInfo) { if (plugin.MessageReceivedAsync != null) { if (GlobalConfig.RunPluginFunctionsAsynchronously) #pragma warning disable 4014 { plugin.GuildUserLeave.Invoke(user); } #pragma warning restore 4014 else { await plugin.GuildUserLeave(user); } } } // Add it to the global database if they don't exist if (RavenDb.GetUser(user.Id) is null) { RavenDb.CreateNewUser(user.Id, user.Username, user.DiscriminatorValue, user.GetAvatarUrl() ?? user.GetDefaultAvatarUrl()); } // Get the guild this user is in RavenGuild guild = RavenDb.GetGuild(user.Guild.Id) ?? RavenDb.CreateNewGuild(user.Guild.Id, user.Guild.Name); // Update the total amount of users guild.TotalUsers = (uint)user.Guild.Users.Count; // If they rejoined, we'll store their old name to log bool rejoined = false; string username = string.Empty; // Get the user from that guild RavenUser guildUser = guild.GetUser(user.Id); if (guildUser is null) // if they don't exist, we'll need to create them { guild.CreateNewUser(user.Id, user.Username, user.DiscriminatorValue, user.GetAvatarUrl() ?? user.GetDefaultAvatarUrl()); } else { // They rejoined, update their name in case/discrim in case it changed rejoined = true; username = guildUser.Username + "#" + guildUser.Discriminator; guildUser.Username = user.Username; guildUser.Discriminator = user.DiscriminatorValue; guild.Save(); // Save the updated information, while storing the old one for logging purposes } // Process welcome message if one is set if (guild.GuildSettings.WelcomeMessage.Enabled) { // If the targeted channel is null or no longer exists or the message itself is undefined if (guild.GuildSettings.WelcomeMessage.ChannelId is null || user.Guild.GetTextChannel(guild.GuildSettings.WelcomeMessage.ChannelId.GetValueOrDefault()) is null || string.IsNullOrWhiteSpace(guild.GuildSettings.WelcomeMessage.Message)) { // If the logging channel is setup, exists, and is enabled if (!(guild.LoggingSettings.ChannelId is null) && !(user.Guild.GetTextChannel(guild.LoggingSettings.ChannelId.GetValueOrDefault()) is null) && guild.LoggingSettings.Enabled) { // Log to the logging channel if it has been set await user.Guild.GetTextChannel(guild.LoggingSettings.ChannelId.Value).SendMessageAsync(null, false, new EmbedBuilder() { Title = "Warning!", Color = new Color(255, 128, 0), // Orange Description = "Unable to send welcome message. Channel or message are currently null. Please reconfigure it.", Footer = new EmbedFooterBuilder() { Text = $"{DateTime.UtcNow:ddd MMM d yyyy HH mm}" } }.Build()); } } else { // Send the welcome message and repalce the server or user tags if they are present await user.Guild.GetTextChannel(guild.GuildSettings.WelcomeMessage.ChannelId.Value) .SendMessageAsync(guild.GuildSettings.WelcomeMessage.Message .Replace("%SERVER%", user.Guild.Name) .Replace("%USER%", user.Username)); } }
internal async Task MessageReceivedAsync(SocketMessage s) { foreach (PluginInfo plugin in GlobalConfig.PluginInfo) { if (plugin.MessageReceivedAsync != null) { if (GlobalConfig.RunPluginFunctionsAsynchronously) #pragma warning disable 4014 { plugin.MessageReceivedAsync.Invoke(s); } #pragma warning restore 4014 else { await plugin.MessageReceivedAsync(s); } } } if (!(s is SocketUserMessage msg)) { return; // If this is not a message (could be a TTS, Image, File, etc) } if (msg.Author.IsBot || msg.Author.IsWebhook) { return; // Ignore messages from bot users, which includes the bot itself. } int argPos = 0; ShardedCommandContext context = new ShardedCommandContext(discord, msg); // If DM Channel, ignore all database based things. if (msg.Channel is IDMChannel || msg.Channel is IGroupChannel) { if (msg.HasStringPrefix(GlobalConfig.Prefix, ref argPos)) { var result = await commandService.ExecuteAsync(context, argPos, service); if (!result.IsSuccess) // If not successful, reply with the error. { await context.Channel.SendMessageAsync(result.ToString()); } return; } } // Get the active database information for the current guild, or create it if it doesn't exist (for some reason) var guild = RavenDb.GetGuild(context.Guild.Id) ?? RavenDb.CreateNewGuild(context.Guild.Id, context.Guild.Name); guild.TotalMessages++; if (msg.Attachments.Count > 0) { foreach (var x in msg.Attachments) { if (x.Height != null) { guild.TotalImages++; } } } guild.Save(); if (!context.Guild.CurrentUser.GuildPermissions.Administrator && msg.HasStringPrefix(guild.GuildSettings.Prefix, ref argPos)) { await context.Channel.SendMessageAsync("The bot is not currently set as an administrator." + "Commands will be ignored until the bot is granted the Administrator permission."); return; } if (msg.Content.Contains("discord.gg/") && !((SocketGuildUser)context.User).GuildPermissions.ManageGuild && guild.GuildSettings.AutoblockInviteLinks) { await msg.DeleteAsync(); await context.Channel.SendMessageAsync("This server does not allow the posting of Discord server invites by non-moderators."); return; } // If the level settings are not disabled, we want to do our level processing. if (guild.GuildSettings.LevelConfig.LevelSettings != LevelSettings.Disabled) { // Get the global database entry for the user, or create it if it doesn't exist. var user = RavenDb.GetUser(context.User.Id) ?? RavenDb.CreateNewUser(context.User.Id, context.User.Username, context.User.DiscriminatorValue, context.User.GetAvatarUrl() ?? context.User.GetDefaultAvatarUrl()); // Is the user ready for extra XP? if (user.XpLastUpdated.AddSeconds(RavenDb.GlobalLevelConfig.SecondsBetweenXpGiven) < DateTime.UtcNow) { user.XpLastUpdated = DateTime.UtcNow; // We are giving them XP so let's update the time stamp user.Xp = Convert.ToUInt64(new Random().Next(RavenDb.GlobalLevelConfig.MinXpGenerated, RavenDb.GlobalLevelConfig.MaxXpGenerated + 1)) + user.Xp; // Generate a value between our two clamps, a little RNG. if (user.Xp > user.RequiredXp) // Are they ready for a level up? { user = PostLevelProcessing(user, out Embed embed); // Level them up // Don't send the global message, maybe a setting in the future? } user.Save(); // Save the global user } // Are they allowing guild leveling? if (guild.GuildSettings.LevelConfig.LevelSettings == LevelSettings.GuildLeveling) { // Get the user or create them if they don't exist. RavenUser guildUser = guild.GetUser(context.User.Id) ?? guild.CreateNewUser(context.User.Id, context.User.Username, context.User.DiscriminatorValue, context.User.GetAvatarUrl() ?? context.User.GetDefaultAvatarUrl()); if (guildUser.UserId == 0) { // This is weird unintentional behaviour, but sometimes it happens // Need to investigate further await context.Channel.SendMessageAsync("Your user ID was 0 for some reason. Please try again."); return; } // Check if they area ready for XP on a guild level if (guildUser.XpLastUpdated.AddSeconds(guild.GuildSettings.LevelConfig.SecondsBetweenXpGiven) < DateTime.UtcNow) { guildUser.XpLastUpdated = DateTime.UtcNow; // They are so we update the timestamp guildUser.Xp = Convert.ToUInt64(new Random().Next(guild.GuildSettings.LevelConfig.MinXpGenerated, guild.GuildSettings.LevelConfig.MaxXpGenerated + 1)) + guildUser.Xp; // Generate a value between our two clamps if (guildUser.Xp >= guildUser.RequiredXp) // If they are ready to level up { // Get the first role they are assigned that has a non-default colour SocketRole role = ((SocketGuildUser)msg.Author).Roles.FirstOrDefault(x => x.Color.ToString() != "#0"); Color? color = role?.Color; // Get the colour from the role, or null if we didn't find a colour. guildUser = PostLevelProcessing(guildUser, out Embed embed, color, guild); // Pass it in to get the result await context.Channel.SendMessageAsync("", false, embed); // Post it } int index = guild.Users.FindIndex(x => x.UserId == context.User.Id); if (index != -1) // I don't think this should ever happend, but better safe than sorry { guild.Users[index] = guildUser; // Update it } guild.Save(); // Save the db entry } } } // If the mention the bot directly, tell them the prefix. If they type just the word prefix, tell them. if ((msg.MentionedUsers.All(x => discord.Shards.Any(y => y.CurrentUser.Id == x.Id)) && MentionUtils.TryParseUser(msg.Content, out ulong a)) || msg.Content.ToLower() == "prefix") { await context.Channel.SendMessageAsync("This guild's prefix is: " + guild.GuildSettings.Prefix); return; }