Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
* dev:
  make upgrade window wider
  install apk: display error message if failed
  add disable unity hub from launching on Editor start #95
  add setting for using unoffical releases list
  adding unofficial releases watchlist downloads
  • Loading branch information
unitycoder committed Dec 20, 2024
2 parents b105fca + efb21fb commit 37ea41d
Show file tree
Hide file tree
Showing 8 changed files with 521 additions and 31 deletions.
1 change: 1 addition & 0 deletions UnityLauncherPro/Data/UnityVersion.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ public class UnityVersion
public string Version { get; set; }
public UnityVersionStream Stream { get; set; }
public DateTime ReleaseDate { get; set; }
public string directURL { get; set; } = null; // if found from unofficial releases list

public static UnityVersion FromJson(string json)
{
Expand Down
128 changes: 126 additions & 2 deletions UnityLauncherPro/GetUnityUpdates.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,31 @@ public static class GetUnityUpdates
private const string CacheFileName = "UnityVersionCache.json";
private static readonly HttpClient Client = new HttpClient();

public static async Task<List<UnityVersion>> FetchAll()
static Dictionary<string, string> unofficialReleaseURLs = new Dictionary<string, string>();

public static async Task<List<UnityVersion>> FetchAll(bool useUnofficialList = false)
{
var cachedVersions = LoadCachedVersions();
var newVersions = await FetchNewVersions(cachedVersions);

var allVersions = newVersions.Concat(cachedVersions).ToList();

if (useUnofficialList == true)
{
var unofficialVersions = await FetchUnofficialVersions(cachedVersions);
unofficialReleaseURLs.Clear();
// TODO modify FetchUnofficialVersions to put items in this dictionary directlys
foreach (var version in unofficialVersions)
{
//Console.WriteLine("unofficial: " + version.Version + " , " + version.directURL);
if (unofficialReleaseURLs.ContainsKey(version.Version) == false)
{
unofficialReleaseURLs.Add(version.Version, version.directURL);
}
}
allVersions = unofficialVersions.Concat(allVersions).ToList();
}

if (newVersions.Count > 0)
{
SaveCachedVersions(allVersions);
Expand All @@ -32,13 +50,89 @@ public static async Task<List<UnityVersion>> FetchAll()
return allVersions;
}

public static async Task<List<UnityVersion>> FetchUnofficialVersions(List<UnityVersion> cachedVersions)
{
var unofficialVersions = new List<UnityVersion>();
var existingVersions = new HashSet<string>(cachedVersions.Select(v => v.Version));

try
{
string url = "https://raw.githubusercontent.com/unitycoder/UnofficialUnityReleasesWatcher/refs/heads/main/unity-releases.md";

var content = await Client.GetStringAsync(url);

// Parse the Markdown content
var lines = content.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
foreach (var line in lines)
{
if (line.StartsWith("- ")) // Identify Markdown list items
{
var urlPart = line.Substring(2).Trim();
var version = ExtractVersionFromUrl(urlPart);

if (!string.IsNullOrEmpty(version) && !existingVersions.Contains(version))
{
var stream = InferStreamFromVersion(version);

unofficialVersions.Add(new UnityVersion
{
Version = version,
Stream = stream,
ReleaseDate = DateTime.Now, // NOTE not correct, but we don't have known release date for unofficial versions (its only when they are found..)
//ReleaseDate = DateTime.MinValue // Release date is unavailable in the MD format, TODO add to md as #2021-01-01 ?
directURL = urlPart, // this is available only for unofficial releases
});
}
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Error fetching unofficial versions: {ex.Message}");
}

return unofficialVersions;
}

// TODO fixme, f is not always LTS
private static UnityVersionStream InferStreamFromVersion(string version)
{
if (Tools.IsAlpha(version)) return UnityVersionStream.Alpha;
if (Tools.IsBeta(version)) return UnityVersionStream.Beta;
if (Tools.IsLTS(version)) return UnityVersionStream.LTS;

//if (version.Contains("a")) return UnityVersionStream.Alpha;
//if (version.Contains("b")) return UnityVersionStream.Beta;
//if (version.Contains("f")) return UnityVersionStream.LTS;
return UnityVersionStream.Tech; // Default to Tech if no identifier is found
}

/// <summary>
/// Extracts the Unity version from the given URL.
/// </summary>
/// <param name="url">The URL to parse.</param>
/// <returns>The Unity version string.</returns>
private static string ExtractVersionFromUrl(string url)
{
try
{
var versionStart = url.LastIndexOf('#') + 1;
return versionStart > 0 && versionStart < url.Length ? url.Substring(versionStart) : null;
}
catch
{
return null;
}
}

public static async Task<string> FetchDownloadUrl(string unityVersion)
{
if (string.IsNullOrEmpty(unityVersion))
{
return null;
}

// unity release api
string apiUrl = $"{BaseApiUrl}?limit=1&version={unityVersion}&architecture=X86_64&platform=WINDOWS";

try
Expand All @@ -53,8 +147,37 @@ public static async Task<string> FetchDownloadUrl(string unityVersion)
}
}

static string ParseHashCodeFromURL(string url)
{
// https://beta.unity3d.com/download/330fbefc18b7/download.html#6000.1.0a8 > 330fbefc18b7

int hashStart = url.IndexOf("download/") + 9;
int hashEnd = url.IndexOf("/download.html", hashStart);
return url.Substring(hashStart, hashEnd - hashStart);
}

private static async Task<string> ExtractDownloadUrlAsync(string json, string unityVersion)
{
//Console.WriteLine("json: " + json + " vers: " + unityVersion);

if (json.Contains("\"results\":[]"))
{
Console.WriteLine("No results found from releases API, checking unofficial list (if enabled)");

if (unofficialReleaseURLs.ContainsKey(unityVersion))
{
Console.WriteLine("Unofficial release found in the list.");

string unityHash = ParseHashCodeFromURL(unofficialReleaseURLs[unityVersion]);
// Console.WriteLine(unityHash);
string downloadURL = Tools.ParseDownloadURLFromWebpage(unityVersion, unityHash, false, true);
// Console.WriteLine("direct download url: "+downloadURL);
return downloadURL;
}

return null;
}

int resultsIndex = json.IndexOf("\"results\":");
if (resultsIndex == -1) return null;

Expand Down Expand Up @@ -84,7 +207,7 @@ private static async Task<string> ExtractDownloadUrlAsync(string json, string un

if (await CheckAssistantUrl(assistantUrl))
{
Console.WriteLine("Assistant download URL found.");
//Console.WriteLine("ExtractDownloadUrlAsync: Assistant download URL found.");
return assistantUrl;
}
else
Expand Down Expand Up @@ -279,6 +402,7 @@ private static void SaveCachedVersions(List<UnityVersion> versions)
if (configDirectory == null) return;

string cacheFilePath = Path.Combine(configDirectory, CacheFileName);
//Console.WriteLine("Saving cachedrelease: " + cacheFilePath);
File.WriteAllText(cacheFilePath, json);
}
}
Expand Down
2 changes: 2 additions & 0 deletions UnityLauncherPro/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,8 @@
<CheckBox x:Name="chkQuitAfterCommandline" Content="Close after launching from Explorer" Unchecked="ChkQuitAfterCommandline_CheckedChanged" Checked="ChkQuitAfterCommandline_CheckedChanged" ToolTip="Close launcher after running from commandline or Explorer (recommended)" HorizontalAlignment="Left"/>
<CheckBox x:Name="chkAllowSingleInstanceOnly" Content="Allow single instance only" Checked="ChkAllowSingleInstanceOnly_CheckedChanged" Unchecked="ChkAllowSingleInstanceOnly_CheckedChanged" ToolTip="Activates already running instance, instead of starting new exe (not working if app is minized to taskbar)" HorizontalAlignment="Left"/>
<CheckBox x:Name="useAlphaReleaseNotesSite" Content="Use Unity Alpha Release Notes Site (only for final versions) " ToolTip="Use the superior (but alpha) Unity Release Notes (https://alpha.release-notes.ds.unity3d.com/) site when clicking on the ReleaseNotes button. Otherwise will default to the normal build page." Checked="UseAlphaReleaseNotes_Checked" Unchecked="UseAlphaReleaseNotes_Checked"/>
<CheckBox x:Name="useUnofficialReleaseList" Content="Use Unofficial Release Watch List (for latest downloads)" ToolTip="Checks latest releases from https://github.com/unitycoder/UnofficialUnityReleasesWatcher (if not yet available in The Unity Releases API)" Checked="useUnofficialReleaseList_Checked" Unchecked="useUnofficialReleaseList_Checked"/>
<CheckBox x:Name="chkDisableUnityHubLaunch" Content="Disable UnityHub launch at Editor start" ToolTip="Overrides UnityHub IPC port. Note: You will be logged out in Editor!" Checked="chkDisableUnityHubLaunch_Checked" Unchecked="chkDisableUnityHubLaunch_Checked"/>
<CheckBox x:Name="chkStreamerMode" Content="Streamer Mode (hide project names and folders)" ToolTip="Hide project names and folders in main view" Checked="ChkStreamerMode_Checked" Unchecked="ChkStreamerMode_Checked" HorizontalAlignment="Left"/>
<!--<StackPanel Orientation="Horizontal" Margin="0,0,0,4">
<TextBox x:Name="txtTemplatePackagesFolder" BorderBrush="Transparent" CaretBrush="{DynamicResource ThemeSearchCaret}" Background="{DynamicResource ThemeTextBoxBackground}" SelectionBrush="{DynamicResource ThemeSearchSelection}" Foreground="{DynamicResource ThemeSearchForeground}" ToolTip="Folder for your custom unitypackage templates (for new project)" Padding="0,3,0,0" Width="110" TextChanged="TxtTemplatePackagesFolder_TextChanged" />
Expand Down
Loading

0 comments on commit 37ea41d

Please sign in to comment.