Skip to content

Commit

Permalink
Implement configurable banners (#674)
Browse files Browse the repository at this point in the history
Part 1 of the summoning rework.

Allows the app to load up banners from `bannerConfig.json` and display
these in the summoning list. Loads up the number of summons and daily
summons available based on banner data.

Does _not_ make these banners functional.

Also:
- Tidy up Program.cs
- Sync namespaces
  • Loading branch information
SapiensAnatis authored Feb 24, 2024
1 parent 0aff896 commit c48c2a9
Show file tree
Hide file tree
Showing 46 changed files with 553 additions and 233 deletions.
6 changes: 5 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -235,4 +235,8 @@ end_of_line = crlf
dotnet_style_qualification_for_field = true:silent
dotnet_style_qualification_for_property = true:silent
dotnet_style_qualification_for_method = true:silent
dotnet_style_qualification_for_event = true:silent
dotnet_style_qualification_for_event = true:silent

[*.cs]
dotnet_diagnostic.RMG012.severity = error # Unmapped target member
dotnet_diagnostic.RMG020.severity = error # Unmapped source member
1 change: 1 addition & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<PackageVersion Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
<PackageVersion Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="8.0.1" />
<PackageVersion Include="MudBlazor" Version="6.13.0" />
<PackageVersion Include="Riok.Mapperly" Version="3.4.0" />
<PackageVersion Include="Serilog.Exceptions" Version="8.4.0" />
<PackageVersion Include="Serilog.Expressions" Version="4.0.0" />
<PackageVersion Include="Serilog.Settings.Configuration" Version="8.0.0" />
Expand Down
9 changes: 5 additions & 4 deletions DragaliaAPI/DragaliaAPI.Database/Entities/DbSummonTicket.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,19 @@ public class DbSummonTicket : DbPlayerData
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Key]
public long TicketKeyId { get; set; }
[Column("TicketKeyId")]
public long KeyId { get; set; }

[Column("Type")]
public SummonTickets Type { get; set; }
public SummonTickets SummonTicketId { get; set; }

[Column("Quantity")]
public int Quantity { get; set; }

[Column("ExpirationTime")]
public DateTimeOffset ExpirationTime { get; set; }
public DateTimeOffset UseLimitTime { get; set; }

[NotMapped]
public bool IsExpired =>
ExpirationTime != DateTimeOffset.UnixEpoch && ExpirationTime > DateTimeOffset.UtcNow;
this.UseLimitTime != DateTimeOffset.UnixEpoch && this.UseLimitTime > DateTimeOffset.UtcNow;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.AspNetCore.TestHost;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Distributed;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Npgsql;
Expand Down Expand Up @@ -89,5 +90,8 @@ protected override void ConfigureWebHost(IWebHostBuilder builder)
});

builder.UseEnvironment("Testing");

// Ensure we override any supplemental config
builder.ConfigureAppConfiguration(cfg => cfg.AddJsonFile("appsettings.Testing.json"));
}
}
76 changes: 73 additions & 3 deletions DragaliaAPI/DragaliaAPI.Integration.Test/Dragalia/SummonTest.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
using DragaliaAPI.Database.Entities;
using DragaliaAPI.Features.Summoning;
using Microsoft.EntityFrameworkCore;

namespace DragaliaAPI.Integration.Test.Dragalia;

