Skip to content

Commit 8056e1e

Browse files
committed
update ExctractTarGz, fixes #149, fix hidden beta regex parsing (feature not enabled yet)
1 parent c614492 commit 8056e1e

File tree

2 files changed

+125
-66
lines changed

2 files changed

+125
-66
lines changed

Diff for: UnityLauncherPro/Libraries/ExtractTarGz.cs

+116-57
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// source https://gist.github.com/Su-s/438be493ae692318c73e30367cbc5c2a
2+
// updated source https://gist.github.com/Matheos96/da8990030dfe3e27b0a48722042d9c0b
23

34
using System;
45
using System.IO;
@@ -16,7 +17,10 @@ public class Tar
1617
/// <param name="outputDir">Output directory to write the files.</param>
1718
public static void ExtractTarGz(string filename, string outputDir)
1819
{
19-
using (var stream = File.OpenRead(filename)) ExtractTarGz(stream, outputDir);
20+
using (var stream = File.OpenRead(filename))
21+
{
22+
ExtractTarGz(stream, outputDir);
23+
}
2024
}
2125

2226
/// <summary>
@@ -26,9 +30,25 @@ public static void ExtractTarGz(string filename, string outputDir)
2630
/// <param name="outputDir">Output directory to write the files.</param>
2731
public static void ExtractTarGz(Stream stream, string outputDir)
2832
{
29-
using (var gzip = new GZipStream(stream, CompressionMode.Decompress))
33+
int read;
34+
const int chunk = 4096;
35+
var buffer = new byte[chunk];
36+
37+
// A GZipStream is not seekable, so copy it first to a MemoryStream
38+
using (var gzipStream = new GZipStream(stream, CompressionMode.Decompress))
3039
{
31-
ExtractTar(gzip, outputDir);
40+
using (var memStream = new MemoryStream())
41+
{
42+
//For .NET 6+
43+
while ((read = gzipStream.Read(buffer, 0, buffer.Length)) > 0)
44+
{
45+
memStream.Write(buffer, 0, read);
46+
}
47+
memStream.Seek(0, SeekOrigin.Begin);
48+
49+
//ExtractTar(gzip, outputDir);
50+
ExtractTar(memStream, outputDir);
51+
}
3252
}
3353
}
3454

@@ -40,7 +60,9 @@ public static void ExtractTarGz(Stream stream, string outputDir)
4060
public static void ExtractTar(string filename, string outputDir)
4161
{
4262
using (var stream = File.OpenRead(filename))
63+
{
4364
ExtractTar(stream, outputDir);
65+
}
4466
}
4567

