7
7
using SixLabors . ImageSharp . Processing ;
8
8
using SixLabors . ImageSharp . Drawing . Processing ;
9
9
using SixLabors . Fonts ;
10
+ using System . Text . Json ;
10
11
11
12
namespace JustDanceEditor . Converter . Converters . Images ;
12
13
13
14
public static class CoverArtGenerator
14
15
{
16
+ private static HttpClient httpClient = new ( ) ;
17
+
15
18
public static Image < Rgba32 > ? ExistingCover ( ConvertUbiArtToUnity convert )
16
19
{
17
20
string [ ] paths =
@@ -51,6 +54,12 @@ public static class CoverArtGenerator
51
54
return null ;
52
55
}
53
56
57
+ public static Image < Rgba32 > ? ExistingSongTitleLogo ( ConvertUbiArtToUnity convert )
58
+ {
59
+ // Load the image
60
+ return TryLoadImage ( Path . Combine ( convert . FileSystem . TempFolders . MenuArtFolder , "songTitleLogo.png" ) ) ;
61
+ }
62
+
54
63
static Image < Rgba32 > ? TryLoadImage ( string path )
55
64
{
56
65
if ( ! File . Exists ( path ) )
@@ -62,110 +71,54 @@ public static class CoverArtGenerator
62
71
return coverImage ;
63
72
}
64
73
65
- public static Image < Rgba32 > ? TryCoverWeb ( ConvertUbiArtToUnity convert )
74
+ public static Image < Rgba32 > ? TryImageWeb ( ConvertUbiArtToUnity convert , string imageType )
66
75
{
67
- try
68
- {
69
- string baseURL = "https://justdance.fandom.com" ;
70
-
71
- // Download one from https://justdance.fandom.com/wiki/User_blog:Sweet_King_Candy/Extended_Covers_for_Just_Dance_%2B
72
- // Load the webpage
73
- HttpClient client = new ( ) ;
74
- string html = client . GetStringAsync ( $ "{ baseURL } /wiki/User_blog:Sweet_King_Candy/Extended_Covers_for_Just_Dance_%2B") . Result ;
75
-
76
- // Convert the html to a document
77
- HtmlDocument doc = new ( ) ;
78
- doc . LoadHtml ( html ) ;
79
-
80
- // Get the class called "fandom-table"[0]/tbody
81
- HtmlNode table = doc . DocumentNode . SelectNodes ( "//table[@class='fandom-table']" ) [ 0 ] ;
82
- HtmlNode htmlNode = table . SelectSingleNode ( "tbody" ) ;
83
-
84
- // Get all the tr nodes
85
- List < HtmlNode > allNodes = htmlNode . SelectNodes ( "tr" ) . Skip ( 1 ) . ToList ( ) ;
86
-
87
- // Find the node where the first td's inner text is the map name
88
- List < HtmlNode > nodes = [ ] ;
89
-
90
- foreach ( HtmlNode node in allNodes )
91
- {
92
- // Get the first <i> tag's title, it might not be a direct child
93
- string title = node . SelectSingleNode ( ".//i" ) . FirstChild . InnerText ;
94
-
95
- if ( title . Trim ( ) == convert . SongData . SongDesc . COMPONENTS [ 0 ] . Title . Trim ( ) )
96
- {
97
- nodes . Add ( node ) ;
98
- }
99
- }
100
-
101
- // If the cover doesn't exist, return false
102
- if ( nodes . Count == 0 )
103
- return null ;
104
-
105
- HtmlNode ? row = null ;
106
-
107
- foreach ( HtmlNode node in nodes )
108
- {
109
- // Get the url at .//i//a
110
- string url = baseURL + node . SelectSingleNode ( ".//a" ) . Attributes [ "href" ] . Value ;
111
-
112
- // Load in the page
113
- string pageHtml = client . GetStringAsync ( url ) . Result ;
114
- HtmlDocument wikiPage = new ( ) ;
115
- wikiPage . LoadHtml ( pageHtml ) ;
116
-
117
- // Query for the infobox element
118
- HtmlNode ? codeName = wikiPage . DocumentNode . SelectSingleNode ( "//b[contains(text(), 'Code Name')]" ) ;
119
-
120
- if ( codeName == null )
121
- continue ;
122
-
123
- // Get the parent.parent/div
124
- HtmlNode codeNameElement = codeName . ParentNode . ParentNode ;
76
+ string baseUrl = "https://raw.githubusercontent.com/MrKev312/JustDanceCovers/refs/heads/main/" ;
125
77
126
- string ? codeNameText = codeNameElement . Elements ( "div" ) . FirstOrDefault ( ) ? . FirstChild . InnerText ;
78
+ Image < Rgba32 > ? FetchCoverFromWeb ( string name )
79
+ => LoadFromUrl ( $ "{ baseUrl } /Covers/{ name } /{ imageType } .webp") ;
127
80
128
- if ( codeNameText == null )
129
- continue ;
81
+ Image < Rgba32 > ? coverImage = FetchCoverFromWeb ( convert . SongData . Name ) ;
130
82
131
- // Skip everything after the first space
132
- codeNameText = codeNameText . Split ( ' ' ) [ 0 ] ;
83
+ if ( coverImage is not null )
84
+ {
85
+ Logger . Log ( $ "Found { imageType } on the web", LogLevel . Important ) ;
86
+ return coverImage ;
87
+ }
133
88
134
- if ( codeNameText . Trim ( ) == convert . SongData . Name . Trim ( ) )
135
- {
136
- row = node ;
137
- break ;
138
- }
139
- }
89
+ // Else, maybe we can look in the Covers.json
90
+ string coversJsonUrl = $ "{ baseUrl } /Covers.json";
91
+ string json = httpClient . GetStringAsync ( coversJsonUrl ) . Result ;
92
+ Dictionary < string , string [ ] > covers = JsonSerializer . Deserialize < Dictionary < string , string [ ] > > ( json ) ! ;
140
93
141
- if ( row == null )
142
- return null ;
94
+ string ? codename = covers . Where ( x => x . Value . Contains ( convert . SongData . Name ) ) . Select ( x => x . Key ) . FirstOrDefault ( ) ;
95
+ if ( codename is null )
96
+ return null ;
143
97
144
- // If both the last or second to last td's are empty or "N/A", then the cover doesn't exist
145
- HtmlNodeCollection tds = row . SelectNodes ( "td" ) ;
98
+ // Now we can try to fetch the cover from the web
99
+ return FetchCoverFromWeb ( codename ) ;
100
+ }
146
101
147
- // Get the cover url with text on it
148
- string coverUrl = tds [ ^ 1 ] . SelectSingleNode ( "(.//a )[1]" ) . Attributes [ "href" ] . Value ;
149
- // If this is a placeholder cover, get the second to last, the version without text
150
- if ( coverUrl . Contains ( "PlaceHolderCover" , StringComparison . OrdinalIgnoreCase ) )
151
- coverUrl = tds [ ^ 2 ] . SelectSingleNode ( "(.//a )[1]" ) . Attributes [ "href" ] . Value ;
152
- if ( coverUrl . Contains ( "PlaceHolderCover" , StringComparison . OrdinalIgnoreCase ) )
153
- // Couldn't find the cover, return false
154
- return null ;
102
+ private static Image < Rgba32 > ? LoadFromUrl ( string url )
103
+ {
104
+ // Return null if the URL is invalid or the request fails
105
+ if ( string . IsNullOrEmpty ( url ) )
106
+ return null ;
155
107
156
- // Load the image
157
- Stream coverStream = client . GetStreamAsync ( coverUrl ) . Result ;
158
- Image < Rgba32 > ? coverImage = Image . Load < Rgba32 > ( coverStream ) ;
159
- coverImage . Mutate ( x => x . Resize ( 640 , 360 ) ) ;
108
+ // Send a GET request to the URL
109
+ using HttpResponseMessage response = httpClient . GetAsync ( url ) . Result ;
160
110
161
- // Success!
162
- return coverImage ;
163
- }
164
- catch ( Exception e )
111
+ // Check if the request was successful
112
+ if ( response . IsSuccessStatusCode )
165
113
{
166
- Logger . Log ( $ "Failed to get cover from the web: { e . Message } ", LogLevel . Warning ) ;
167
- return null ;
114
+ // Read the image data from the response
115
+ byte [ ] imageData = response . Content . ReadAsByteArrayAsync ( ) . Result ;
116
+ // Load the image from the byte array
117
+ using MemoryStream stream = new ( imageData ) ;
118
+ return Image . Load < Rgba32 > ( stream ) ;
168
119
}
120
+
121
+ return null ;
169
122
}
170
123
171
124
public static Image < Rgba32 > GenerateOwnCover ( ConvertUbiArtToUnity convert )
0 commit comments