Exemplo n.º 1
0
    async Task IRoleRemover.RemoveBasementRolesAsync()
    {
        var basementRoleId = (DiscordRoleId)_dynamicConfiguration.DiscordMapping["BasementRoleId"];

        // If there are any users from the last check, free them this round.
        foreach (var discordUserID in _usersToFreeFromBasement)
        {
            if (!_discordAccess.CanManageRolesForUser(discordUserID))
            {
                continue;
            }

            var(success, roleName) = await _discordAccess.TryRevokeNonMemberRole(discordUserID, basementRoleId);

            if (success)
            {
                await _discordAccess.LogToDiscord($"Automatically removed role `{roleName}` from <@{discordUserID}>.");

                continue;
            }

            var leaderMention = _discordAccess.GetRoleMention("Leader");
            await _discordAccess.LogToDiscord($"{leaderMention}: failed to remove role `{roleName}` from <@{discordUserID}>");
        }

        // Gather users that should be freed next round.
        _usersToFreeFromBasement.Clear();
        var usersInBasement = _discordAccess.GetUsersIdsInRole(basementRoleId);

        if (usersInBasement.Any())
        {
            _usersToFreeFromBasement.AddRange(usersInBasement);
        }
    }
Exemplo n.º 2
0
    private async Task ConnectedHandler()
    {
        await _discordAccess.SetCurrentGame("Hand of Unity");

        if (_isFirstConnect)
        {
            _isFirstConnect = false;
            await _discordAccess.LogToDiscord($"Bot started on **{_botInformationProvider.GetEnvironmentName()}** in version {_botInformationProvider.GetFormattedVersion()}.");

            // Start privacy provider clean up
            _privacyProvider.Start();

            // Register background jobs (HangFire).
            // Sync all users every 15 minutes to UNITS.
            RecurringJob.AddOrUpdate <IUnitsSyncService>("sync-users-to-UNITS", service => service.SyncAllUsers(), "0,15,30,45 0-23 * * *");
            // Sync all users every 15 minutes to UnityHub.
            RecurringJob.AddOrUpdate <UnityHubSyncService>("sync-users-to-UnityHub", service => service.SyncAllUsers(), "0,15,30,45 0-23 * * *");
            // Send personal reminders as scheduled.
            SchedulePersonalReminders();
            // Apply birthday role at 09:00 community time (UTC).
            RecurringJob.AddOrUpdate <BirthdayService>("birthday-apply-role", service => service.ApplyRoleAsync(), "0 9 * * *");
            // Remove birthday role at 23:59 community time (UTC).
            RecurringJob.AddOrUpdate <BirthdayService>("birthday-revoke-role", service => service.RevokeRoleAsync(), "59 23 * * *");
            RecurringJob.AddOrUpdate <IRoleRemover>("remove-basement-role", remover => remover.RemoveBasementRolesAsync(), "0 0-23 * * *");

            EstablishUnitsSignalRConnections();
        }

        _logger.LogInformation("Bot ready.");
    }
Exemplo n.º 3
0
    public async Task ApplyRoleAsync()
    {
        var birthdayRoleId = (DiscordRoleId)_dynamicConfiguration.DiscordMapping[BirthdayRoleIdKey];
        var birthdayUsers  = await _birthdayProvider.GetBirthdaysAsync(DateOnly.FromDateTime(DateTime.UtcNow));

        var userIdsWithAppliedRole = new List <DiscordUserId>(birthdayUsers.Length);

        foreach (var userId in birthdayUsers)
        {
            if (!_discordAccess.CanManageRolesForUser(userId))
            {
                continue;
            }

            var(success, _) = await _discordAccess.TryAddNonMemberRole(userId, birthdayRoleId);

            if (success)
            {
                userIdsWithAppliedRole.Add(userId);
            }
            else
            {
                await _discordAccess.LogToDiscord($"{_discordAccess.GetLeadershipMention()}: "
                                                  + $"Failed to apply role {birthdayRoleId.ToMention()} to {userId.ToMention()}.");
            }
        }

        if (userIdsWithAppliedRole.Count == 0)
        {
            return;
        }

        var birthdayAnnouncementChannelId = (DiscordChannelId)_dynamicConfiguration.DiscordMapping[BirthdayAnnouncementChannelIdKey];
        var messages = userIdsWithAppliedRole.Select(m => "HoU wishes a Happy Birthday to our latest Birthday Yata, "
                                                     + $"{m.ToMention()}. Have an amazing day filled with fun!!!")
                       .ToArray();
        await _discordAccess.CreateBotMessagesInChannelAsync(birthdayAnnouncementChannelId, messages);
    }