4668
/// <summary>
@@ -51,78 +73,115 @@ public static void ExtractTar(string filename, string outputDir)
5173
public static void ExtractTar(Stream stream, string outputDir)
5274
{
5375
var buffer = new byte[100];
54-
// store current position here
55-
long pos = 0;
76+
var longFileName = string.Empty;
5677
while (true)
5778
{
58-
pos += stream.Read(buffer, 0, 100);
59-
var name = Encoding.ASCII.GetString(buffer).Trim('\0');
60-
if (String.IsNullOrWhiteSpace(name)) break;
61-
FakeSeekForward(stream, 24);
62-
pos += 24;
79+
stream.Read(buffer, 0, 100);
80+
string name = string.IsNullOrEmpty(longFileName) ? Encoding.ASCII.GetString(buffer).Trim('\0') : longFileName; //Use longFileName if we have one read
6381

64-
pos += stream.Read(buffer, 0, 12);
82+
if (String.IsNullOrWhiteSpace(name)) break;
83+
stream.Seek(24, SeekOrigin.Current);
84+
stream.Read(buffer, 0, 12);
6585
var size = Convert.ToInt64(Encoding.UTF8.GetString(buffer, 0, 12).Trim('\0').Trim(), 8);
66-
FakeSeekForward(stream, 376);
67-
pos += 376;
86+
stream.Seek(20, SeekOrigin.Current); //Move head to typeTag byte
87+
var typeTag = stream.ReadByte();
88+
stream.Seek(355L, SeekOrigin.Current); //Move head to beginning of data (byte 512)
89+
90+
if (typeTag == 'L')
91+
{
92+
//If Type Tag is 'L' we have a filename that is longer than the 100 bytes reserved for it in the header.
93+
//We read it here and save it temporarily as it will be the file name of the next block where the actual data is
94+
var buf = new byte[size];
95+
stream.Read(buf, 0, buf.Length);
96+
longFileName = Encoding.ASCII.GetString(buf).Trim('\0');
97+
}
98+
else
99+
{
100+
longFileName = string.Empty; //Reset longFileName if current entry is not indicating one
68101

69-
var output = Path.Combine(outputDir, name);
102+
var output = Path.Combine(outputDir, name);
70103

71-
// only include these folders
72-
var include = (output.IndexOf("package/ProjectData~/Assets/") > -1);
73-
include |= (output.IndexOf("package/ProjectData~/ProjectSettings/") > -1);
74-
include |= (output.IndexOf("package/ProjectData~/Packages/") > -1);
104+
// only include these folders
105+
var include = (output.IndexOf("package/ProjectData~/Assets/") > -1);
106+
include |= (output.IndexOf("package/ProjectData~/ProjectSettings/") > -1);
107+
include |= (output.IndexOf("package/ProjectData~/Packages/") > -1);
75108

76-
// rename output path from "package/ProjectData~/Assets/" into "Assets/"
77-
output = output.Replace("package/ProjectData~/", "");
109+
// rename output path from "package/ProjectData~/Assets/" into "Assets/"
110+
output = output.Replace("package/ProjectData~/", "");
78111

79-
if (include == true && !Directory.Exists(Path.GetDirectoryName(output))) Directory.CreateDirectory(Path.GetDirectoryName(output));
112+
if (include == true && !Directory.Exists(Path.GetDirectoryName(output))) Directory.CreateDirectory(Path.GetDirectoryName(output));
80113

81-
if (!name.Equals("./", StringComparison.InvariantCulture))
82-
{
83-
if (include == true)
114+
// not folder
115+
//if (name.Equals("./", StringComparison.InvariantCulture) == false)
116+
if (name.EndsWith("/") == false) //Directories are zero size and don't need anything written
84117
{
85-
//Console.WriteLine("output=" + output);
86-
using (var str = File.Open(output, FileMode.OpenOrCreate, FileAccess.Write))
118+
if (include == true)
119+
{
120+
//Console.WriteLine("output=" + output);
121+
using (var str = File.Open(output, FileMode.OpenOrCreate, FileAccess.ReadWrite))
122+
{
123+
var buf = new byte[size];
124+
stream.Read(buf, 0, buf.Length);
125+
// take only data from this folder
126+
str.Write(buf, 0, buf.Length);
127+
}
128+
}
129+
else
87130
{
88131
var buf = new byte[size];
89-
pos += stream.Read(buf, 0, buf.Length);
90-
// take only data from this folder
91-
str.Write(buf, 0, buf.Length);
132+
stream.Read(buf, 0, buf.Length);
92133
}
93134
}
94-
else
95-
{
96-
//pos += size;
97-
var buf = new byte[size];
98-
pos += stream.Read(buf, 0, buf.Length);
99-
//FakeSeekForward(stream, (int)size);
100-
}
101135
}
102136

103-
var offset = (int)(512 - (pos % 512));
137+
//Move head to next 512 byte block
138+
var pos = stream.Position;
139+
var offset = 512 - (pos % 512);
104140
if (offset == 512) offset = 0;
105-
FakeSeekForward(stream, offset);
106-
pos += offset;
107-
}
108-
}
109141

110-
private static void FakeSeekForward(Stream stream, int offset)
111-
{
112-
if (stream.CanSeek)
113142
stream.Seek(offset, SeekOrigin.Current);
114-
else
115-
{
116-
int bytesRead = 0;
117-
var buffer = new byte[offset];
118-
while (bytesRead < offset)
119-
{
120-
int read = stream.Read(buffer, bytesRead, offset - bytesRead);
121-
if (read == 0)
122-
throw new EndOfStreamException();
123-
bytesRead += read;
124-
}
125143
}
126144
}
127-
}
128-
}
145+
} // class Tar
146+
} // namespace TarLib
147+
148+
149+
/*
150+
This software is available under 2 licenses-- choose whichever you prefer.
151+
------------------------------------------------------------------------------
152+
ALTERNATIVE A - MIT License
153+
Copyright (c) 2017 Sean Barrett
154+
Permission is hereby granted, free of charge, to any person obtaining a copy of
155+
this software and associated documentation files (the "Software"), to deal in
156+
the Software without restriction, including without limitation the rights to
157+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
158+
of the Software, and to permit persons to whom the Software is furnished to do
159+
so, subject to the following conditions:
160+
The above copyright notice and this permission notice shall be included in all
161+
copies or substantial portions of the Software.
162+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
163+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
164+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
165+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
166+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
167+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
168+
SOFTWARE.
169+
------------------------------------------------------------------------------
170+
ALTERNATIVE B - Public Domain (www.unlicense.org)
171+
This is free and unencumbered software released into the public domain.
172+
Anyone is free to copy, modify, publish, use, compile, sell, or distribute this
173+
software, either in source code form or as a compiled binary, for any purpose,
174+
commercial or non-commercial, and by any means.
175+
In jurisdictions that recognize copyright laws, the author or authors of this
176+
software dedicate any and all copyright interest in the software to the public
177+
domain.We make this dedication for the benefit of the public at large and to
178+
the detriment of our heirs and successors. We intend this dedication to be an
179+
overt act of relinquishment in perpetuity of all present and future rights to
180+
this software under copyright law.
181+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
182+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
183+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
184+
AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
185+
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
186+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
187+
*/

