Skip to content

Commit 600fd17

Browse files
committed
testing vulnerability warning fetch
1 parent 1a7c177 commit 600fd17

File tree

7 files changed

+227
-4
lines changed

7 files changed

+227
-4
lines changed

UnityLauncherPro/Data/UnityInstallation.cs

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,12 +15,33 @@ public class UnityInstallation : IValueConverter
1515
public bool IsPreferred { set; get; }
1616
public string ReleaseType { set; get; } // Alpha, Beta, LTS.. TODO could be enum
1717

18+
public string InfoLabel { set; get; } // this is additional info from Releases API (like vulnerabilities..)
19+
1820
// https://stackoverflow.com/a/5551986/5452781
1921
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
2022
{
2123
string version = value as string;
2224
if (string.IsNullOrEmpty(version)) return null;
23-
return MainWindow.unityInstalledVersions.ContainsKey(version);
25+
26+
bool checkInfoLabel = true;
27+
28+
if (MainWindow.unityInstalledVersions.ContainsKey(version))
29+
{
30+
//Console.WriteLine("checking version: "+version);
31+
if (checkInfoLabel && string.IsNullOrEmpty(InfoLabel) == false)
32+
{
33+
Console.WriteLine("Contains warning: "+version);
34+
return -1; // has warning
35+
}
36+
else
37+
{
38+
return 1; // normal
39+
}
40+
}
41+
else
42+
{
43+
return 0; // not installed
44+
}
2445
}
2546

2647
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

UnityLauncherPro/GetUnityInstallations.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ public static class GetUnityInstallations
1111
{
1212
static Dictionary<string, string> platformNames = new Dictionary<string, string> { { "androidplayer", "Android" }, { "windowsstandalonesupport", "Win" }, { "linuxstandalonesupport", "Linux" }, { "LinuxStandalone", "Linux" }, { "OSXStandalone", "OSX" }, { "webglsupport", "WebGL" }, { "metrosupport", "UWP" }, { "iossupport", "iOS" } };
1313

14-
1514
// returns unity installations
1615
public static List<UnityInstallation> Scan()
1716
{
@@ -65,6 +64,9 @@ public static List<UnityInstallation> Scan()
6564
unity.IsPreferred = (version == MainWindow.preferredVersion);
6665
unity.ProjectCount = GetProjectCountForUnityVersion(version);
6766

67+
// TODO here need to check for vulnerabilities from CACHED data, BUT if its cached, then it might be old
68+
unity.InfoLabel = null;
69+
6870
if (Tools.IsAlpha(version))
6971
{
7072
unity.ReleaseType = "Alpha";

UnityLauncherPro/MainWindow.xaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,15 @@
117117
<DataGridTextColumn.CellStyle>
118118
<Style TargetType="{x:Type DataGridCell}">
119119
<Setter Property="Foreground" Value="{DynamicResource ThemeGridRedText}" />
120+
<Setter Property="BorderBrush" Value="{x:Null}" />
120121
<Style.Triggers>
121-
<DataTrigger Binding="{Binding Version, Converter={StaticResource VersionInstalledConverter}}" Value="true">
122+
<DataTrigger Binding="{Binding Version, Converter={StaticResource VersionInstalledConverter}}" Value="1">
123+
<Setter Property="Foreground" Value="{DynamicResource ThemeGridGreenText}" />
124+
<Setter Property="BorderBrush" Value="{x:Null}" />
125+
</DataTrigger>
126+
<DataTrigger Binding="{Binding Version, Converter={StaticResource VersionInstalledConverter}}" Value="-1">
122127
<Setter Property="Foreground" Value="{DynamicResource ThemeGridGreenText}" />
128+
<Setter Property="BorderBrush" Value="Orange" />
123129
</DataTrigger>
124130
</Style.Triggers>
125131
</Style>
@@ -845,6 +851,7 @@
845851
<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"/>
846852
<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"/>
847853
<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"/>
854+
<CheckBox x:Name="chkFetchAdditionalInfo" Content="Fetch additional info about Editor" ToolTip="Reads releases API for security related info" Checked="chkFetchAdditionalInfo_Checked" Unchecked="chkFetchAdditionalInfo_Checked"/>
848855
<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"/>
849856
<!--<StackPanel Orientation="Horizontal" Margin="0,0,0,4">
850857
<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" />

UnityLauncherPro/MainWindow.xaml.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -198,6 +198,8 @@ void Start()
198198

199199
CheckCustomIcon();
200200

201+
if (chkFetchAdditionalInfo.IsChecked == true) Tools.FetchAdditionalInfoForEditors();
202+
201203
isInitializing = false;
202204
} // Start()
203205

@@ -543,6 +545,7 @@ void LoadSettings()
543545
useAlphaReleaseNotesSite.IsChecked = Settings.Default.useAlphaReleaseNotes;
544546
useUnofficialReleaseList.IsChecked = Settings.Default.useUnofficialReleaseList;
545547
chkDisableUnityHubLaunch.IsChecked = Settings.Default.disableUnityHubLaunch;
548+
chkFetchAdditionalInfo.IsChecked = Settings.Default.fetchAdditionalInfo;
546549

547550
chkEnablePlatformSelection.IsChecked = Settings.Default.enablePlatformSelection;
548551
chkRunAutomatically.IsChecked = Settings.Default.runAutomatically;
@@ -1332,6 +1335,7 @@ private void GridRecent_Loaded(object sender, RoutedEventArgs e)
13321335
RefreshSorting();
13331336
//Tools.SetFocusToGrid(gridRecent);
13341337
Dispatcher.InvokeAsync(() => Tools.SetFocusToGrid(gridRecent), DispatcherPriority.ApplicationIdle);
1338+
13351339
}
13361340

13371341
void RefreshSorting()
@@ -4113,6 +4117,14 @@ private void btnPurgeMissingFolders_Click(object sender, RoutedEventArgs e)
41134117
SetStatus("Purged " + removedCount + " items", MessageType.Info);
41144118
}
41154119