Exemplo n.º 4
0
        public async Task AddGameAsync(IRole game)
        {
            if (!_userStore.TryGetUser((DiscordUserId)Context.User.Id, out var user))
            {
                await RespondAsync("Couldn't find you in the user store. Game was not added.");

                return;
            }

            // Add
            var(success, message, addedGame) = await _gameRoleProvider.AddGameAsync(user !.InternalUserId, (DiscordRoleId)game.Id);

            if (success && addedGame != null)
            {
                // When the game was added successfully, log the add
                var logMessage = $"{Context.User.Username} added the game **{addedGame.DisplayName} ({game.Mention})**.";
                _logger.LogInformation(logMessage);
                await _discordAccess.LogToDiscord(logMessage);
            }

            await RespondAsync(message);
        }
Exemplo n.º 5
0
    // Do NOT implement this as explicit implementation, as it cannot be triggered by hangfire then!
    public async Task SyncAllUsers()
    {
        if (_dynamicConfiguration.UnitsEndpoints.Length == 0)
        {
            _logger.LogWarning("No UNITS access configured.");
            return;
        }

        if (!_discordAccess.IsConnected || !_discordAccess.IsGuildAvailable)
        {
            return;
        }

        foreach (var unitsSyncData in _dynamicConfiguration.UnitsEndpoints.Where(m => !string.IsNullOrWhiteSpace(m.BaseAddress) &&
                                                                                 !string.IsNullOrWhiteSpace(m.Secret) &&
                                                                                 m.ConnectToRestApi))
        {
            if (string.IsNullOrWhiteSpace(unitsSyncData.BaseAddress))
            {
                _logger.LogWarning("UNITS base address not configured.");
                continue;
            }

            if (string.IsNullOrWhiteSpace(unitsSyncData.Secret))
            {
                _logger.LogWarning("UNITS access secret not configured.");
                continue;
            }

            var allowedRoles = await _unitsAccess.GetValidRoleNamesAsync(unitsSyncData);

            if (allowedRoles == null)
            {
                _logger.LogWarning("Failed to synchronize all users: {Reason}.", "unable to fetch allowed roles");
                continue;
            }

            var users = _discordAccess.GetUsersInRoles(allowedRoles);
            if (users.Any())
            {
                users = SanitizeUsers(users);
                _logger.LogInformation("Sending {Count} users to the UNITS system at {Address} ...",
                                       users.Length,
                                       unitsSyncData.BaseAddress);
                var result = await _unitsAccess.SendAllUsersAsync(unitsSyncData, users);

                if (result == null)
                {
                    continue;
                }

                var utcNow = DateTime.UtcNow;
                var notificationRequired = utcNow.Hour == 15 && utcNow.Minute < 15;
                var onlySkippedUsers     = result.SkippedUsers > 0 &&
                                           result.CreatedUsers == 0 &&
                                           result.UpdatedUsers == 0 &&
                                           result.UpdatedUserRoleRelations == 0 &&
                                           (result.Errors?.Count ?? 0) == 0;
                var shouldPostResults = notificationRequired || !onlySkippedUsers;
                if (!shouldPostResults)
                {
                    continue;
                }

                var sb = new StringBuilder($"Synchronized {users.Length} users with the UNIT system at {unitsSyncData.BaseAddress}:");
                sb.AppendLine();
                if (result.CreatedUsers > 0)
                {
                    sb.AppendLine($"Created {result.CreatedUsers} users.");
                }
                if (result.UpdatedUsers > 0)
                {
                    sb.AppendLine($"Updated {result.UpdatedUsers} users.");
                }
                if (result.SkippedUsers > 0)
                {
                    sb.AppendLine($"Skipped {result.SkippedUsers} users.");
                }
                if (result.UpdatedUserRoleRelations > 0)
                {
                    sb.AppendLine($"Updated {result.UpdatedUserRoleRelations} user-role relations.");
                }
                if (result.Errors != null && result.Errors.Any())
                {
                    if (notificationRequired)
                    {
                        var leadershipMention = _discordAccess.GetLeadershipMention();
                        sb.AppendLine($"**{leadershipMention} - errors synchronizing Discord with the UNIT system:**");
                    }
                    else
                    {
                        sb.AppendLine("**Errors synchronizing Discord with the UNIT system:**");
                    }

                    for (var index = 0; index < result.Errors.Count; index++)
                    {
                        var error        = result.Errors[index];
                        var errorMessage = $"`{error}`";

                        // Check if this error message would create a too long Discord message.
                        if (sb.Length + errorMessage.Length > 1900 && index < result.Errors.Count - 1 ||
                            sb.Length + errorMessage.Length > 2000)
                        {
                            sb.AppendLine($"**{result.Errors.Count - index} more errors were truncated from this message.**");
                            break;
                        }

                        sb.AppendLine(errorMessage);
                    }
                }

                await _discordAccess.LogToDiscord(sb.ToString());
            }
            else
            {
                _logger.LogWarning("Failed to synchronize all users: {Reason}.", "unable to fetch allowed users");
            }
        }
    }