Diff for: UnityLauncherPro/Tools.cs

+9-9
Original file line numberDiff line numberDiff line change
@@ -620,7 +620,7 @@ public static void DownloadInBrowser(string url, string version, bool preferFull
620620
{
621621
string exeURL = ParseDownloadURLFromWebpage(version, preferFullInstaller, useHash);
622622

623-
Console.WriteLine("download exeURL= (" + exeURL + ")");
623+
//Console.WriteLine("DownloadInBrowser exeURL= '" + exeURL + "'");
624624

625625
if (string.IsNullOrEmpty(exeURL) == false && exeURL.StartsWith("https") == true)
626626
{
@@ -834,9 +834,10 @@ public static string ParseDownloadURLFromWebpage(string version, bool preferFull
834834

835835
//Console.WriteLine(url);
836836

837+
837838
version = FetchUnityVersionNumberFromHTML(url);
838839
//Console.WriteLine(url);
839-
//Console.WriteLine(version);
840+
//Console.WriteLine("got "+version);
840841
if (string.IsNullOrEmpty(version))
841842
{
842843
SetStatus("Failed to get version (" + version + ") number from hash: " + hash);
@@ -849,7 +850,7 @@ public static string ParseDownloadURLFromWebpage(string version, bool preferFull
849850
string[] lines = sourceHTML.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None);
850851

851852
// patch version download assistant finder
852-
if (VersionIsPatch(version))
853+
if (useHash==false && VersionIsPatch(version))
853854
{
854855
for (int i = 0; i < lines.Length; i++)
855856
{
@@ -862,7 +863,7 @@ public static string ParseDownloadURLFromWebpage(string version, bool preferFull
862863
}
863864
}
864865
}
865-
else if (VersionIsArchived(version))
866+
else if (useHash == false && VersionIsArchived(version))
866867
{
867868
// archived version download assistant finder
868869
for (int i = 0; i < lines.Length; i++)
@@ -911,15 +912,15 @@ public static string ParseDownloadURLFromWebpage(string version, bool preferFull
911912
}
912913
else // hidden download page
913914
{
914-
string pattern = @"UnityDownloadAssistant(?:-\d+\.\d+\.\d+b\d+)?\.exe";
915+
string pattern = @"UnityDownloadAssistant(?:-\d+\.\d+\.\d+[bf]\d*)?\.exe";
915916
Match match = Regex.Match(lines[i], pattern);
916917
if (match.Success)
917918
{
918919
// append base url
919920
Regex regex = new Regex(@"(https://beta\.unity3d\.com/download/[a-zA-Z0-9]+/)");
920921
Match match2 = regex.Match(url);
921922

922-
Console.WriteLine("source urö: " + url);
923+
//Console.WriteLine("source url: " + url);
923924

924925
if (match2.Success)
925926
{
@@ -938,7 +939,7 @@ public static string ParseDownloadURLFromWebpage(string version, bool preferFull
938939
} // alpha or beta
939940

940941
// download full installer instead
941-
if (preferFullInstaller)
942+
if (useHash == false && preferFullInstaller)
942943
{
943944
exeURL = exeURL.Replace("UnityDownloadAssistant-" + version + ".exe", "Windows64EditorInstaller/UnitySetup64-" + version + ".exe");
944945
// handle alpha/beta
@@ -962,8 +963,7 @@ private static string FetchUnityVersionNumberFromHTML(string url)
962963

963964
if (string.IsNullOrEmpty(sourceHTML)) return null;
964965

965-
string pattern = @"\d+\.\d+\.\d+b\d+";
966-
966+
string pattern = @"\d+\.\d+\.\d+[bf]\d+";
967967
MatchCollection matches = Regex.Matches(sourceHTML, pattern);
968968
if (matches.Count > 0)
969969
{

0 commit comments

Comments
 (0)