4120+
private void chkFetchAdditionalInfo_Checked(object sender, RoutedEventArgs e)
4121+
{
4122+
if (this.IsActive == false) return; // dont run code on window init
4123+
4124+
Settings.Default.fetchAdditionalInfo = (bool)chkFetchAdditionalInfo.IsChecked;
4125+
Settings.Default.Save();
4126+
}
4127+
41164128
//private void menuProjectProperties_Click(object sender, RoutedEventArgs e)
41174129
//{
41184130
// var proj = GetSelectedProject();

UnityLauncherPro/Properties/Settings.Designer.cs

Lines changed: 13 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

UnityLauncherPro/Properties/Settings.settings

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,5 +157,8 @@
157157
<Setting Name="registerExplorerMenuAPK" Type="System.Boolean" Scope="User">
158158
<Value Profile="(Default)">False</Value>
159159
</Setting>
160+
<Setting Name="fetchAdditionalInfo" Type="System.Boolean" Scope="User">
161+
<Value Profile="(Default)">False</Value>
162+
</Setting>
160163
</Settings>
161164
</SettingsFile>

UnityLauncherPro/Tools.cs

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2901,6 +2901,172 @@ public static void CopyDirectory(string sourceDir, string targetDir)
29012901
}
29022902
}
29032903

