5
5
using System . Linq ;
6
6
using System . Net ;
7
7
using System . Net . Http . Headers ;
8
+ using System . Security . Policy ;
8
9
using System . Threading . Tasks ;
9
10
using System . Web ;
10
11
using System . Windows ;
12
+ using System . Windows . Input ;
11
13
using static ModAssistant . Http ;
12
14
13
15
namespace ModAssistant . API
14
16
{
15
17
public class BeatSaver
16
18
{
17
- private const string BeatSaverURLPrefix = "https://api.beatsaver.com" ;
19
+ private static string BeatSaverURLPrefix { get =>
20
+ Properties . Settings . Default . AssetsDownloadServer == AssetsServer . Default ? ModAssistant . Utils . Constants . BeatSaverURLPrefix_default :
21
+ ( Properties . Settings . Default . AssetsDownloadServer == AssetsServer . WGZeyu ? ModAssistant . Utils . Constants . BeatSaverURLPrefix_wgzeyu :
22
+ ModAssistant . Utils . Constants . BeatSaverURLPrefix_beatsaberchina ) ;
23
+ }
24
+
25
+ private static string BeatSaverCDNURLPrefix
26
+ {
27
+ get =>
28
+ Properties . Settings . Default . AssetsDownloadServer == AssetsServer . Default ? ModAssistant . Utils . Constants . BeatSaverCDNURLPrefix_default :
29
+ ( Properties . Settings . Default . AssetsDownloadServer == AssetsServer . WGZeyu ? ModAssistant . Utils . Constants . BeatSaverCDNURLPrefix_wgzeyu :
30
+ ModAssistant . Utils . Constants . BeatSaverCDNURLPrefix_beatsaberchina ) ;
31
+ }
18
32
private static readonly string CustomSongsFolder = Path . Combine ( "Beat Saber_Data" , "CustomLevels" ) ;
19
33
private static readonly string CustomWIPSongsFolder = Path . Combine ( "Beat Saber_Data" , "CustomWIPLevels" ) ;
20
34
private const bool BypassDownloadCounter = false ;
21
35
22
- public static async Task < BeatSaverMap > GetFromKey ( string Key , bool showNotification = true )
36
+ public static async Task < BeatSaverMap > GetFromKey ( string Key , bool showNotification = true , bool fromPlaylist = false )
23
37
{
24
38
if ( showNotification && App . OCIWindow != "No" && App . OCIWindow != "Notify" ) OneClickInstaller . Status . Show ( ) ;
25
- return await GetMap ( Key , "key" , showNotification ) ;
39
+ return await GetMap ( Key , "key" , showNotification , fromPlaylist ) ;
26
40
}
27
41
28
- public static async Task < BeatSaverMap > GetFromHash ( string Hash , bool showNotification = true )
42
+ public static async Task < BeatSaverMap > GetFromHash ( string Hash , bool showNotification = true , bool fromPlaylist = false )
29
43
{
30
44
if ( showNotification && App . OCIWindow != "No" && App . OCIWindow != "Notify" ) OneClickInstaller . Status . Show ( ) ;
31
- return await GetMap ( Hash , "hash" , showNotification ) ;
45
+ return await GetMap ( Hash , "hash" , showNotification , fromPlaylist ) ;
32
46
}
33
47
34
- private static async Task < BeatSaverMap > GetMap ( string id , string type , bool showNotification )
48
+ private static async Task < BeatSaverMap > GetMap ( string id , string type , bool showNotification , bool fromPlaylist = false )
35
49
{
36
50
string urlSegment ;
37
51
switch ( type )
@@ -54,7 +68,12 @@ private static async Task<BeatSaverMap> GetMap(string id, string type, bool show
54
68
if ( showNotification ) Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "OneClick:Installing" ) , id ) } ") ;
55
69
try
56
70
{
57
- BeatSaverApiResponse beatsaver = await GetResponse ( BeatSaverURLPrefix + urlSegment + id ) ;
71
+ var result = proxyURL ( "" , true , fromPlaylist , showNotification ) ;
72
+ if ( result [ 1 ] )
73
+ {
74
+ Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "OneClick:Fallback" ) , "默认@default" ) } ") ;
75
+ }
76
+ BeatSaverApiResponse beatsaver = await GetResponse ( result [ 0 ] + urlSegment + id ) ;
58
77
if ( beatsaver != null && beatsaver . map != null )
59
78
{
60
79
map . response = beatsaver ;
@@ -71,14 +90,19 @@ private static async Task<BeatSaverMap> GetMap(string id, string type, bool show
71
90
}
72
91
map . HashToDownload = mapVersion . hash ;
73
92
}
74
- map . Name = await InstallMap ( map , showNotification ) ;
93
+ map . Name = await InstallMap ( map , showNotification , fromPlaylist , result [ 1 ] ) ;
94
+ if ( ModAssistant . Properties . Settings . Default . AssetsDownloadServer == "国内源@WGzeyu" && ! result [ 1 ] )
95
+ {
96
+ Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "MainWindow:AssetsServerLimitLabel" ) , ZeyuCount . getCount ( ) . ToString ( ) ) } ") ;
97
+ }
75
98
map . Success = true ;
76
99
}
77
100
}
78
101
catch ( Exception e )
79
102
{
80
- ModAssistant . Utils . Log ( $ "Failed downloading BeatSaver map: { id } | Error: { e . Message } ", "ERROR" ) ;
103
+ ModAssistant . Utils . Log ( $ "Failed downloading BeatSaver map: { id } | Error: { e . Message } \n { e . StackTrace } ", "ERROR" ) ;
81
104
Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "OneClick:Failed" ) , ( map . Name ?? id ) ) } ") ;
105
+ Utils . SetMessage ( e . Message ) ;
82
106
App . CloseWindowOnFinish = false ;
83
107
}
84
108
return map ;
@@ -131,12 +155,19 @@ private static async Task<BeatSaverApiResponse> GetResponse(string url, bool sho
131
155
}
132
156
}
133
157
134
- public static async Task < string > InstallMap ( BeatSaverMap Map , bool showNotification = true )
158
+ public static async Task < string > InstallMap ( BeatSaverMap Map , bool showNotification = true , bool fromPlaylist = false , bool fallback = false )
135
159
{
136
160
BeatSaverApiResponseMap responseMap = Map . response . map ;
137
- BeatSaverApiResponseMap . BeatsaverMapVersion mapVersion = responseMap . versions . Where ( r => r . hash == Map . HashToDownload ) . First ( ) ;
138
- if ( mapVersion == null )
161
+ BeatSaverApiResponseMap . BeatsaverMapVersion mapVersion = null ;
162
+ try
139
163
{
164
+ mapVersion = responseMap . versions . Where ( r => r . hash == Map . HashToDownload ) . First ( ) ;
165
+ if ( mapVersion == null )
166
+ {
167
+ throw new Exception ( "Could not find map version." ) ;
168
+ }
169
+ }
170
+ catch ( Exception ) {
140
171
throw new Exception ( "Could not find map version." ) ;
141
172
}
142
173
@@ -152,11 +183,11 @@ public static async Task<string> InstallMap(BeatSaverMap Map, bool showNotificat
152
183
#pragma warning disable CS0162 // Unreachable code detected
153
184
if ( BypassDownloadCounter )
154
185
{
155
- await Utils . DownloadAsset ( mapVersion . downloadURL , targetSongDirectory , Map . HashToDownload + ".zip" , mapName , showNotification , true ) ;
186
+ await Utils . DownloadAsset ( mapVersion . downloadURL , targetSongDirectory , Map . HashToDownload + ".zip" , mapName , showNotification , true , false , fromPlaylist , fallback ) ;
156
187
}
157
188
else
158
189
{
159
- await Utils . DownloadAsset ( mapVersion . downloadURL , targetSongDirectory , Map . HashToDownload + ".zip" , mapName , showNotification , true ) ;
190
+ await Utils . DownloadAsset ( mapVersion . downloadURL , targetSongDirectory , Map . HashToDownload + ".zip" , mapName , showNotification , true , false , fromPlaylist , fallback ) ;
160
191
}
161
192
#pragma warning restore CS0162 // Unreachable code detected
162
193
@@ -251,8 +282,11 @@ public static DateTime UnixTimestampToDateTime(double unixTime)
251
282
return new DateTime ( unixStart . Ticks + unixTimeStampInTicks , DateTimeKind . Utc ) ;
252
283
}
253
284
254
- public static async Task Download ( string url , string output , int retries = 3 )
285
+ public static async Task Download ( string url , string output , bool fromPlaylist , bool fallback = false , int retries = 3 )
255
286
{
287
+ var result = proxyURL ( url , false , fromPlaylist ) ;
288
+ url = result [ 0 ] ;
289
+ fallback = result [ 1 ] ;
256
290
if ( retries == 0 )
257
291
{
258
292
Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "OneClick:RatelimitSkip" ) , url ) } ") ;
@@ -269,13 +303,18 @@ public static async Task Download(string url, string output, int retries = 3)
269
303
Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "OneClick:RatelimitHit" ) , ratelimit . ResetTime . ToLocalTime ( ) ) } ") ;
270
304
271
305
await ratelimit . Wait ( ) ;
272
- await Download ( url , output , retries - 1 ) ;
306
+ await Download ( url , output , fromPlaylist , fallback , retries - 1 ) ;
273
307
}
274
308
275
309
using ( var stream = await resp . Content . ReadAsStreamAsync ( ) )
276
310
using ( var fs = new FileStream ( output , FileMode . OpenOrCreate , FileAccess . Write ) )
277
311
{
278
312
await stream . CopyToAsync ( fs ) ;
313
+ if ( fromPlaylist ) {
314
+ ModAssistant . ZeyuCount . downloadBeatsaverMultiple ( ) ;
315
+ } else {
316
+ ModAssistant . ZeyuCount . downloadBeatsaverSingle ( ) ;
317
+ }
279
318
}
280
319
}
281
320
@@ -389,6 +428,25 @@ public class ParitySummary
389
428
public int resets { get ; set ; }
390
429
}
391
430
}
431
+
432
+ public static dynamic [ ] proxyURL ( string url , bool api = false , bool fromPlaylist = false , bool showNotification = false ) {
433
+ string ProxyURL = api ? BeatSaverURLPrefix : BeatSaverCDNURLPrefix ;
434
+ bool fallback = false ;
435
+
436
+ if ( Properties . Settings . Default . AssetsDownloadServer == "国内源@WGzeyu" && ( ( fromPlaylist && ! ModAssistant . ZeyuCount . checkBeatsaverMultiple ( ) ) || ( ! fromPlaylist && ! ModAssistant . ZeyuCount . checkBeatsaverSingle ( ) ) ) )
437
+ {
438
+ if ( showNotification ) Utils . SetMessage ( $ "{ string . Format ( ( string ) Application . Current . FindResource ( "OneClick:Fallback" ) , "默认@default" ) } ") ;
439
+ ProxyURL = api ? ModAssistant . Utils . Constants . BeatSaverURLPrefix_default : ModAssistant . Utils . Constants . BeatSaverCDNURLPrefix_default ;
440
+ fallback = true ;
441
+ }
442
+
443
+ dynamic [ ] result = new dynamic [ ] { api ? ProxyURL : url . Replace ( "https://as.cdn.beatsaver.com" , "https://cdn.beatsaver.com" )
444
+ . Replace ( "https://na.cdn.beatsaver.com" , "https://cdn.beatsaver.com" )
445
+ . Replace ( "https://r2cdn.beatsaver.com" , "https://cdn.beatsaver.com" )
446
+ . Replace ( "https://cdn.beatsaver.com" , ProxyURL ) , fallback } ;
447
+
448
+ return result ;
449
+ }
392
450
}
393
451
}
394
452
#pragma warning restore IDE1006 // Naming Styles
0 commit comments