@@ -14,6 +14,7 @@ namespace MCPForUnity.Editor.Services
1414 /// </summary>
1515 public class PackageUpdateService : IPackageUpdateService
1616 {
17+ private const int DefaultRequestTimeoutMs = 3000 ;
1718 private const string LastCheckDateKey = EditorPrefKeys . LastUpdateCheck ;
1819 private const string CachedVersionKey = EditorPrefKeys . LatestKnownVersion ;
1920 private const string LastBetaCheckDateKey = EditorPrefKeys . LastUpdateCheck + ".beta" ;
@@ -81,6 +82,88 @@ public UpdateCheckResult CheckForUpdate(string currentVersion)
8182 } ;
8283 }
8384
85+ /// <inheritdoc/>
86+ public UpdateCheckResult ? TryGetCachedResult ( string currentVersion )
87+ {
88+ bool isGitInstallation = IsGitInstallation ( ) ;
89+ string gitBranch = isGitInstallation ? GetGitUpdateBranch ( currentVersion ) : "main" ;
90+ bool useBetaChannel = isGitInstallation && string . Equals ( gitBranch , "beta" , StringComparison . OrdinalIgnoreCase ) ;
91+
92+ string lastCheckKey = isGitInstallation
93+ ? ( useBetaChannel ? LastBetaCheckDateKey : LastCheckDateKey )
94+ : LastAssetStoreCheckDateKey ;
95+ string cachedVersionKey = isGitInstallation
96+ ? ( useBetaChannel ? CachedBetaVersionKey : CachedVersionKey )
97+ : CachedAssetStoreVersionKey ;
98+
99+ string lastCheckDate = EditorPrefs . GetString ( lastCheckKey , "" ) ;
100+ string cachedLatestVersion = EditorPrefs . GetString ( cachedVersionKey , "" ) ;
101+
102+ if ( lastCheckDate == DateTime . Now . ToString ( "yyyy-MM-dd" ) && ! string . IsNullOrEmpty ( cachedLatestVersion ) )
103+ {
104+ return new UpdateCheckResult
105+ {
106+ CheckSucceeded = true ,
107+ LatestVersion = cachedLatestVersion ,
108+ UpdateAvailable = IsNewerVersion ( cachedLatestVersion , currentVersion ) ,
109+ Message = "Using cached version check"
110+ } ;
111+ }
112+
113+ return null ;
114+ }
115+
116+ /// <inheritdoc/>
117+ public UpdateCheckResult FetchAndCompare ( string currentVersion )
118+ {
119+ bool isGitInstallation = IsGitInstallation ( ) ;
120+ string gitBranch = isGitInstallation ? GetGitUpdateBranch ( currentVersion ) : "main" ;
121+
122+ string latestVersion = isGitInstallation
123+ ? FetchLatestVersionFromGitHub ( gitBranch )
124+ : FetchLatestVersionFromAssetStoreJson ( ) ;
125+
126+ if ( ! string . IsNullOrEmpty ( latestVersion ) )
127+ {
128+ return new UpdateCheckResult
129+ {
130+ CheckSucceeded = true ,
131+ LatestVersion = latestVersion ,
132+ UpdateAvailable = IsNewerVersion ( latestVersion , currentVersion ) ,
133+ Message = "Successfully checked for updates"
134+ } ;
135+ }
136+
137+ return new UpdateCheckResult
138+ {
139+ CheckSucceeded = false ,
140+ UpdateAvailable = false ,
141+ Message = isGitInstallation
142+ ? "Failed to check for updates (network issue or offline)"
143+ : "Failed to check for Asset Store updates (network issue or offline)"
144+ } ;
145+ }
146+
147+ /// <inheritdoc/>
148+ public void CacheFetchResult ( string currentVersion , string fetchedVersion )
149+ {
150+ if ( string . IsNullOrEmpty ( fetchedVersion ) ) return ;
151+
152+ bool isGitInstallation = IsGitInstallation ( ) ;
153+ string gitBranch = isGitInstallation ? GetGitUpdateBranch ( currentVersion ) : "main" ;
154+ bool useBetaChannel = isGitInstallation && string . Equals ( gitBranch , "beta" , StringComparison . OrdinalIgnoreCase ) ;
155+
156+ string lastCheckKey = isGitInstallation
157+ ? ( useBetaChannel ? LastBetaCheckDateKey : LastCheckDateKey )
158+ : LastAssetStoreCheckDateKey ;
159+ string cachedVersionKey = isGitInstallation
160+ ? ( useBetaChannel ? CachedBetaVersionKey : CachedVersionKey )
161+ : CachedAssetStoreVersionKey ;
162+
163+ EditorPrefs . SetString ( lastCheckKey , DateTime . Now . ToString ( "yyyy-MM-dd" ) ) ;
164+ EditorPrefs . SetString ( cachedVersionKey , fetchedVersion ) ;
165+ }
166+
84167 /// <inheritdoc/>
85168 public bool IsNewerVersion ( string version1 , string version2 )
86169 {
@@ -265,7 +348,7 @@ protected virtual string FetchLatestVersionFromGitHub(string branch)
265348 // - More reliable - doesn't require releases to be published
266349 // - Direct source of truth from the main branch
267350
268- using ( var client = new WebClient ( ) )
351+ using ( var client = CreateWebClient ( ) )
269352 {
270353 client . Headers . Add ( "User-Agent" , "Unity-MCPForUnity-UpdateChecker" ) ;
271354 string packageJsonUrl = string . Equals ( branch , "beta" , StringComparison . OrdinalIgnoreCase )
@@ -304,7 +387,7 @@ protected virtual string FetchLatestVersionFromAssetStoreJson()
304387 {
305388 try
306389 {
307- using ( var client = new WebClient ( ) )
390+ using ( var client = CreateWebClient ( ) )
308391 {
309392 client . Headers . Add ( "User-Agent" , "Unity-MCPForUnity-AssetStoreUpdateChecker" ) ;
310393 string jsonContent = client . DownloadString ( AssetStoreVersionUrl ) ;
@@ -322,5 +405,41 @@ protected virtual string FetchLatestVersionFromAssetStoreJson()
322405 return null ;
323406 }
324407 }
408+
409+ protected virtual WebClient CreateWebClient ( )
410+ {
411+ return new TimeoutWebClient ( GetRequestTimeoutMs ( ) ) ;
412+ }
413+
414+ protected virtual int GetRequestTimeoutMs ( )
415+ {
416+ return DefaultRequestTimeoutMs ;
417+ }
418+
419+ private sealed class TimeoutWebClient : WebClient
420+ {
421+ private readonly int _timeoutMs ;
422+
423+ public TimeoutWebClient ( int timeoutMs )
424+ {
425+ _timeoutMs = timeoutMs ;
426+ }
427+
428+ protected override WebRequest GetWebRequest ( Uri address )
429+ {
430+ var request = base . GetWebRequest ( address ) ;
431+ if ( request != null )
432+ {
433+ request . Timeout = _timeoutMs ;
434+
435+ if ( request is HttpWebRequest httpRequest )
436+ {
437+ httpRequest . ReadWriteTimeout = _timeoutMs ;
438+ }
439+ }
440+
441+ return request ;
442+ }
443+ }
325444 }
326445}
0 commit comments