2904+
2905+
2906+
// test fetching
2907+
2908+
// Reuse a single HttpClient
2909+
private static readonly HttpClient _http = new HttpClient
2910+
{
2911+
Timeout = TimeSpan.FromSeconds(15)
2912+
};
2913+
2914+
/// <summary>
2915+
/// Fire-and-forget entry; returns immediately. Keeps your UI thread free.
2916+
/// </summary>
2917+
internal static void FetchAdditionalInfoForEditors()
2918+
{
2919+
_ = FetchImplAsync(); // don't await -> no UI hang
2920+
}
2921+
2922+
private static async Task FetchImplAsync()
2923+
{
2924+
try
2925+
{
2926+
foreach (var version in MainWindow.unityInstalledVersions.Keys)
2927+
{
2928+
Console.WriteLine("******** Fetching " + version);
2929+
2930+
var url = $"https://services.api.unity.com/unity/editor/release/v1/releases?order=RELEASE_DATE_DESC&limit=1&version={Uri.EscapeDataString(version)}";
2931+
2932+
string json;
2933+
try
2934+
{
2935+
json = await _http.GetStringAsync(url).ConfigureAwait(false);
2936+
}
2937+
catch (Exception ex)
2938+
{
2939+
Debug.WriteLine($"[FetchAdditionalInfo] {version}: HTTP error: {ex.Message}");
2940+
continue;
2941+
}
2942+
2943+
try
2944+
{
2945+
//Console.WriteLine("received: " + json);
2946+
UnityEditorInfoLabel label = ExtractLabelText(json);
2947+
if (label != null)
2948+
{
2949+
2950+
// feed this info back to main window
2951+
if (string.IsNullOrEmpty(label.labelText) == false)
2952+
{
2953+
//Console.WriteLine(label.description);
2954+
2955+
var u = MainWindow.unityInstallationsSource.FirstOrDefault(x => x.Version == version);
2956+
u.InfoLabel = label.labelText;
2957+
// replace old item in list
2958+
2959+
int index = MainWindow.unityInstallationsSource.IndexOf(u);
2960+
if (index >= 0)
2961+
{
2962+
MainWindow.unityInstallationsSource[index] = u;
2963+
}
2964+
2965+
SetStatus($"Info for {version}: {label.labelText}");
2966+
Console.WriteLine("got infolabel for "+version);
2967+
}
2968+
}
2969+
2970+
}
2971+
catch (Exception ex)
2972+
{
2973+
Debug.WriteLine($"[FetchAdditionalInfo] {version}: JSON parse error: {ex.Message}");
2974+
}
2975+
2976+
// delay
2977+
await Task.Delay(5000).ConfigureAwait(false);
2978+
2979+
} // foreach version
2980+
}
2981+
catch (Exception ex)
2982+
{
2983+
// Last-resort catch so fire-and-forget exceptions aren’t unobserved
2984+
Debug.WriteLine($"[FetchAdditionalInfo] Fatal: {ex}");
2985+
}
2986+
} // FetchImplAsync()
2987+
2988+
public class UnityEditorInfoLabel
2989+
{
2990+
public string description; // may contain HTML
2991+
public string labelText;
2992+
public string icon;
2993+
public string color;
2994+
}
2995+
2996+
private static UnityEditorInfoLabel ExtractLabelText(string json)
2997+
{
2998+
var label = new UnityEditorInfoLabel();
2999+
if (string.IsNullOrEmpty(json) || json.Contains("\"results\":[]")) return label;
3000+
3001+
int resultsIndex = json.IndexOf("\"results\":", StringComparison.Ordinal);
3002+
if (resultsIndex == -1) return label;
3003+
3004+
// Use the LAST "label": in the payload (the editor-level one)
3005+
int labelIndex = json.LastIndexOf("\"label\":", StringComparison.Ordinal);
3006+
if (labelIndex == -1 || labelIndex < resultsIndex) return label;
3007+
3008+
// labelText
3009+
int ltIndex = json.IndexOf("\"labelText\":", labelIndex, StringComparison.Ordinal);
3010+
if (ltIndex != -1)
3011+
{
3012+
int vStart = json.IndexOf('\"', ltIndex + 12) + 1; // "labelText": => +12
3013+
if (vStart > 0)
3014+
{
3015+
int vEnd = json.IndexOf('\"', vStart);
3016+
if (vEnd > vStart) label.labelText = json.Substring(vStart, vEnd - vStart);
3017+
}
3018+
}
3019+
3020+
// icon
3021+
int iconIndex = json.IndexOf("\"icon\":", labelIndex, StringComparison.Ordinal);
3022+
if (iconIndex != -1)
3023+
{
3024+
int vStart = json.IndexOf('\"', iconIndex + 7) + 1; // "icon": => +7
3025+
if (vStart > 0)
3026+
{
3027+
int vEnd = json.IndexOf('\"', vStart);
3028+
if (vEnd > vStart) label.icon = json.Substring(vStart, vEnd - vStart);
3029+
}
3030+
}
3031+
3032+
// color
3033+
int colorIndex = json.IndexOf("\"color\":", labelIndex, StringComparison.Ordinal);
3034+
if (colorIndex != -1)
3035+
{
3036+
int vStart = json.IndexOf('\"', colorIndex + 8) + 1; // "color": => +8
3037+
if (vStart > 0)
3038+
{
3039+
int vEnd = json.IndexOf('\"', vStart);
3040+
if (vEnd > vStart) label.color = json.Substring(vStart, vEnd - vStart);
3041+
}
3042+
}
3043+
3044+
// description (may contain escaped quotes)
3045+
int descIndex = json.IndexOf("\"description\":", labelIndex, StringComparison.Ordinal);
3046+
if (descIndex != -1)
3047+
{
3048+
int qStart = json.IndexOf('\"', descIndex + 14) + 1; // "description": => +14
3049+
if (qStart > 0)
3050+
{
3051+
int i = qStart;
3052+
for (; i < json.Length; i++)
3053+
if (json[i] == '\"' && json[i - 1] != '\\') break;
3054+
3055+
if (i > qStart)
3056+
label.description = json.Substring(qStart, i - qStart)
3057+
.Replace("\\\"", "\"")
3058+
.Replace("\\n", "\n")
3059+
.Replace("\\r", "\r")
3060+
.Replace("\\t", "\t");
3061+
}
3062+
}
3063+
3064+
return label;
3065+
}
3066+
3067+
3068+
3069+
29043070
} // class
29053071

29063072
} // namespace

0 commit comments

Comments
 (0)