Automated Task

结算观众分

Type Scheduled

Date Executed 8/31/2024, 4:00:00 PM

Created 7/18/2024, 4:31:23 AM

Updated 8/31/2024, 4:34:56 PM

Description 收集 PhiZone 谱面投票并结算观众分。

Code
1
using Microsoft.Extensions.Logging;
2
using Microsoft.Extensions.DependencyInjection;
3
using PhiZoneApi.Models;
4
using PhiZoneApi.Interfaces;
5
using System;
6
using System.Linq;
7
using System.Globalization;
8

9
var target = (EventDivision)Target;
10
const int reviewerCount = 20;
11
await using (var scope = ServiceProvider.CreateAsyncScope())
12
{
13
    var eventTeamRepository = scope.ServiceProvider.GetRequiredService<IEventTeamRepository>();
14
    var chartRepository = scope.ServiceProvider.GetRequiredService<IChartRepository>();
15
    var eventResourceRepository = scope.ServiceProvider.GetRequiredService<IEventResourceRepository>();
16
    var leaderboardService = scope.ServiceProvider.GetRequiredService<ILeaderboardService>();
17
    var eventTeams = await eventTeamRepository.GetEventTeamsAsync(predicate: e => e.DivisionId == target.Id);
18
    foreach (var eventTeam in eventTeams)
19
    {
20
        var entries = await eventResourceRepository.GetEventResourcesAsync(predicate: e => e.TeamId == eventTeam.Id);
21
        foreach (var entry in entries)
22
        {
23
            while (entry.Reserved.Count < 14 + reviewerCount)
24
            {
25
                entry.Reserved.Add(string.Empty);
26
            }
27

28
            entry.Reserved[2] = Math.Round((await chartRepository.GetChartAsync(entry.ResourceId)).Rating, 2).ToString(CultureInfo.InvariantCulture);
29
            var reviewerScores = Enumerable.Range(14, reviewerCount)
30
                .Select(i => entry.Reserved[i])
31
                .Where(e => !string.IsNullOrWhiteSpace(e) && double.TryParse(e, out var f) && f > 0)
32
                .Select(e => e!)
33
                .ToList();
34
            var reviewerAverage = reviewerScores.Count > 0 ? Math.Round(reviewerScores.Average(double.Parse), 2) : 0;
35
            entry.Reserved[1] = reviewerAverage.ToString(CultureInfo.InvariantCulture);
36
            var challengeTotal = Enumerable.Range(7, 7)
37
                .Select(i => entry.Reserved[i])
38
                .Select(e => !string.IsNullOrWhiteSpace(e) && double.TryParse(e, out _) ? e : "0")
39
                .Sum(double.Parse);
40
            entry.Reserved[3] = challengeTotal.ToString(CultureInfo.InvariantCulture);
41
            var scores = Enumerable.Range(1, 3)
42
                .Select(i => entry.Reserved[i])
43
                .Select(e =>
44
                {
45
                    if (!string.IsNullOrWhiteSpace(e) && double.TryParse(e, out var result)) return (double?)result;
46
                    return null;
47
                })
48
                .ToList();
49
            var total = Math.Round((scores[0] ?? 0) * ((scores[2] ?? 0) + 100) / 100 + (scores[1] ?? 2.5) * 3, 2);
50
            entry.Reserved[0] = total.ToString(CultureInfo.InvariantCulture);
51
            if (eventTeam.IsUnveiled)
52
            {
53
                entry.Score = total;
54
            }
55

56
            await eventResourceRepository.UpdateEventResourceAsync(entry);
57
        }
58

59
        while (eventTeam.Reserved.Count < 14 + reviewerCount)
60
        {
61
            eventTeam.Reserved.Add(string.Empty);
62
        }
63

64
        for (var i = 1; i <= 3; i++)
65
        {
66
            var entryScores = entries.Select(e => e.Reserved[i])
67
                .Where(e => !string.IsNullOrWhiteSpace(e) && double.TryParse(e, out _))
68
                .Select(e => e!)
69
                .ToList();
70
            eventTeam.Reserved[i] = entryScores.Count > 0
71
                ? Math.Round(entryScores.Average(double.Parse), 2).ToString(CultureInfo.InvariantCulture)
72
                : "0";
73
        }
74
        var teamScores = Enumerable.Range(1, 3)
75
            .Select(i => eventTeam.Reserved[i])
76
            .Select(e =>
77
            {
78
                if (!string.IsNullOrWhiteSpace(e) && double.TryParse(e, out var result)) return (double?)result;
79
                return null;
80
            })
81
            .ToList();
82
        var teamTotal = Math.Round((teamScores[0] ?? 0) * ((teamScores[2] ?? 0) + 100) / 100 + (teamScores[1] ?? 2.5) * 3, 2);
83
        eventTeam.Reserved[0] = teamTotal.ToString(CultureInfo.InvariantCulture);
84
        if (eventTeam.IsUnveiled)
85
        {
86
            eventTeam.Score = teamTotal;
87
        }
88

89
        await eventTeamRepository.UpdateEventTeamAsync(eventTeam);
90
        if (eventTeam.IsUnveiled)
91
        {
92
            leaderboardService.Add(eventTeam);
93
        }
94
    }
95
}