/// <summary>
/// Tests <see cref="Controllers.Dragalia.SummonController"/>
/// Tests <see cref="SummonController"/>
/// </summary>
public class SummonTest : TestFixture
{
Expand Down Expand Up @@ -76,16 +77,85 @@ await this.Client.PostMsgpack<SummonGetSummonHistoryData>(
}

[Fact]
public async Task SummonGetSummonList_ReturnsAnyData()
public async Task SummonGetSummonList_ReturnsDataWithBannerInformation()
{
int bannerId = 1020010;
int dailyCount = 1;
int summonCount = 10;

await this.AddToDatabase(
new DbPlayerBannerData()
{
SummonBannerId = bannerId,
DailyLimitedSummonCount = dailyCount,
SummonCount = summonCount
}
);

await this.AddToDatabase(
new DbSummonTicket()
{
SummonTicketId = SummonTickets.SingleSummon,
KeyId = 2,
Quantity = 1,
UseLimitTime = DateTimeOffset.UnixEpoch
}
);

SummonGetSummonListData response = (
await this.Client.PostMsgpack<SummonGetSummonListData>(
"summon/get_summon_list",
new SummonGetSummonListRequest()
)
).data;

response.Should().NotBeNull();
response
.summon_list.Should()
.ContainSingle()
.Which.Should()
.BeEquivalentTo(
new SummonList()
{
summon_id = bannerId,
summon_type = 2,
single_crystal = 120,
single_diamond = 120,
multi_crystal = 1200,
multi_diamond = 1200,
limited_crystal = 0,
limited_diamond = 30,
summon_point_id = bannerId,
add_summon_point = 1,
add_summon_point_stone = 2,
exchange_summon_point = 300,
status = 1,
commence_date = DateTimeOffset.Parse("2024-02-24T15:22:06Z"),
complete_date = DateTimeOffset.Parse("2037-02-24T15:22:06Z"),
daily_count = dailyCount,
daily_limit = 1,
total_limit = 0,
total_count = summonCount,
campaign_type = 0,
free_count_rest = 0,
is_beginner_campaign = 0,
beginner_campaign_count_rest = 0,
consecution_campaign_count_rest = 0,
}
);

response
.summon_ticket_list.Should()
.ContainSingle()
.Which.Should()
.BeEquivalentTo(
new SummonTicketList()
{
SummonTicketId = SummonTickets.SingleSummon,
KeyId = 2,
Quantity = 1,
UseLimitTime = DateTimeOffset.UnixEpoch
}
);
}

[Fact]
Expand Down
8 changes: 4 additions & 4 deletions DragaliaAPI/DragaliaAPI.Shared/ServiceConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ public static class ServiceConfiguration
{
public static IServiceCollection ConfigureSharedServices(
this IServiceCollection serviceCollection
)
{
return serviceCollection.AddScoped<IPlayerIdentityService, PlayerIdentityService>();
}
) =>
serviceCollection
.AddHttpContextAccessor()
.AddScoped<IPlayerIdentityService, PlayerIdentityService>();
}
3 changes: 1 addition & 2 deletions DragaliaAPI/DragaliaAPI/App.razor
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
@using DragaliaAPI.Blazor.Authentication

