Skip to content

Commit a870bb8

Browse files
committed
adding unofficial releases watchlist downloads
1 parent b8d1f1d commit a870bb8

File tree

3 files changed

+320
-6
lines changed

3 files changed

+320
-6
lines changed

UnityLauncherPro/Data/UnityVersion.cs

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ public class UnityVersion
88
public string Version { get; set; }
99
public UnityVersionStream Stream { get; set; }
1010
public DateTime ReleaseDate { get; set; }
11+
public string directURL { get; set; } = null; // if found from unofficial releases list
1112

1213
public static UnityVersion FromJson(string json)
1314
{

UnityLauncherPro/GetUnityUpdates.cs

+125-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,30 @@ public static class GetUnityUpdates
1717
private const string CacheFileName = "UnityVersionCache.json";
1818
private static readonly HttpClient Client = new HttpClient();
1919

20+
static Dictionary<string, string> unofficialReleaseURLs = new Dictionary<string, string>();
21+
2022
public static async Task<List<UnityVersion>> FetchAll()
2123
{
2224
var cachedVersions = LoadCachedVersions();
2325
var newVersions = await FetchNewVersions(cachedVersions);
2426

25-
var allVersions = newVersions.Concat(cachedVersions).ToList();
27+
var unofficialVersions = await FetchUnofficialVersions(cachedVersions);
28+
29+
unofficialReleaseURLs.Clear();
30+
// TODO modify FetchUnofficialVersions to put items in this dictionary directly
31+
foreach (var version in unofficialVersions)
32+
{
33+
//Console.WriteLine("unofficial: " + version.Version + " , " + version.directURL);
34+
if (unofficialReleaseURLs.ContainsKey(version.Version) == false)
35+
{
36+
unofficialReleaseURLs.Add(version.Version, version.directURL);
37+
}
38+
}
39+
40+
var allVersions = newVersions.Concat(unofficialVersions).Concat(cachedVersions).ToList();
41+
//var allVersions = newVersions.Concat(cachedVersions).ToList();
2642

43+
// TODO save unofficial versions to cache also? or maybe not, they will appear in official list later
2744
if (newVersions.Count > 0)
2845
{
2946
SaveCachedVersions(allVersions);
@@ -32,13 +49,89 @@ public static async Task<List<UnityVersion>> FetchAll()
3249
return allVersions;
3350
}
3451

52+
public static async Task<List<UnityVersion>> FetchUnofficialVersions(List<UnityVersion> cachedVersions)
53+
{
54+
var unofficialVersions = new List<UnityVersion>();
55+
var existingVersions = new HashSet<string>(cachedVersions.Select(v => v.Version));
56+
57+
try
58+
{
59+
string url = "https://raw.githubusercontent.com/unitycoder/UnofficialUnityReleasesWatcher/refs/heads/main/unity-releases.md";
60+
61+
var content = await Client.GetStringAsync(url);
62+
63+
// Parse the Markdown content
64+
var lines = content.Split(new[] { '\n', '\r' }, StringSplitOptions.RemoveEmptyEntries);
65+
foreach (var line in lines)
66+
{
67+
if (line.StartsWith("- ")) // Identify Markdown list items
68+
{
69+
var urlPart = line.Substring(2).Trim();
70+
var version = ExtractVersionFromUrl(urlPart);
71+
72+
if (!string.IsNullOrEmpty(version) && !existingVersions.Contains(version))
73+
{
74+
var stream = InferStreamFromVersion(version);
75+
76+
unofficialVersions.Add(new UnityVersion
77+
{
78+
Version = version,
79+
Stream = stream,
80+
ReleaseDate = DateTime.Now, // NOTE not correct, but we don't have known release date for unofficial versions (its only when they are found..)
81+
//ReleaseDate = DateTime.MinValue // Release date is unavailable in the MD format, TODO add to md as #2021-01-01 ?
82+
directURL = urlPart, // this is available only for unofficial releases
83+
});
84+
}
85+
}
86+
}
87+
}
88+
catch (Exception ex)
89+
{
90+
Console.WriteLine($"Error fetching unofficial versions: {ex.Message}");
91+
}
92+
93+
return unofficialVersions;
94+
}
95+
96+
// TODO fixme, f is not always LTS
97+
private static UnityVersionStream InferStreamFromVersion(string version)
98+
{
99+
if (Tools.IsAlpha(version)) return UnityVersionStream.Alpha;
100+
if (Tools.IsBeta(version)) return UnityVersionStream.Beta;
101+
if (Tools.IsLTS(version)) return UnityVersionStream.LTS;
102+
103+
//if (version.Contains("a")) return UnityVersionStream.Alpha;
104+
//if (version.Contains("b")) return UnityVersionStream.Beta;
105+
//if (version.Contains("f")) return UnityVersionStream.LTS;
106+
return UnityVersionStream.Tech; // Default to Tech if no identifier is found
107+
}
108+
109+
/// <summary>
110+
/// Extracts the Unity version from the given URL.
111+
/// </summary>
112+
/// <param name="url">The URL to parse.</param>
113+
/// <returns>The Unity version string.</returns>
114+
private static string ExtractVersionFromUrl(string url)
115+
{
116+
try
117+
{
118+
var versionStart = url.LastIndexOf('#') + 1;
119+
return versionStart > 0 && versionStart < url.Length ? url.Substring(versionStart) : null;
120+
}
121+
catch
122+
{
123+
return null;
124+
}
125+
}
126+
35127
public static async Task<string> FetchDownloadUrl(string unityVersion)
36128
{
37129
if (string.IsNullOrEmpty(unityVersion))
38130
{
39131
return null;
40132
}
41133

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

44137
try
@@ -53,8 +146,37 @@ public static async Task<string> FetchDownloadUrl(string unityVersion)
53146
}
54147
}
55148

149+
static string ParseHashCodeFromURL(string url)
150+
{
151+
// https://beta.unity3d.com/download/330fbefc18b7/download.html#6000.1.0a8 > 330fbefc18b7
152+
153+
int hashStart = url.IndexOf("download/") + 9;
154+
int hashEnd = url.IndexOf("/download.html", hashStart);
155+
return url.Substring(hashStart, hashEnd - hashStart);
156+
}
157+
56158
private static async Task<string> ExtractDownloadUrlAsync(string json, string unityVersion)
57159
{
160+
//Console.WriteLine("json: " + json + " vers: " + unityVersion);
161+
162+
if (json.Contains("\"results\":[]"))
163+
{
164+
Console.WriteLine("No results found from releases API, checking unofficial list (if enabled)");
165+
166+
if (unofficialReleaseURLs.ContainsKey(unityVersion))
167+
{
168+
Console.WriteLine("Unofficial release found in the list.");
169+
170+
string unityHash = ParseHashCodeFromURL(unofficialReleaseURLs[unityVersion]);
171+
// Console.WriteLine(unityHash);
172+
string downloadURL = Tools.ParseDownloadURLFromWebpage(unityVersion, unityHash, false, true);
173+
// Console.WriteLine("direct download url: "+downloadURL);
174+
return downloadURL;
175+
}
176+
177+
return null;
178+
}
179+
58180
int resultsIndex = json.IndexOf("\"results\":");
59181
if (resultsIndex == -1) return null;
60182

@@ -84,7 +206,7 @@ private static async Task<string> ExtractDownloadUrlAsync(string json, string un
84206

85207
if (await CheckAssistantUrl(assistantUrl))
86208
{
87-
Console.WriteLine("Assistant download URL found.");
209+
//Console.WriteLine("ExtractDownloadUrlAsync: Assistant download URL found.");
88210
return assistantUrl;
89211
}
90212
else
@@ -279,6 +401,7 @@ private static void SaveCachedVersions(List<UnityVersion> versions)
279401
if (configDirectory == null) return;
280402

281403
string cacheFilePath = Path.Combine(configDirectory, CacheFileName);
404+
//Console.WriteLine("Saving cachedrelease: " + cacheFilePath);
282405
File.WriteAllText(cacheFilePath, json);
283406
}
284407
}

0 commit comments

Comments
 (0)