@@ -604,9 +604,9 @@ public static void OpenURL(string url)
604604 Process . Start ( url ) ;
605605 }
606606
607- public static void DownloadInBrowser ( string url , string version , bool preferFullInstaller = false )
607+ public static void DownloadInBrowser ( string url , string version , bool preferFullInstaller = false , bool useHash = false )
608608 {
609- string exeURL = ParseDownloadURLFromWebpage ( version , preferFullInstaller ) ;
609+ string exeURL = ParseDownloadURLFromWebpage ( version , preferFullInstaller , useHash ) ;
610610
611611 Console . WriteLine ( "download exeURL= (" + exeURL + ")" ) ;
612612
@@ -777,107 +777,208 @@ static bool DownloadFile(string url, string tempFile)
777777 return result ;
778778 }
779779
780+ public static string DownloadHTML ( string url )
781+ {
782+ if ( string . IsNullOrEmpty ( url ) == true ) return null ;
783+ using ( WebClient client = new WebClient ( ) )
784+ {
785+ try
786+ {
787+ // download page html
788+ return client . DownloadString ( url ) ;
789+ }
790+ catch ( WebException e )
791+ {
792+ Console . WriteLine ( "DownloadHTML: " + e . Message ) ;
793+ return null ;
794+ }
795+ }
796+ }
797+
780798 // parse Unity installer exe from release page
781799 // thanks to https://github.com/softfruit
782- public static string ParseDownloadURLFromWebpage ( string version , bool preferFullInstaller = false )
800+ public static string ParseDownloadURLFromWebpage ( string version , bool preferFullInstaller = false , bool useHash = false )
783801 {
784- string url = "" ;
802+ string exeURL = "" ;
785803
786804 if ( string . IsNullOrEmpty ( version ) ) return null ;
787805
788- using ( WebClient client = new WebClient ( ) )
806+ string url = null ;
807+ if ( useHash == false )
789808 {
790809 // get correct page url
791- string website = "https://unity3d.com/get-unity/download/archive" ;
792- if ( VersionIsPatch ( version ) ) website = "https://unity3d.com/unity/qa/patch-releases" ;
793- if ( VersionIsBeta ( version ) ) website = "https://unity.com/releases/editor/beta/" + version ;
794- if ( VersionIsAlpha ( version ) ) website = "https://unity.com/releases/editor/alpha/" + version ;
795-
810+ url = "https://unity3d.com/get-unity/download/archive" ;
811+ if ( VersionIsPatch ( version ) ) url = "https://unity3d.com/unity/qa/patch-releases" ;
812+ if ( VersionIsBeta ( version ) ) url = "https://unity.com/releases/editor/beta/" + version ;
813+ if ( VersionIsAlpha ( version ) ) url = "https://unity.com/releases/editor/alpha/" + version ;
796814 // fix unity server problem, some pages says 404 found if no url params
797- website += "?unitylauncherpro" ;
815+ url += "?unitylauncherpro" ;
816+ }
817+ else
818+ {
819+ // TODO version here is actually HASH
820+ url = $ "https://beta.unity3d.com/download/{ version } /download.html";
798821
799- string sourceHTML = null ;
800- // need to catch 404 error
801- try
802- {
803- // download page html
804- sourceHTML = client . DownloadString ( website ) ;
805- }
806- catch ( WebException e )
822+ //Console.WriteLine(url);
823+
824+ version = FetchUnityVersionNumberFromHTML ( url ) ;
825+ //Console.WriteLine(url);
826+ //Console.WriteLine(version);
827+ if ( string . IsNullOrEmpty ( version ) )
807828 {
808- Console . WriteLine ( e . Message ) ;
829+ Console . WriteLine ( "Failed to get version number from hash: " + version ) ;
809830 return null ;
810831 }
832+ }
811833
812- string [ ] lines = sourceHTML . Split ( new [ ] { " \r \n " , " \r " , " \n " } , StringSplitOptions . None ) ;
834+ string sourceHTML = DownloadHTML ( url ) ;
813835
814- // patch version download assistant finder
815- if ( VersionIsPatch ( version ) )
836+ string [ ] lines = sourceHTML . Split ( new [ ] { "\r \n " , "\r " , "\n " } , StringSplitOptions . None ) ;
837+
838+ // patch version download assistant finder
839+ if ( VersionIsPatch ( version ) )
840+ {
841+ for ( int i = 0 ; i < lines . Length ; i ++ )
816842 {
817- for ( int i = 0 ; i < lines . Length ; i ++ )
843+ if ( lines [ i ] . Contains ( "UnityDownloadAssistant-" + version + ".exe" ) )
818844 {
819- if ( lines [ i ] . Contains ( "UnityDownloadAssistant-" + version + ".exe" ) )
820- {
821- int start = lines [ i ] . IndexOf ( '"' ) + 1 ;
822- int end = lines [ i ] . IndexOf ( '"' , start ) ;
823- url = lines [ i ] . Substring ( start , end - start ) ;
824- break ;
825- }
845+ int start = lines [ i ] . IndexOf ( '"' ) + 1 ;
846+ int end = lines [ i ] . IndexOf ( '"' , start ) ;
847+ exeURL = lines [ i ] . Substring ( start , end - start ) ;
848+ break ;
826849 }
827850 }
828- else if ( VersionIsArchived ( version ) )
851+ }
852+ else if ( VersionIsArchived ( version ) )
853+ {
854+ // archived version download assistant finder
855+ for ( int i = 0 ; i < lines . Length ; i ++ )
829856 {
830- // archived version download assistant finder
831- for ( int i = 0 ; i < lines . Length ; i ++ )
857+ // find line where full installer is (from archive page)
858+ if ( lines [ i ] . Contains ( "UnitySetup64-" + version ) )
832859 {
833- // find line where full installer is (from archive page)
834- if ( lines [ i ] . Contains ( "UnitySetup64-" + version ) )
835- {
836- // take full exe installer line, to have changeset hash, then replace with download assistant filepath
837- string line = lines [ i ] ;
838- int start = line . IndexOf ( '"' ) + 1 ;
839- int end = line . IndexOf ( '"' , start ) ;
840- url = line . Substring ( start , end - start ) ;
841- url = url . Replace ( "Windows64EditorInstaller/UnitySetup64-" , "UnityDownloadAssistant-" ) ;
842- break ;
843- }
860+ // take full exe installer line, to have changeset hash, then replace with download assistant filepath
861+ string line = lines [ i ] ;
862+ int start = line . IndexOf ( '"' ) + 1 ;
863+ int end = line . IndexOf ( '"' , start ) ;
864+ exeURL = line . Substring ( start , end - start ) ;
865+ exeURL = exeURL . Replace ( "Windows64EditorInstaller/UnitySetup64-" , "UnityDownloadAssistant-" ) ;
866+ break ;
844867 }
845868 }
846- else // alpha or beta version download assistant finder
869+ }
870+ else // alpha or beta version download assistant finder
871+ {
872+ // regular beta
873+ // <a href="https://beta.unity3d.com/download/21aeb48b6ed2/UnityDownloadAssistant.exe">
874+ // https://beta.unity3d.com/download/21aeb48b6ed2/UnityDownloadAssistant.exe
875+
876+ // hidden beta
877+ // <a href='UnityDownloadAssistant-6000.0.0b15.exe'>
878+ // https://beta.unity3d.com/download/8008bc0c1b74/UnityDownloadAssistant-6000.0.0b15.exe
879+
880+ // check html lines
881+ for ( int i = 0 ; i < lines . Length ; i ++ )
847882 {
848- for ( int i = 0 ; i < lines . Length ; i ++ )
883+ //Console.WriteLine(lines[i]);
884+ if ( lines [ i ] . Contains ( "UnityDownloadAssistant" ) )
849885 {
850- if ( lines [ i ] . Contains ( "UnityDownloadAssistant.exe" ) )
886+ if ( useHash == false )
851887 {
852- // parse download url from this html line
853888 string pattern = @"https://beta\.unity3d\.com/download/[a-zA-Z0-9]+/UnityDownloadAssistant\.exe" ;
854889 Match match = Regex . Match ( lines [ i ] , pattern ) ;
855890 if ( match . Success )
856891 {
857- url = match . Value ;
858- //Console.WriteLine("url= " + url);
892+ exeURL = match . Value ;
893+ }
894+ else
895+ {
896+ Console . WriteLine ( "No match found for download base url.." ) ;
897+ }
898+ }
899+ else // hidden download page
900+ {
901+ string pattern = @"UnityDownloadAssistant(?:-\d+\.\d+\.\d+b\d+)?\.exe" ;
902+ Match match = Regex . Match ( lines [ i ] , pattern ) ;
903+ if ( match . Success )
904+ {
905+ // append base url
906+ Regex regex = new Regex ( @"(https://beta\.unity3d\.com/download/[a-zA-Z0-9]+/)" ) ;
907+ Match match2 = regex . Match ( url ) ;
908+
909+ Console . WriteLine ( "source urö: " + url ) ;
910+
911+ if ( match2 . Success )
912+ {
913+ string capturedUrl = match2 . Groups [ 1 ] . Value ;
914+ exeURL = capturedUrl + match . Value ;
915+ }
916+ else
917+ {
918+ Console . WriteLine ( "No match found for download base url.." ) ;
919+ }
859920 }
860921 break ;
861922 }
862923 }
863- }
864- }
924+ } // for lines
925+ } // alpha or beta
865926
866927 // download full installer instead
867928 if ( preferFullInstaller )
868929 {
869- url = url . Replace ( "UnityDownloadAssistant-" + version + ".exe" , "Windows64EditorInstaller/UnitySetup64-" + version + ".exe" ) ;
930+ exeURL = exeURL . Replace ( "UnityDownloadAssistant-" + version + ".exe" , "Windows64EditorInstaller/UnitySetup64-" + version + ".exe" ) ;
870931 // handle alpha/beta
871- url = url . Replace ( "UnityDownloadAssistant.exe" , "Windows64EditorInstaller/UnitySetup64-" + version + ".exe" ) ;
932+ exeURL = exeURL . Replace ( "UnityDownloadAssistant.exe" , "Windows64EditorInstaller/UnitySetup64-" + version + ".exe" ) ;
872933 }
873934
874935 // didnt find installer
875- if ( string . IsNullOrEmpty ( url ) )
936+ if ( string . IsNullOrEmpty ( exeURL ) )
876937 {
877938 //SetStatus("Cannot find UnityDownloadAssistant.exe for this version.");
878- Console . WriteLine ( "Installer not found from URL.." ) ;
939+ Console . WriteLine ( "Installer not found from URL: " + url ) ;
879940 }
880- return url ;
941+ return exeURL ;
942+ }
943+
944+ private static string FetchUnityVersionNumberFromHTML ( string url )
945+ {
946+ string version = null ;
947+
948+ string sourceHTML = DownloadHTML ( url ) ;
949+
950+ if ( string . IsNullOrEmpty ( sourceHTML ) ) return null ;
951+
952+ string pattern = @"\d+\.\d+\.\d+b\d+" ;
953+
954+ MatchCollection matches = Regex . Matches ( sourceHTML , pattern ) ;
955+ if ( matches . Count > 0 )
956+ {
957+ foreach ( Match match in matches )
958+ {
959+ Console . WriteLine ( "Extracted number: " + match . Value ) ;
960+ return match . Value ;
961+ break ;
962+ }
963+ }
964+ else
965+ {
966+ Console . WriteLine ( "No match found." ) ;
967+ }
968+
969+ return null ;
970+
971+ //if (string.IsNullOrEmpty(sourceHTML) == false)
972+ //{
973+ // // find version number from html
974+ // string pattern = @"UnityDownloadAssistant-[0-9]+\.[0-9]+\.[0-9]+[a-z]?\.exe";
975+ // Match match = Regex.Match(sourceHTML, pattern);
976+ // if (match.Success)
977+ // {
978+ // version = match.Value.Replace("UnityDownloadAssistant-", "").Replace(".exe", "");
979+ // }
980+ //}
981+ return version ;
881982 }
882983
883984 public static string FindNearestVersion ( string currentVersion , List < string > allAvailable )
0 commit comments