@using DragaliaAPI.Authentication
@{
string? darkModeCookie = this.HttpContext?.Request.Cookies.FirstOrDefault(x => x.Key == "darkMode").Value;
bool? isDarkMode = null;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using DragaliaAPI.Shared.PlayerDetails;
using Microsoft.AspNetCore.Components.Authorization;

namespace DragaliaAPI.Blazor.Authentication;
namespace DragaliaAPI.Authentication;

public class BlazorIdentityService : IBlazorIdentityService
{
Expand All @@ -14,7 +14,8 @@ public class BlazorIdentityService : IBlazorIdentityService
public BlazorIdentityService(AuthenticationStateProvider authenticationStateProvider)
{
this.authenticationStateProvider = authenticationStateProvider;
this.authenticationStateProvider.AuthenticationStateChanged += OnAuthenticationStateChanged;
this.authenticationStateProvider.AuthenticationStateChanged +=
this.OnAuthenticationStateChanged;
}

public async Task InitializeAsync()
Expand Down
2 changes: 1 addition & 1 deletion DragaliaAPI/DragaliaAPI/Authentication/Constants.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace DragaliaAPI.Blazor.Authentication;
namespace DragaliaAPI.Authentication;

public class Constants
{
Expand Down
2 changes: 1 addition & 1 deletion DragaliaAPI/DragaliaAPI/Authentication/HttpRequestState.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
namespace DragaliaAPI.Blazor.Authentication;
namespace DragaliaAPI.Authentication;

public class HttpRequestState
{
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using DragaliaAPI.Shared.PlayerDetails;

namespace DragaliaAPI.Blazor.Authentication;
namespace DragaliaAPI.Authentication;

public interface IBlazorIdentityService : IPlayerIdentityService
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ public SummonMapProfile()
.ForMember(nameof(SummonHistoryList.summon_point_id), o => o.MapFrom(x => x.SummonId));

this.CreateMap<DbSummonTicket, SummonTicketList>()
.ForMember(x => x.key_id, o => o.MapFrom(src => src.TicketKeyId))
.ForMember(x => x.summon_ticket_id, o => o.MapFrom(src => src.Type))
.ForMember(x => x.quantity, o => o.MapFrom(src => src.Quantity))
.ForMember(x => x.use_limit_time, o => o.MapFrom(src => src.ExpirationTime));
.ForMember(x => x.KeyId, o => o.MapFrom(src => src.KeyId))
.ForMember(x => x.SummonTicketId, o => o.MapFrom(src => src.SummonTicketId))
.ForMember(x => x.Quantity, o => o.MapFrom(src => src.Quantity))
.ForMember(x => x.UseLimitTime, o => o.MapFrom(src => src.UseLimitTime));

this.SourceMemberNamingConvention = DatabaseNamingConvention.Instance;
this.DestinationMemberNamingConvention = LowerUnderscoreNamingConvention.Instance;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ public class SummonReverseMapProfile : Profile
public SummonReverseMapProfile()
{
this.CreateMap<SummonTicketList, DbSummonTicket>()
.ForMember(x => x.Type, o => o.MapFrom(src => src.summon_ticket_id))
.ForMember(x => x.Quantity, o => o.MapFrom(src => src.quantity))
.ForMember(x => x.ExpirationTime, o => o.MapFrom(src => src.use_limit_time))
.ForMember(x => x.TicketKeyId, o => o.Ignore())
.ForMember(x => x.SummonTicketId, o => o.MapFrom(src => src.SummonTicketId))
.ForMember(x => x.Quantity, o => o.MapFrom(src => src.Quantity))
.ForMember(x => x.UseLimitTime, o => o.MapFrom(src => src.UseLimitTime))
.ForMember(x => x.KeyId, o => o.Ignore())
.ForMember(x => x.ViewerId, o => o.Ignore())
.ForMember(x => x.Owner, o => o.Ignore());

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using DragaliaAPI.Database.Entities;
using DragaliaAPI.Database.Repositories;
using DragaliaAPI.Features.Summoning;
using DragaliaAPI.Models.Generated;
using DragaliaAPI.Services;
using DragaliaAPI.Shared.Definitions.Enums;
Expand Down
1 change: 1 addition & 0 deletions DragaliaAPI/DragaliaAPI/DragaliaAPI.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" />
<PackageReference Include="MudBlazor" />
<PackageReference Include="Riok.Mapperly" />
<PackageReference Include="Serilog.Exceptions" />
<PackageReference Include="Serilog.Expressions" />
<PackageReference Include="Serilog.Settings.Configuration" />
Expand Down
2 changes: 1 addition & 1 deletion DragaliaAPI/DragaliaAPI/Features/GraphQL/Schema.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace DragaliaAPI.Features.GraphQL;

public static class Schema
{
public static IServiceCollection ConfigureGraphQlSchema(this IServiceCollection collection) =>
public static IServiceCollection ConfigureGraphQLSchema(this IServiceCollection collection) =>
collection.AddGraphQLSchema<ApiContext>(options =>
{
options.AutoBuildSchemaFromContext = true;
Expand Down
2 changes: 1 addition & 1 deletion DragaliaAPI/DragaliaAPI/Features/Shop/PaymentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ public async Task ProcessPayment(Entity entity, PaymentTarget? payment = null)
break;
case EntityTypes.SummonTicket:
DbSummonTicket? ticket = await ticketRepository.Tickets.SingleOrDefaultAsync(x =>
x.TicketKeyId == entity.Id
x.KeyId == entity.Id
);
quantity = ticket?.Quantity;
// NOTE: Maybe remove here once quantity == 0?
Expand Down
12 changes: 12 additions & 0 deletions DragaliaAPI/DragaliaAPI/Features/Summoning/FeatureExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using DragaliaAPI.Features.Summoning;

// ReSharper disable once CheckNamespace
namespace Microsoft.Extensions.DependencyInjection;

public static partial class FeatureExtensions
{
public static IServiceCollection AddSummoningFeature(
this IServiceCollection serviceCollection
) =>
serviceCollection.AddScoped<ISummonService, SummonService>().AddScoped<SummonListService>();
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using DragaliaAPI.Models.Generated;

namespace DragaliaAPI.Services;
namespace DragaliaAPI.Features.Summoning;

public interface ISummonService
{
Expand Down
33 changes: 33 additions & 0 deletions DragaliaAPI/DragaliaAPI/Features/Summoning/SummonBannerOptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
using DragaliaAPI.Shared.Definitions.Enums;

namespace DragaliaAPI.Features.Summoning;

public class SummonBannerOptions
{
public required IReadOnlyList<Banner> Banners { get; init; }
}

public class Banner
{
public int Id { get; init; }

public DateTime Start { get; init; }

public DateTime End { get; init; }

public bool IsGala { get; init; }

public bool IsPrizeShowcase { get; init; }

public required IReadOnlyList<Charas> FeaturedAdventurers { get; init; }

public required IReadOnlyList<Dragons> FeaturedDragons { get; init; }

public required IReadOnlyList<Charas> LimitedAdventurers { get; init; }

public required IReadOnlyList<Dragons> LimitedDragons { get; init; }

public required IReadOnlyList<Charas> TradeAdventurers { get; init; }

public required IReadOnlyList<Dragons> TradeDragons { get; init; }
}
Loading

0 comments on commit c48c2a9

Please sign in to comment.