@@ -184,16 +184,27 @@ private void _DownloadAndUnpack() {
184184 int i = 0 ;
185185 foreach ( ZipArchiveEntry entry in zip . Entries ) {
186186 OnProgress ? . Invoke ( Status . Unpack , ( i + 1 ) / ( float ) zip . Entries . Count ) ;
187- string to = Path . Combine ( root , entry . Name ) ;
188- string toParent = Path . GetDirectoryName ( to ) ;
189- Console . WriteLine ( $ "{ entry . Name } -> { to } ") ;
190- if ( ! Directory . Exists ( toParent ) )
191- Directory . CreateDirectory ( toParent ) ;
192- if ( File . Exists ( to ) )
193- File . Delete ( to ) ;
194- using ( FileStream fs = File . OpenWrite ( to ) )
195- using ( Stream compressed = entry . Open ( ) )
196- compressed . CopyTo ( fs ) ;
187+
188+ if ( ! entry . Name . EndsWith ( "/" ) && entry . Length != 0 ) {
189+ string entryName = entry . Name ;
190+ if ( entryName . StartsWith ( "main/" ) )
191+ entryName = entryName . Substring ( 5 ) ;
192+
193+ string to = Path . Combine ( root , entryName ) ;
194+ string toParent = Path . GetDirectoryName ( to ) ;
195+ Console . WriteLine ( $ "{ entry . Name } -> { to } ") ;
196+
197+ if ( ! Directory . Exists ( toParent ) )
198+ Directory . CreateDirectory ( toParent ) ;
199+
200+ if ( File . Exists ( to ) )
201+ File . Delete ( to ) ;
202+
203+ using ( FileStream fs = File . OpenWrite ( to ) )
204+ using ( Stream compressed = entry . Open ( ) )
205+ compressed . CopyTo ( fs ) ;
206+ }
207+
197208 i ++ ;
198209 }
199210 }
@@ -274,77 +285,91 @@ private byte[] _Download(string url) {
274285
275286 // The following blob of code comes from the old ETGMod.Installer.
276287
277- byte [ ] data = null ;
278-
279288 Console . WriteLine ( $ "Downloading { url } ") ;
280289
281- DateTime timeStart = DateTime . Now ;
282- using ( WebClient wc = new WebClient ( ) ) {
283- using ( Stream s = wc . OpenRead ( url ) ) {
284- long sLength ;
285- if ( s . CanSeek ) {
286- // Mono
287- sLength = s . Length ;
288- } else {
289- // .NET
290- HttpWebRequest request = ( HttpWebRequest ) WebRequest . Create ( url ) ;
291- request . UserAgent = $ "MonoMod.Installer { Assembly . GetEntryAssembly ( ) . GetName ( ) . Version } ";
292- request . Method = "HEAD" ;
293- using ( HttpWebResponse response = ( HttpWebResponse ) request . GetResponse ( ) ) {
294- sLength = response . ContentLength ;
290+ using ( MemoryStream copy = new MemoryStream ( ) ) {
291+ DateTime timeStart = DateTime . Now ;
292+ using ( WebClient wc = new WebClient ( ) ) {
293+ using ( Stream input = wc . OpenRead ( url ) ) {
294+ long length ;
295+ if ( input . CanSeek ) {
296+ // Mono
297+ length = input . Length ;
298+ } else {
299+ // .NET
300+ try {
301+ HttpWebRequest request = ( HttpWebRequest ) WebRequest . Create ( url ) ;
302+ request . UserAgent = $ "MonoMod.Installer { Assembly . GetEntryAssembly ( ) . GetName ( ) . Version } ";
303+ request . Method = "HEAD" ;
304+ using ( HttpWebResponse response = ( HttpWebResponse ) request . GetResponse ( ) ) {
305+ length = response . ContentLength ;
306+ }
307+ } catch ( Exception ) {
308+ length = 0 ;
309+ }
295310 }
296- }
297- Console . WriteLine ( $ "{ sLength } bytes") ;
298- data = new byte [ sLength ] ;
299-
300- long progressSize = sLength ;
301- int progressScale = 1 ;
302- while ( progressSize > int . MaxValue ) {
303- progressScale *= 10 ;
304- progressSize = sLength / progressScale ;
305- }
311+ Console . WriteLine ( $ "{ length } bytes") ;
306312
307- OnProgress ? . Invoke ( Status . Download , 0f ) ;
308-
309- DateTime timeLast = timeStart ;
310-
311- int read ;
312- int readForSpeed = 0 ;
313- int pos = 0 ;
314- int speed = 0 ;
315- TimeSpan td ;
316- while ( pos < data . Length ) {
317- read = s . Read ( data , pos , Math . Min ( 2048 , data . Length - pos ) ) ;
318- pos += read ;
319- readForSpeed += read ;
320-
321- td = ( DateTime . Now - timeLast ) ;
322- if ( td . TotalMilliseconds > 100 ) {
323- speed = ( int ) ( ( readForSpeed / 1024D ) / td . TotalSeconds ) ;
324- readForSpeed = 0 ;
325- timeLast = DateTime . Now ;
313+ long progressSize = length ;
314+ int progressScale = 1 ;
315+ while ( progressSize > int . MaxValue ) {
316+ progressScale *= 10 ;
317+ progressSize = length / progressScale ;
326318 }
327319
328- OnProgress ? . Invoke ( Status . Download , ( float ) ( ( pos / progressScale ) / ( double ) progressSize ) ) ;
329- LogWriter . OnWriteLine ? . Invoke (
330- "Downloading - " +
331- ( int ) ( Math . Round ( 100D * ( ( pos / progressScale ) / ( double ) progressSize ) ) ) + "%, " +
332- speed + " KiB/s"
333- ) ;
334- }
320+ OnProgress ? . Invoke ( Status . Download , 0f ) ;
321+
322+ DateTime timeLast = timeStart ;
323+
324+ byte [ ] buffer = new byte [ 4096 ] ;
325+ DateTime timeLastSpeed = timeStart ;
326+ int read = 1 ;
327+ int readForSpeed = 0 ;
328+ int pos = 0 ;
329+ int speed = 0 ;
330+ int count = 0 ;
331+ TimeSpan td ;
332+ while ( read > 0 ) {
333+ count = length > 0 ? ( int ) Math . Min ( buffer . Length , length - pos ) : buffer . Length ;
334+ read = input . Read ( buffer , 0 , count ) ;
335+ copy . Write ( buffer , 0 , read ) ;
336+ pos += read ;
337+ readForSpeed += read ;
338+
339+ td = ( DateTime . Now - timeLast ) ;
340+ if ( td . TotalMilliseconds > 100 ) {
341+ speed = ( int ) ( ( readForSpeed / 1024D ) / td . TotalSeconds ) ;
342+ readForSpeed = 0 ;
343+ timeLast = DateTime . Now ;
344+ }
345+
346+ if ( length > 0 ) {
347+ OnProgress ? . Invoke ( Status . Download , ( float ) ( ( pos / progressScale ) / ( double ) progressSize ) ) ;
348+ LogWriter . OnWriteLine ? . Invoke (
349+ $ "Downloading: { ( ( int ) Math . Floor ( 100D * ( pos / ( double ) length ) ) ) } % @ { speed } KiB/s"
350+ ) ;
351+ } else {
352+ OnProgress ? . Invoke ( Status . Download , 1f ) ;
353+ LogWriter . OnWriteLine ? . Invoke (
354+ $ "Downloading: { ( ( int ) Math . Floor ( pos / 1000D ) ) } KiB @ { speed } KiB/s"
355+ ) ;
356+ }
357+ }
335358
359+ }
336360 }
337- }
338361
339- OnProgress ? . Invoke ( Status . Download , 1f ) ;
362+ OnProgress ? . Invoke ( Status . Download , 1f ) ;
340363
341- string logSize = ( data . Length / 1024D ) . ToString ( CultureInfo . InvariantCulture ) ;
342- logSize = logSize . Substring ( 0 , Math . Min ( logSize . IndexOf ( '.' ) + 3 , logSize . Length ) ) ;
343- string logTime = ( DateTime . Now - timeStart ) . TotalSeconds . ToString ( CultureInfo . InvariantCulture ) ;
344- logTime = logTime . Substring ( 0 , Math . Min ( logTime . IndexOf ( '.' ) + 3 , logTime . Length ) ) ;
345- Console . WriteLine ( $ "Downloaded { logSize } KiB in { logTime } seconds.") ;
364+ byte [ ] data = copy . ToArray ( ) ;
365+ string logSize = ( data . Length / 1024D ) . ToString ( CultureInfo . InvariantCulture ) ;
366+ logSize = logSize . Substring ( 0 , Math . Min ( logSize . IndexOf ( '.' ) + 3 , logSize . Length ) ) ;
367+ string logTime = ( DateTime . Now - timeStart ) . TotalSeconds . ToString ( CultureInfo . InvariantCulture ) ;
368+ logTime = logTime . Substring ( 0 , Math . Min ( logTime . IndexOf ( '.' ) + 3 , logTime . Length ) ) ;
369+ Console . WriteLine ( $ "Downloaded { logSize } KiB in { logTime } seconds.") ;
346370
347- return data ;
371+ return data ;
372+ }
348373 }
349374
350375 public enum Status {
0 commit comments