Skip to content

Commit e78ee9f

Browse files
committed
Refactor emoji handling and improve maintainability
Refactored `CardAutocompleteProvider` to support multiple locales and improved filtering logic for card actions. Replaced hardcoded emoji replacements with dynamic `<img>` tag handling using a new `ImgTagRegex` method and `HoyolabSharedUtils.UrlToEmojis`. Replaced `RoleEmojisModule` and `UpdateRoleEmojisSlashCommand` with `UpdateEmojisModule` and `UpdateEmojisSlashCommand`, adding support for dynamic emoji creation from roles and URLs. Consolidated emoji-related logic into a modular structure for better scalability. Introduced `HoyolabSharedUtils` to centralize constants and utilities. Enhanced `UpdateEmojisSlashCommand` to encode images in WebP format before uploading. Removed unused imports and redundant code across modules. Improved readability and maintainability throughout the codebase.
1 parent daabe0d commit e78ee9f

9 files changed

Lines changed: 143 additions & 82 deletions

File tree

src/GitcgNetCord.MainApp/Commands/Autocompletes/CardAutocompleteProvider.cs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@ AutocompleteInteractionContext context
1818
{
1919
var keyword = option.Value!;
2020

21-
var cardActions = await cardActionService.GetCardActionsAsync("vi-vn");
21+
List<HoyolabHttpClient.Responses.CardActions.Data> cardActions = [
22+
await cardActionService.GetCardActionsAsync(),
23+
await cardActionService.GetCardActionsAsync("vi-vn")
24+
];
2225

23-
var suggestions = cardActions.Actions
26+
var suggestions = cardActions
27+
.SelectMany(x => x.Actions)
28+
.DistinctBy(x => x.Basic.Name)
2429
.Where(x => StartsWith(x.Basic.Name, keyword) || Contains(x.Basic.Name, keyword))
2530
.OrderBy(x => StartsWith(x.Basic.Name, keyword) ? 0 : 1)
2631
.Select(x => new ApplicationCommandOptionChoiceProperties(x.Basic.Name, x.Basic.ItemId));

src/GitcgNetCord.MainApp/Commands/Slash/TcgCardSlashCommand.cs

Lines changed: 34 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using NetCord.Rest;
77
using NetCord.Services.ApplicationCommands;
88
using System.Collections.Immutable;
9+
using System.Text;
910
using System.Text.RegularExpressions;
1011
using Color = System.Drawing.Color;
1112

@@ -95,54 +96,38 @@ await context.Interaction.ModifyResponseAsync(message =>
9596

9697
string GetName(int cardId)
9798
{
98-
return GetDesc(
99-
$"{data.Cost1Raw}" +
100-
$"<img src='{data.Cost2TypeIcon}' /> - " +
101-
$"{action.Basic.Name}"
102-
);
99+
var builder = new StringBuilder();
100+
if (data.Cost2Raw > 0)
101+
{
102+
builder.Append($"<img src='{data.Cost2TypeIcon}' /> - ");
103+
}
104+
builder.Append($"{data.Cost1Raw} ");
105+
builder.Append($"<img src='{data.Cost1TypeIcon}' /> ");
106+
builder.Append($"- {action.Basic.Name} ");
107+
108+
return GetDesc(builder.ToString());
103109
}
104110

105111
string GetDesc(string desc)
106112
{
107113
var result = desc;
108114

109115
result = result.Replace("\\n", "\n");
110-
result = result.Replace(
111-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/e25f04745615df9e779831a1c1354e38.png' />",
112-
emojis["food"].ToString()
113-
);
114-
result = result.Replace(
115-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/d92127a21b942663e6ed0717cef1086e.png' />",
116-
emojis["location"].ToString()
117-
);
118-
result = result.Replace(
119-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/377c4198e3072e9c68066736be5b790c.png' />",
120-
emojis["item"].ToString()
121-
);
122-
result = result.Replace(
123-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/1643452964b58e2e69e64e2b5d3b5878.png' />",
124-
emojis["catalyst"].ToString()
125-
);
126-
result = result.Replace(
127-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/49acb071b0d634ded17cb788d9f520ed.png' />",
128-
emojis["weapon"].ToString()
129-
);
130-
result = result.Replace(
131-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/e1430a8775eb864ed0617b7ef516e608.png' />",
132-
emojis["physical_dmg"].ToString()
133-
);
134-
result = result.Replace(
135-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/8401f5013a7c381edb6cd088b207bb9f.png' />",
136-
emojis["omni"].ToString()
137-
);
138-
result = result.Replace(
139-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/' />",
140-
emojis["aligned"].ToString()
141-
);
142-
result = result.Replace(
143-
"<img src='https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/39de35b178b080a090ac95622bbbf0df.png' />",
144-
emojis["unaligned"].ToString()
145-
);
116+
117+
result = ImgTagRegex().Replace(result, match =>
118+
{
119+
var url = match.Groups["url"].Value;
120+
121+
ApplicationEmoji? emoji = null;
122+
123+
var availableEmojis = HoyolabSharedUtils.UrlToEmojis
124+
.TryGetValue(url, out var emojiKey)
125+
&& emojis.TryGetValue(emojiKey, out emoji);
126+
127+
if (availableEmojis) return emoji!.ToString();
128+
129+
return match.Value; // leave unchanged if not found
130+
});
146131

147132
while (ColorTagRegex().IsMatch(result))
148133
{
@@ -160,4 +145,12 @@ string GetDesc(string desc)
160145
)
161146
]
162147
private static partial Regex ColorTagRegex();
148+
149+
[
150+
GeneratedRegex(
151+
pattern: @"<img\s+src=['""](?<url>[^'""]+)['""][^>]*\/?>",
152+
options: RegexOptions.IgnoreCase, cultureName: "en-US"
153+
)
154+
]
155+
private static partial Regex ImgTagRegex();
163156
}

src/GitcgNetCord.MainApp/Commands/Slash/UpdateRoleEmojisSlashCommand.cs renamed to src/GitcgNetCord.MainApp/Commands/Slash/UpdateEmojisSlashCommand.cs

Lines changed: 42 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
1-
using System.Collections.Concurrent;
2-
using System.Collections.Immutable;
31
using GitcgNetCord.MainApp.Commands.Preconditions;
4-
using GitcgPainter;
5-
using GitcgPainter.Extensions;
2+
using GitcgSkia;
3+
using GitcgSkia.Extensions;
64
using HoyolabHttpClient;
75
using NetCord;
86
using NetCord.Rest;
97
using NetCord.Services.ApplicationCommands;
108
using SixLabors.ImageSharp;
9+
using SkiaSharp;
10+
using System.Collections.Concurrent;
11+
using System.Collections.Immutable;
1112

1213
namespace GitcgNetCord.MainApp.Commands.Slash;
1314

14-
public static class UpdateRoleEmojisSlashCommand
15+
public static class UpdateEmojisSlashCommand
1516
{
1617
private static ImmutableDictionary<string, ApplicationEmoji> _emojis = null!;
1718

@@ -36,9 +37,14 @@ await context.Interaction.SendResponseAsync(
3637

3738
ConcurrentBag<ApplicationEmoji> newEmotes = [];
3839

39-
await Task.WhenAll(
40-
response.Roles.Select(CreateApplicationEmoteAsync)
41-
);
40+
await Task.WhenAll([
41+
..response.Roles.Select(CreateApplicationEmoteByRoleAsync),
42+
..HoyolabSharedUtils.UrlToEmojis.Select(
43+
x => CreateApplicationEmoteByUrlAsync(
44+
emojiName: x.Value, url: x.Key
45+
)
46+
)
47+
]);
4248

4349
var newEmotesString = string.Join(" ", newEmotes);
4450

@@ -53,27 +59,49 @@ Emojis updated!
5359

5460
return;
5561

56-
async Task CreateApplicationEmoteAsync(
62+
async Task CreateApplicationEmoteByRoleAsync(
5763
HoyolabHttpClient.Models.Role role
5864
)
5965
{
6066
var emojiName = role.Basic.ItemId.ToString();
67+
var url = role.Basic.IconSmall;
68+
69+
await CreateApplicationEmoteByUrlAsync(emojiName, url);
70+
}
6171

72+
async Task CreateApplicationEmoteByUrlAsync(
73+
string emojiName, string url
74+
)
75+
{
6276
// Skip if the emote already exists
6377
if (_emojis.ContainsKey(emojiName))
6478
return;
6579

66-
using var iconSmall = await imageCacheService
67-
.LoadIconSmallAsync(role: role);
68-
using var memoryStream = new MemoryStream();
69-
await iconSmall.SaveAsPngAsync(memoryStream);
80+
if (url == "https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/")
81+
{
82+
url += "item_icon/67c7f719/8b295c3fed21771dcced6055cdf2f2ce.png";
83+
}
84+
85+
using var icon = await imageCacheService.LoadHttpImageAsync(url);
86+
87+
await EncodeThenUploadAsync(emojiName, icon);
88+
}
89+
90+
async Task EncodeThenUploadAsync(
91+
string emojiName, SKBitmap icon
92+
)
93+
{
94+
using var encoded = icon.Encode(
95+
format: SKEncodedImageFormat.Webp,
96+
quality: 100
97+
);
7098

7199
var emoji = await context.Client.Rest.CreateApplicationEmojiAsync(
72100
applicationId: applicationId,
73101
new ApplicationEmojiProperties(
74102
name: emojiName,
75103
image: new ImageProperties()
76-
.WithData(memoryStream.GetBuffer())
104+
.WithData(encoded.ToArray())
77105
)
78106
);
79107

src/GitcgNetCord.MainApp/Extensions/Extensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ this IHost host
2929
host.AddHoyolabGcgModule();
3030

3131
// Utility modules
32-
host.AddRoleEmojisModule();
32+
host.AddUpdateEmojisModule();
3333
}
3434

3535
public static void AddNetCordServices(

src/GitcgNetCord.MainApp/Infrastructure/HoyolabServices/HoyolabDecoder.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using GitcgNetCord.MainApp.Enums;
22
using GitcgNetCord.MainApp.Models;
33
using HoyolabHttpClient;
4-
using HoyolabHttpClient.Models.Interfaces;
54
using Microsoft.Extensions.Options;
65
using SharedUtils;
76

src/GitcgNetCord.MainApp/Modules/RoleEmojisModule.cs

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using GitcgNetCord.MainApp.Commands.Slash;
2+
using NetCord.Hosting.Services.ApplicationCommands;
3+
4+
namespace GitcgNetCord.MainApp.Modules;
5+
6+
public static class UpdateEmojisModule
7+
{
8+
public static void AddUpdateEmojisModule(this IHost host)
9+
{
10+
host.AddSlashCommand(
11+
name: "update-emojis",
12+
description: "Fetch emojis and update the bot's emojis.",
13+
handler: UpdateEmojisSlashCommand.ExecuteAsync
14+
);
15+
}
16+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
using System.Collections.Generic;
2+
3+
namespace HoyolabHttpClient;
4+
5+
public static class HoyolabSharedUtils
6+
{
7+
public const int RoleCardCount = 3;
8+
public const int ActionCardCount = 30;
9+
10+
// Dictionary mapping URLs to emoji keys
11+
public static readonly Dictionary<string, string> UrlToEmojis = new()
12+
{
13+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/e25f04745615df9e779831a1c1354e38.png"] = "food",
14+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/d92127a21b942663e6ed0717cef1086e.png"] = "location",
15+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/377c4198e3072e9c68066736be5b790c.png"] = "item",
16+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/1643452964b58e2e69e64e2b5d3b5878.png"] = "catalyst",
17+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/49acb071b0d634ded17cb788d9f520ed.png"] = "weapon",
18+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/8abebfa3ce62ff97769616f606b9a7f4.png"] = "artifact",
19+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/c77ba0b2ea2bf428b8414c9f9bc86035.png"] = "technique",
20+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/e1430a8775eb864ed0617b7ef516e608.png"] = "physical_dmg",
21+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/"] = "aligned",
22+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/8b295c3fed21771dcced6055cdf2f2ce.png"] = "aligned",
23+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/39de35b178b080a090ac95622bbbf0df.png"] = "unaligned",
24+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/8401f5013a7c381edb6cd088b207bb9f.png"] = "omni",
25+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/54f12c0eadb091b3d564408471387021.png"] = "energy",
26+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/5bdbe64fa0b51912abf046d26f735401.png"] = "arcane_die",
27+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/412134fa7fc8a73b5e20c177a3ae0046.png"] = "cryo_die",
28+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/aebd3583ff696429f2e8d83527149ce3.png"] = "hydro_die",
29+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/fe4517db495f28fdbcb44607d94640c3.png"] = "pyro_die",
30+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/0a7a50d15a7580c4de07a41f87a95787.png"] = "electro_die",
31+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/bff8d36c5fdb0df001e05624aa7b7e97.png"] = "anemo_die",
32+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/680e755181a0b8c29e87d0570815ac29.png"] = "geo_die",
33+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/848248aa7c40784633446db172ee4678.png"] = "dendro_die",
34+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f71f/ad05fb6424e58a2a5685647b6240555a.png"] = "arcane",
35+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/924fba80b9137b4e8fdf5871aa22d666.png"] = "cryo",
36+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/b357f624efdec0c1cc0cc4f180e07db4.png"] = "hydro",
37+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/54e95d5fad102409daf191d692c92adc.png"] = "pyro",
38+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/0ff87d31d2858dc563d4a441cdd42f95.png"] = "electro",
39+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/c89ca75b4aef48091d59bf71aaff2b8b.png"] = "anemo",
40+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/98c267c74a3efdcfed4131a054ff4b82.png"] = "geo",
41+
["https://act-webstatic.hoyoverse.com/hk4e/e20200928calculate/item_icon/67c7f719/0bfb3be161357095eefb85b88c1267a8.png"] = "dendro",
42+
};
43+
}

src/HoyolabHttpClient/Utils.cs

Lines changed: 0 additions & 7 deletions
This file was deleted.

0 commit comments

Comments
 (0)