private async Task HandleStreamerRole(SocketGuildUser guildUser, StreamerSettings settings) { // Get the streaming role. var streamingRole = guildUser.Guild.Roles.FirstOrDefault(r => r.Id == settings.RoleId); // Remove the streaming role if it does not exist. if (streamingRole == null) { await _settingsService.RemoveSetting(settings); Logger.LogError("Streamer Module: Role could not be found!"); } else { // Add use to role. if (guildUser.Activity != null && guildUser.Activity.Type == ActivityType.Streaming) { await AddUserToStreamingRole(guildUser, streamingRole); } // Remove user from role. else if (guildUser.Roles.Any(r => r.Id == streamingRole.Id)) { await RemoveUserFromStreamingRole(guildUser, streamingRole); } } }
private async Task HandleStreamerRole(SocketGuildUser guildUser, StreamerSettings settings) { // Get the streaming role. var streamingRole = guildUser.Guild.Roles.FirstOrDefault(r => r.Id == settings.RoleId); // Remove the streaming role if it does not exist. if (streamingRole == null) { await _settingsService.RemoveSetting(settings); Logger.LogError("Streamer Module: Role could not be found!"); } else { using (var scope = _scopeFactory.CreateScope()) { var botService = scope.ServiceProvider.GetRequiredService <IBot>(); var botRolePosition = botService.GetBotRoleHierarchy(guildUser.Guild.Id); if (streamingRole.Position < botRolePosition) { // Add use to role. if (guildUser.Activity != null && guildUser.Activity.Type == ActivityType.Streaming && IsUserWhiteListed(settings, guildUser)) { await AddUserToStreamingRole(guildUser, streamingRole); } // Remove user from role. else if (guildUser.Roles.Any(r => r.Id == streamingRole.Id)) { await RemoveUserFromStreamingRole(guildUser, streamingRole); } } else { Logger.LogError( $"Streamer Module: Could not add/remove role as bot has insufficient hierarchical position. " + $"Guild Id: {guildUser.Guild.Id}"); await botService.GetGuild(guildUser.Guild.Id).Owner.SendMessageAsync( $"We couldn't add/remove Role '{streamingRole.Name}' to a user as the role's hierarchical position is greater than the bot's.{Environment.NewLine}" + $"To fix this, please adjust your role's position and then re-enable the module via our website.{Environment.NewLine}" + $"Guild: {guildUser.Guild.Name}"); var settingsDb = await _settingsService.GetSettingsByGuild(guildUser.Guild.Id); settingsDb.StreamerRoleEnabled = false; await _settingsService.SaveSettings(settingsDb); } } } }
/// <summary> /// Announces the user if it's appropriate to do so. /// </summary> /// <param name="user">User to be evaluated/adjusted for streaming announcement.</param> /// <param name="channels">List of channels with module enabled</param> /// <param name="settings">Streamer settings for specified guild.</param> private async Task CheckUser(SocketGuildUser user, List <StreamerChannelSettings> channels, StreamerSettings settings) { // Add initial hash set for the guild. if (!StreamingList.TryGetValue(user.Guild.Id, out var set)) { set = new HashSet <StreamAnnouncerMessage>(); StreamingList[user.Guild.Id] = set; } // Check to make sure the user is streaming and not in the streaming list. if (user.Activity != null && user.Activity.Type == ActivityType.Streaming) { // If the user is not in the streaming list, they just started streaming. So, handle announcement. if (!StreamingList.Any(u => u.Key == user.Guild.Id && u.Value.Any(x => x.UserId == user.Id)) && IsUserWhiteListed(settings, user)) { await AnnounceUserHandler(user, channels); } // Else, the user is already streaming and already has an announcement message. // This happens when GuildMemberUpdated is triggered by something other than the user stopping their stream. // So, do nothing. } // User is not streaming. else { // Get user from streaming list. var userDataFromList = StreamingList[user.Guild.Id].Where(x => x.UserId == user.Id).ToList(); // Handle announced streaming messages. await AnnouncedMessageHandler(user, userDataFromList, channels); // Remove messages from hashset. foreach (var m in userDataFromList) { StreamingList[user.Guild.Id].Remove(m); } } }
public async Task <IActionResult> StreamerSettings(ulong guildId, StreamerSettingsViewModel viewModel, [FromServices] IBot bot, [FromServices] IDiscordGuildService guildService) { var botRolePosition = bot.GetBotRoleHierarchy(guildId); var roles = await guildService.GetRoles(guildId); var selectedRolePosition = roles.FirstOrDefault(r => r.Id == viewModel.RoleId)?.Position; // Discord bots cannot assign to roles that are higher then them in the hierarchy. if (selectedRolePosition > botRolePosition) { ModelState.AddModelError("RolePosition", "The bots managed role must be positioned higher than the selected role"); // All channels in guild. var channels = await guildService.GetChannels(guildId); // Text channels in guild. var textChannels = channels.Where(x => x.Type == 0).ToList(); viewModel.Channels = new SelectList(textChannels, "Id", "Name"); viewModel.Roles = new SelectList(roles.RemoveManaged(), "Id", "Name"); return(View(viewModel)); } var moduleSettings = await _streamAnnouncerSettingsService.GetSettingsByGuild(guildId); var saveSettingsTasks = new List <Task>(); // If the guild doesn't already have a settings DB entry, we want to add one before we do anything else. // Running that operation along side adding individual channel settings risks throwing an FK exception. if (moduleSettings == null) { var streamerSettings = new StreamerSettings { GuildId = guildId, Enabled = viewModel.Enabled, StreamerRoleEnabled = viewModel.StreamerRoleEnabled, RoleId = viewModel.RoleId, WhiteListedRoleIds = new List <WhiteListedRole>() }; if (viewModel.WhiteListedRoleIds != null) { streamerSettings.WhiteListedRoleIds = new List <WhiteListedRole>(viewModel.WhiteListedRoleIds .Select(r => new WhiteListedRole { RoleId = r })); } await _streamAnnouncerSettingsService.SaveSettings(streamerSettings); } else { // Clear all white listed roles from the database var whiteListedRoles = await _whiteListedRoleEntityService.Get(w => w.GuildId == guildId); if (whiteListedRoles != null) { await _whiteListedRoleEntityService.RemoveBulk(whiteListedRoles); } if (viewModel.WhiteListedRoleIds != null) { await _whiteListedRoleEntityService.CreateBulk(viewModel.WhiteListedRoleIds.Select(r => new WhiteListedRole { RoleId = r, GuildId = guildId })); } saveSettingsTasks.Add(_streamAnnouncerSettingsService.SaveSettings(new StreamerSettings { GuildId = guildId, Enabled = viewModel.Enabled, StreamerRoleEnabled = viewModel.StreamerRoleEnabled, RoleId = viewModel.RoleId })); } // Value defaults to 0, if the value is 0, EF will try to auto increment the ID, throwing an error. if (viewModel.ChannelId != 0) { // Settings for the specified channel of a guild. var settings = await _streamAnnouncerChannelSettingsService.Find(viewModel.ChannelId); // Remember if there were settings in db, as settings will be populated later if they aren't. var isSettingsInDb = settings != null; // Save general module settings to the database if (!isSettingsInDb) { settings = new StreamerChannelSettings { GuildId = guildId, ChannelId = viewModel.ChannelId } } ; settings.RemoveMessage = viewModel.ChannelSettings.RemoveMessages; // Save specific channel settings to the database. if (viewModel.ChannelSettings.Enabled) { saveSettingsTasks.Add(!isSettingsInDb ? _streamAnnouncerChannelSettingsService.Create(settings) : _streamAnnouncerChannelSettingsService.Update(settings)); } else { if (isSettingsInDb) { saveSettingsTasks.Add(_streamAnnouncerChannelSettingsService.Remove(settings)); } } } await Task.WhenAll(saveSettingsTasks.ToArray()); return(RedirectToAction("Index")); }
/// <summary> /// Checks if a user is part of the white listed roles. /// </summary> /// <param name="settings">Streamer settings for specified guild.</param> /// <param name="guildUser">User to check.</param> /// <returns>True if the user is a part of the white listed roles; otherwise false.</returns> private static bool IsUserWhiteListed(StreamerSettings settings, SocketGuildUser guildUser) { var whiteListedRoles = settings.WhiteListedRoleIds.Select(w => w.RoleId).ToList(); return(!whiteListedRoles.Any() || guildUser.Roles.Any(r => whiteListedRoles.Contains(r.Id))); }