mirror of
https://github.com/ppy/osu.git
synced 2024-12-04 16:12:58 +08:00
Compare commits
16 Commits
5651530325
...
1548f17aa7
Author | SHA1 | Date | |
---|---|---|---|
|
1548f17aa7 | ||
|
f09d8f097a | ||
|
457957d3b8 | ||
|
2ceb3f6f85 | ||
|
7ece8ec1dc | ||
|
68f4fa5a57 | ||
|
68f21709a8 | ||
|
fa3c95c296 | ||
|
fced254594 | ||
|
0a8ec4db2b | ||
|
5b63d725c5 | ||
|
f5a7716509 | ||
|
13d7c6a2d8 | ||
|
cd9b5927eb | ||
|
c57ace0b5f | ||
|
8f6e5c4754 |
@ -46,8 +46,59 @@ dotnet_diagnostic.IDE0130.severity = warning
|
||||
# IDE1006: Naming style
|
||||
dotnet_diagnostic.IDE1006.severity = warning
|
||||
|
||||
#Disable operator overloads requiring alternate named methods
|
||||
dotnet_diagnostic.CA2225.severity = none
|
||||
# CA1305: Specify IFormatProvider
|
||||
# Too many noisy warnings for parsing/formatting numbers
|
||||
dotnet_diagnostic.CA1305.severity = none
|
||||
|
||||
# CA1507: Use nameof to express symbol names
|
||||
# Flaggs serialization name attributes
|
||||
dotnet_diagnostic.CA1507.severity = suggestion
|
||||
|
||||
# CA1806: Do not ignore method results
|
||||
# The usages for numeric parsing are explicitly optional
|
||||
dotnet_diagnostic.CA1806.severity = suggestion
|
||||
|
||||
# CA1822: Mark members as static
|
||||
# Potential false positive around reflection/too much noise
|
||||
dotnet_diagnostic.CA1822.severity = none
|
||||
|
||||
# CA1826: Do not use Enumerable method on indexable collections
|
||||
dotnet_diagnostic.CA1826.severity = suggestion
|
||||
|
||||
# CA1859: Use concrete types when possible for improved performance
|
||||
# Involves design considerations
|
||||
dotnet_diagnostic.CA1859.severity = suggestion
|
||||
|
||||
# CA1860: Avoid using 'Enumerable.Any()' extension method
|
||||
dotnet_diagnostic.CA1860.severity = suggestion
|
||||
|
||||
# CA1861: Avoid constant arrays as arguments
|
||||
# Outdated with collection expressions
|
||||
dotnet_diagnostic.CA1861.severity = suggestion
|
||||
|
||||
# CA2007: Consider calling ConfigureAwait on the awaited task
|
||||
dotnet_diagnostic.CA2007.severity = warning
|
||||
|
||||
# CA2016: Forward the 'CancellationToken' parameter to methods
|
||||
# Some overloads are having special handling for debugger
|
||||
dotnet_diagnostic.CA2016.severity = suggestion
|
||||
|
||||
# CA2021: Do not call Enumerable.Cast<T> or Enumerable.OfType<T> with incompatible types
|
||||
# Causing a lot of false positives with generics
|
||||
dotnet_diagnostic.CA2021.severity = none
|
||||
|
||||
# CA2101: Specify marshaling for P/Invoke string arguments
|
||||
# Reports warning for all non-UTF16 usages on DllImport; consider migrating to LibraryImport
|
||||
dotnet_diagnostic.CA2101.severity = none
|
||||
|
||||
# CA2201: Do not raise reserved exception types
|
||||
dotnet_diagnostic.CA2201.severity = warning
|
||||
|
||||
# CA2208: Instantiate argument exceptions correctly
|
||||
dotnet_diagnostic.CA2208.severity = suggestion
|
||||
|
||||
# CA2242: Test for NaN correctly
|
||||
dotnet_diagnostic.CA2242.severity = warning
|
||||
|
||||
# Banned APIs
|
||||
dotnet_diagnostic.RS0030.severity = error
|
||||
|
@ -14,10 +14,6 @@ M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Gen
|
||||
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
|
||||
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.
|
||||
M:System.Threading.ManualResetEventSlim.Wait();Specify a timeout to avoid waiting forever.
|
||||
M:System.Char.ToLower(System.Char);char.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture.
|
||||
M:System.Char.ToUpper(System.Char);char.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use char.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture.
|
||||
M:System.String.ToLower();string.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
|
||||
M:System.String.ToUpper();string.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
|
||||
M:Humanizer.InflectorExtensions.Pascalize(System.String);Humanizer's .Pascalize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToPascalCase() instead.
|
||||
M:Humanizer.InflectorExtensions.Camelize(System.String);Humanizer's .Camelize() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToCamelCase() instead.
|
||||
M:Humanizer.InflectorExtensions.Underscore(System.String);Humanizer's .Underscore() extension method changes behaviour depending on CultureInfo.CurrentCulture. Use StringDehumanizeExtensions.ToSnakeCase() instead.
|
||||
|
@ -1,58 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="osu! Rule Set" Description=" " ToolsVersion="16.0">
|
||||
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
|
||||
<Rule Id="CA1016" Action="None" />
|
||||
<Rule Id="CA1028" Action="None" />
|
||||
<Rule Id="CA1031" Action="None" />
|
||||
<Rule Id="CA1034" Action="None" />
|
||||
<Rule Id="CA1036" Action="None" />
|
||||
<Rule Id="CA1040" Action="None" />
|
||||
<Rule Id="CA1044" Action="None" />
|
||||
<Rule Id="CA1051" Action="None" />
|
||||
<Rule Id="CA1054" Action="None" />
|
||||
<Rule Id="CA1056" Action="None" />
|
||||
<Rule Id="CA1062" Action="None" />
|
||||
<Rule Id="CA1063" Action="None" />
|
||||
<Rule Id="CA1067" Action="None" />
|
||||
<Rule Id="CA1707" Action="None" />
|
||||
<Rule Id="CA1710" Action="None" />
|
||||
<Rule Id="CA1714" Action="None" />
|
||||
<Rule Id="CA1716" Action="None" />
|
||||
<Rule Id="CA1717" Action="None" />
|
||||
<Rule Id="CA1720" Action="None" />
|
||||
<Rule Id="CA1721" Action="None" />
|
||||
<Rule Id="CA1724" Action="None" />
|
||||
<Rule Id="CA1801" Action="None" />
|
||||
<Rule Id="CA1806" Action="None" />
|
||||
<Rule Id="CA1812" Action="None" />
|
||||
<Rule Id="CA1814" Action="None" />
|
||||
<Rule Id="CA1815" Action="None" />
|
||||
<Rule Id="CA1819" Action="None" />
|
||||
<Rule Id="CA1822" Action="None" />
|
||||
<Rule Id="CA1823" Action="None" />
|
||||
<Rule Id="CA2007" Action="Warning" />
|
||||
<Rule Id="CA2214" Action="None" />
|
||||
<Rule Id="CA2227" Action="None" />
|
||||
</Rules>
|
||||
<Rules AnalyzerId="Microsoft.CodeQuality.CSharp.Analyzers" RuleNamespace="Microsoft.CodeQuality.CSharp.Analyzers">
|
||||
<Rule Id="CA1001" Action="None" />
|
||||
<Rule Id="CA1032" Action="None" />
|
||||
</Rules>
|
||||
<Rules AnalyzerId="Microsoft.NetCore.Analyzers" RuleNamespace="Microsoft.NetCore.Analyzers">
|
||||
<Rule Id="CA1303" Action="None" />
|
||||
<Rule Id="CA1304" Action="None" />
|
||||
<Rule Id="CA1305" Action="None" />
|
||||
<Rule Id="CA1307" Action="None" />
|
||||
<Rule Id="CA1308" Action="None" />
|
||||
<Rule Id="CA1816" Action="None" />
|
||||
<Rule Id="CA1826" Action="None" />
|
||||
<Rule Id="CA2000" Action="None" />
|
||||
<Rule Id="CA2008" Action="None" />
|
||||
<Rule Id="CA2213" Action="None" />
|
||||
<Rule Id="CA2235" Action="None" />
|
||||
</Rules>
|
||||
<Rules AnalyzerId="Microsoft.NetCore.CSharp.Analyzers" RuleNamespace="Microsoft.NetCore.CSharp.Analyzers">
|
||||
<Rule Id="CA1309" Action="Warning" />
|
||||
<Rule Id="CA2201" Action="Warning" />
|
||||
</Rules>
|
||||
</RuleSet>
|
@ -20,7 +20,17 @@
|
||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Code Analysis">
|
||||
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
|
||||
<AnalysisMode>Default</AnalysisMode>
|
||||
<AnalysisModeDesign>Default</AnalysisModeDesign>
|
||||
<AnalysisModeDocumentation>Recommended</AnalysisModeDocumentation>
|
||||
<AnalysisModeGlobalization>Recommended</AnalysisModeGlobalization>
|
||||
<AnalysisModeInteroperability>Recommended</AnalysisModeInteroperability>
|
||||
<AnalysisModeMaintainability>Recommended</AnalysisModeMaintainability>
|
||||
<AnalysisModeNaming>Default</AnalysisModeNaming>
|
||||
<AnalysisModePerformance>Minimum</AnalysisModePerformance>
|
||||
<AnalysisModeReliability>Recommended</AnalysisModeReliability>
|
||||
<AnalysisModeSecurity>Default</AnalysisModeSecurity>
|
||||
<AnalysisModeUsage>Default</AnalysisModeUsage>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Documentation">
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
|
@ -164,7 +164,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 1: return colour_cyan;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 3:
|
||||
@ -176,7 +176,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 2: return colour_cyan;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 4:
|
||||
@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 3: return colour_purple;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 5:
|
||||
@ -206,7 +206,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 4: return colour_cyan;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 6:
|
||||
@ -224,7 +224,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 5: return colour_pink;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 7:
|
||||
@ -244,7 +244,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 6: return colour_pink;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 8:
|
||||
@ -266,7 +266,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 7: return colour_purple;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 9:
|
||||
@ -290,7 +290,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 8: return colour_purple;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
|
||||
case 10:
|
||||
@ -316,7 +316,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 9: return colour_purple;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,7 +339,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
|
||||
|
||||
case 5: return colour_green;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException();
|
||||
default: throw new ArgumentOutOfRangeException(nameof(columnIndex));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
7
osu.Game.Tests/CodeAnalysis.tests.globalconfig
Normal file
7
osu.Game.Tests/CodeAnalysis.tests.globalconfig
Normal file
@ -0,0 +1,7 @@
|
||||
# Higher global_level has higher priority, the default global_level
|
||||
# is 100 for root .globalconfig and 0 for others
|
||||
# https://learn.microsoft.com/dotnet/fundamentals/code-analysis/configuration-files#precedence
|
||||
is_global = true
|
||||
global_level = 101
|
||||
|
||||
dotnet_diagnostic.CA2007.severity = none
|
@ -221,7 +221,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
string? filePath = null;
|
||||
|
||||
// Files starting with _ are temporary, created by CreateFileSafely call.
|
||||
AddUntilStep("wait for export file", () => filePath = LocalStorage.GetFiles("exports").SingleOrDefault(f => !Path.GetFileName(f).StartsWith("_", StringComparison.Ordinal)), () => Is.Not.Null);
|
||||
AddUntilStep("wait for export file", () => filePath = LocalStorage.GetFiles("exports").SingleOrDefault(f => !Path.GetFileName(f).StartsWith('_')), () => Is.Not.Null);
|
||||
AddUntilStep("filesize is non-zero", () =>
|
||||
{
|
||||
try
|
||||
|
@ -198,7 +198,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
|
||||
AddStep("make second user host", () => MultiplayerClient.TransferHost(3));
|
||||
|
||||
AddUntilStep("kick buttons not visible", () => this.ChildrenOfType<ParticipantPanel.KickButton>().Count(d => d.IsPresent) == 0);
|
||||
AddUntilStep("kick buttons not visible", () => !this.ChildrenOfType<ParticipantPanel.KickButton>().Any(d => d.IsPresent));
|
||||
|
||||
AddStep("make local user host again", () => MultiplayerClient.TransferHost(API.LocalUser.Value.Id));
|
||||
|
||||
|
@ -151,7 +151,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
|
||||
AddStep("click delete option", () =>
|
||||
{
|
||||
InputManager.MoveMouseTo(contextMenuContainer.ChildrenOfType<DrawableOsuMenuItem>().First(i => i.Item.Text.Value.ToString().ToLowerInvariant() == "delete"));
|
||||
InputManager.MoveMouseTo(contextMenuContainer.ChildrenOfType<DrawableOsuMenuItem>().First(i => string.Equals(i.Item.Text.Value.ToString(), "delete", System.StringComparison.OrdinalIgnoreCase)));
|
||||
InputManager.Click(MouseButton.Left);
|
||||
});
|
||||
|
||||
|
@ -12,9 +12,9 @@
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Label="Code Analysis">
|
||||
<CodeAnalysisRuleSet>tests.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Code Analysis">
|
||||
<GlobalAnalyzerConfigFiles Include="CodeAnalysis.tests.globalconfig" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
|
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RuleSet Name="osu! Rule Set" Description=" " ToolsVersion="16.0">
|
||||
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
|
||||
<Rule Id="CA2007" Action="None" />
|
||||
</Rules>
|
||||
</RuleSet>
|
@ -248,29 +248,30 @@ namespace osu.Game.Database
|
||||
return new RealmLive<T>(realmObject, realm);
|
||||
}
|
||||
|
||||
#pragma warning disable RS0030 // mentioning banned symbols in documentation
|
||||
/// <summary>
|
||||
/// Register a callback to be invoked each time this <see cref="T:Realms.IRealmCollection`1" /> changes.
|
||||
/// Register a callback to be invoked each time this <see cref="IRealmCollection{T}" /> changes.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// This adds osu! specific thread and managed state safety checks on top of <see cref="IRealmCollection{T}.SubscribeForNotifications"/>.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// The first callback will be invoked with the initial <see cref="T:Realms.IRealmCollection`1" /> after the asynchronous query completes,
|
||||
/// The first callback will be invoked with the initial <see cref="IRealmCollection{T}" /> after the asynchronous query completes,
|
||||
/// and then called again after each write transaction which changes either any of the objects in the collection, or
|
||||
/// which objects are in the collection. The <c>changes</c> parameter will
|
||||
/// be <c>null</c> the first time the callback is invoked with the initial results. For each call after that,
|
||||
/// it will contain information about which rows in the results were added, removed or modified.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If a write transaction did not modify any objects in this <see cref="T:Realms.IRealmCollection`1" />, the callback is not invoked at all.
|
||||
/// If a write transaction did not modify any objects in this <see cref="IRealmCollection{T}" />, the callback is not invoked at all.
|
||||
/// If an error occurs the callback will be invoked with <c>null</c> for the <c>sender</c> parameter and a non-<c>null</c> <c>error</c>.
|
||||
/// Currently the only errors that can occur are when opening the <see cref="T:Realms.Realm" /> on the background worker thread.
|
||||
/// Currently the only errors that can occur are when opening the <see cref="Realm" /> on the background worker thread.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// At the time when the block is called, the <see cref="T:Realms.IRealmCollection`1" /> object will be fully evaluated
|
||||
/// At the time when the block is called, the <see cref="IRealmCollection{T}" /> object will be fully evaluated
|
||||
/// and up-to-date, and as long as you do not perform a write transaction on the same thread
|
||||
/// or explicitly call <see cref="M:Realms.Realm.Refresh" />, accessing it will never perform blocking work.
|
||||
/// or explicitly call <see cref="Realm.Refresh" />, accessing it will never perform blocking work.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// Notifications are delivered via the standard event loop, and so can't be delivered while the event loop is blocked by other activity.
|
||||
@ -279,13 +280,14 @@ namespace osu.Game.Database
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
/// <param name="collection">The <see cref="IRealmCollection{T}"/> to observe for changes.</param>
|
||||
/// <param name="callback">The callback to be invoked with the updated <see cref="T:Realms.IRealmCollection`1" />.</param>
|
||||
/// <param name="callback">The callback to be invoked with the updated <see cref="IRealmCollection{T}" />.</param>
|
||||
/// <returns>
|
||||
/// A subscription token. It must be kept alive for as long as you want to receive change notifications.
|
||||
/// To stop receiving notifications, call <see cref="M:System.IDisposable.Dispose" />.
|
||||
/// To stop receiving notifications, call <see cref="IDisposable.Dispose" />.
|
||||
/// </returns>
|
||||
/// <seealso cref="M:Realms.CollectionExtensions.SubscribeForNotifications``1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0})" />
|
||||
/// <seealso cref="M:Realms.CollectionExtensions.SubscribeForNotifications``1(System.Linq.IQueryable{``0},Realms.NotificationCallbackDelegate{``0})" />
|
||||
/// <seealso cref="Realms.CollectionExtensions.SubscribeForNotifications{T}(IList{T}, NotificationCallbackDelegate{T})" />
|
||||
/// <seealso cref="Realms.CollectionExtensions.SubscribeForNotifications{T}(IQueryable{T}, NotificationCallbackDelegate{T})" />
|
||||
#pragma warning restore RS0030
|
||||
public static IDisposable QueryAsyncWithNotifications<T>(this IRealmCollection<T> collection, NotificationCallbackDelegate<T> callback)
|
||||
where T : RealmObjectBase
|
||||
{
|
||||
|
@ -60,7 +60,7 @@ namespace osu.Game.Extensions
|
||||
public static string ToCamelCase(this string input)
|
||||
{
|
||||
string word = input.ToPascalCase();
|
||||
return word.Length > 0 ? word.Substring(0, 1).ToLowerInvariant() + word.Substring(1) : word;
|
||||
return word.Length > 0 ? char.ToLowerInvariant(word[0]) + word.Substring(1) : word;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -44,6 +44,11 @@ namespace osu.Game.Localisation
|
||||
/// </summary>
|
||||
public static LocalisableString CheckUpdate => new TranslatableString(getKey(@"check_update"), @"Check for updates");
|
||||
|
||||
/// <summary>
|
||||
/// "Checking for updates"
|
||||
/// </summary>
|
||||
public static LocalisableString CheckingForUpdates => new TranslatableString(getKey(@"checking_for_updates"), @"Checking for updates");
|
||||
|
||||
/// <summary>
|
||||
/// "Open osu! folder"
|
||||
/// </summary>
|
||||
|
@ -363,7 +363,7 @@ namespace osu.Game.Online.Leaderboards
|
||||
return null;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(state));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -87,7 +87,7 @@ namespace osu.Game.Online
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(state.NewValue));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -126,7 +126,7 @@ namespace osu.Game.Overlays
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(state.NewValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -386,10 +386,8 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
channelList.RemoveChannel(channel);
|
||||
|
||||
if (loadedChannels.ContainsKey(channel))
|
||||
if (loadedChannels.Remove(channel, out var loaded))
|
||||
{
|
||||
DrawableChannel loaded = loadedChannels[channel];
|
||||
loadedChannels.Remove(channel);
|
||||
// DrawableChannel removed from cache must be manually disposed
|
||||
loaded.Dispose();
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ namespace osu.Game.Overlays.Comments
|
||||
protected void OnSuccess(CommentBundle response)
|
||||
{
|
||||
commentCounter.Current.Value = response.Total;
|
||||
newCommentEditor.CommentableMeta.Value = response.CommentableMeta.SingleOrDefault(m => m.Id == id.Value && m.Type == type.Value.ToString().ToSnakeCase().ToLowerInvariant());
|
||||
newCommentEditor.CommentableMeta.Value = response.CommentableMeta.SingleOrDefault(m => m.Id == id.Value && string.Equals(m.Type, type.Value.ToString().ToSnakeCase(), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (!response.Comments.Any())
|
||||
{
|
||||
|
@ -4,7 +4,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Extensions;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osu.Framework.Localisation;
|
||||
using osu.Framework.Logging;
|
||||
@ -13,6 +12,7 @@ using osu.Framework.Screens;
|
||||
using osu.Framework.Statistics;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Localisation;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Overlays.Notifications;
|
||||
using osu.Game.Overlays.Settings.Sections.Maintenance;
|
||||
using osu.Game.Updater;
|
||||
@ -36,8 +36,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
[Resolved]
|
||||
private Storage storage { get; set; } = null!;
|
||||
|
||||
[Resolved]
|
||||
private OsuGame? game { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config, OsuGame? game)
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
Add(new SettingsEnumDropdown<ReleaseStream>
|
||||
{
|
||||
@ -50,23 +53,7 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
Add(checkForUpdatesButton = new SettingsButton
|
||||
{
|
||||
Text = GeneralSettingsStrings.CheckUpdate,
|
||||
Action = () =>
|
||||
{
|
||||
checkForUpdatesButton.Enabled.Value = false;
|
||||
Task.Run(updateManager.CheckForUpdateAsync).ContinueWith(task => Schedule(() =>
|
||||
{
|
||||
if (!task.GetResultSafely())
|
||||
{
|
||||
notifications?.Post(new SimpleNotification
|
||||
{
|
||||
Text = GeneralSettingsStrings.RunningLatestRelease(game!.Version),
|
||||
Icon = FontAwesome.Solid.CheckCircle,
|
||||
});
|
||||
}
|
||||
|
||||
checkForUpdatesButton.Enabled.Value = true;
|
||||
}));
|
||||
}
|
||||
Action = () => checkForUpdates().FireAndForget()
|
||||
});
|
||||
}
|
||||
|
||||
@ -94,6 +81,44 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
||||
}
|
||||
}
|
||||
|
||||
private async Task checkForUpdates()
|
||||
{
|
||||
if (updateManager == null || game == null)
|
||||
return;
|
||||
|
||||
checkForUpdatesButton.Enabled.Value = false;
|
||||
|
||||
var checkingNotification = new ProgressNotification
|
||||
{
|
||||
Text = GeneralSettingsStrings.CheckingForUpdates,
|
||||
};
|
||||
notifications?.Post(checkingNotification);
|
||||
|
||||
try
|
||||
{
|
||||
bool foundUpdate = await updateManager.CheckForUpdateAsync().ConfigureAwait(true);
|
||||
|
||||
if (!foundUpdate)
|
||||
{
|
||||
notifications?.Post(new SimpleNotification
|
||||
{
|
||||
Text = GeneralSettingsStrings.RunningLatestRelease(game.Version),
|
||||
Icon = FontAwesome.Solid.CheckCircle,
|
||||
});
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
}
|
||||
finally
|
||||
{
|
||||
// This sequence allows the notification to be immediately dismissed.
|
||||
checkingNotification.State = ProgressNotificationState.Cancelled;
|
||||
checkingNotification.Close(false);
|
||||
checkForUpdatesButton.Enabled.Value = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void exportLogs()
|
||||
{
|
||||
ProgressNotification notification = new ProgressNotification
|
||||
|
@ -130,7 +130,7 @@ namespace osu.Game.Overlays.Toolbar
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException();
|
||||
throw new ArgumentOutOfRangeException(nameof(state.NewValue));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -173,10 +173,10 @@ namespace osu.Game.Rulesets.Mods
|
||||
};
|
||||
drawable.OnRevertResult += (_, result) =>
|
||||
{
|
||||
if (!ratesForRewinding.ContainsKey(result.HitObject)) return;
|
||||
if (!ratesForRewinding.TryGetValue(result.HitObject, out double rate)) return;
|
||||
if (!shouldProcessResult(result)) return;
|
||||
|
||||
recentRates.Insert(0, ratesForRewinding[result.HitObject]);
|
||||
recentRates.Insert(0, rate);
|
||||
ratesForRewinding.Remove(result.HitObject);
|
||||
|
||||
recentRates.RemoveAt(recentRates.Count - 1);
|
||||
|
@ -243,7 +243,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
|
||||
return PathType.CATMULL;
|
||||
|
||||
case 'B':
|
||||
if (input.Length > 1 && int.TryParse(input.Substring(1), out int degree) && degree > 0)
|
||||
if (input.Length > 1 && int.TryParse(input.AsSpan(1), out int degree) && degree > 0)
|
||||
return PathType.BSpline(degree);
|
||||
|
||||
return PathType.BEZIER;
|
||||
|
@ -59,14 +59,14 @@ namespace osu.Game.Screens.Ranking.Statistics.User
|
||||
new SimpleStatisticTable.Spacer(),
|
||||
new PerformancePointsChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } },
|
||||
},
|
||||
new Drawable[] { },
|
||||
[],
|
||||
new Drawable[]
|
||||
{
|
||||
new MaximumComboChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } },
|
||||
new SimpleStatisticTable.Spacer(),
|
||||
new AccuracyChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } },
|
||||
},
|
||||
new Drawable[] { },
|
||||
[],
|
||||
new Drawable[]
|
||||
{
|
||||
new RankedScoreChangeRow { StatisticsUpdate = { BindTarget = StatisticsUpdate } },
|
||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
protected override string[] HashableFileTypes => new[] { ".ini", ".json" };
|
||||
|
||||
protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path).ToLowerInvariant() == @".osk";
|
||||
protected override bool ShouldDeleteArchive(string path) => string.Equals(Path.GetExtension(path), @".osk", StringComparison.OrdinalIgnoreCase);
|
||||
|
||||
protected override SkinInfo CreateModel(ArchiveReader archive, ImportParameters parameters) => new SkinInfo { Name = archive.Name ?? @"No name" };
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
@ -91,7 +92,7 @@ namespace osu.Game.Storyboards
|
||||
// Importantly, do this after the NullOrEmpty because EF may have stored the non-nullable value as null to the database, bypassing compile-time constraints.
|
||||
backgroundPath = backgroundPath.ToLowerInvariant();
|
||||
|
||||
return GetLayer("Background").Elements.Any(e => e.Path.ToLowerInvariant() == backgroundPath);
|
||||
return GetLayer("Background").Elements.Any(e => string.Equals(e.Path, backgroundPath, StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -78,12 +78,12 @@ namespace osu.Game.Tests.Visual.Spectator
|
||||
/// <param name="state">The spectator state to end play with.</param>
|
||||
public void SendEndPlay(int userId, SpectatedUserState state = SpectatedUserState.Quit)
|
||||
{
|
||||
if (!userBeatmapDictionary.TryGetValue(userId, out int value))
|
||||
if (!userBeatmapDictionary.TryGetValue(userId, out int beatmapId))
|
||||
return;
|
||||
|
||||
((ISpectatorClient)this).UserFinishedPlaying(userId, new SpectatorState
|
||||
{
|
||||
BeatmapID = value,
|
||||
BeatmapID = beatmapId,
|
||||
RulesetID = 0,
|
||||
Mods = userModsDictionary[userId],
|
||||
State = state
|
||||
|
@ -666,10 +666,7 @@ namespace osu.Game.Utils
|
||||
{
|
||||
// 2020-10-07 jbialogrodzki #730 Since this is public API we should probably
|
||||
// handle null arguments? It doesn't seem to have been done consistently in this class though.
|
||||
if (coefficients == null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(coefficients));
|
||||
}
|
||||
ArgumentNullException.ThrowIfNull(coefficients);
|
||||
|
||||
// 2020-10-07 jbialogrodzki #730 Zero polynomials need explicit handling.
|
||||
// Without this check, we attempted to peek coefficients at negative indices!
|
||||
|
2
osu.sln
2
osu.sln
@ -60,7 +60,7 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
|
||||
Directory.Build.props = Directory.Build.props
|
||||
osu.Android.props = osu.Android.props
|
||||
osu.iOS.props = osu.iOS.props
|
||||
CodeAnalysis\osu.ruleset = CodeAnalysis\osu.ruleset
|
||||
global.json = global.json
|
||||
osu.sln.DotSettings = osu.sln.DotSettings
|
||||
osu.TestProject.props = osu.TestProject.props
|
||||
EndProjectSection
|
||||
|
Loading…
Reference in New Issue
Block a user