1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 12:17:26 +08:00

Merge branch 'master' into peppy/skinnable-health-display

This commit is contained in:
smoogipoo 2020-10-16 23:17:17 +09:00
commit dfbc0965e4
35 changed files with 86 additions and 134 deletions

View File

@ -2,7 +2,7 @@
<project version="4"> <project version="4">
<component name="ProjectModuleManager"> <component name="ProjectModuleManager">
<modules> <modules>
<module fileurl="file://$PROJECT_DIR$/.idea/.idea.osu.Desktop/riderModule.iml" filepath="$PROJECT_DIR$/.idea/.idea.osu.Desktop/riderModule.iml" /> <module fileurl="file://$PROJECT_DIR$/.idea/.idea.osu.Desktop/.idea/riderModule.iml" filepath="$PROJECT_DIR$/.idea/.idea.osu.Desktop/.idea/riderModule.iml" />
</modules> </modules>
</component> </component>
</project> </project>

View File

@ -30,7 +30,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
{ {
private static readonly DllResourceStore beatmaps_resource_store = TestResources.GetStore(); private static readonly DllResourceStore beatmaps_resource_store = TestResources.GetStore();
private static IEnumerable<string> allBeatmaps = beatmaps_resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu")); private static IEnumerable<string> allBeatmaps = beatmaps_resource_store.GetAvailableResources().Where(res => res.EndsWith(".osu", StringComparison.Ordinal));
[TestCaseSource(nameof(allBeatmaps))] [TestCaseSource(nameof(allBeatmaps))]
public void TestEncodeDecodeStability(string name) public void TestEncodeDecodeStability(string name)

View File

@ -69,7 +69,7 @@ namespace osu.Game.Tests.Visual.Gameplay
createNew(h => h.OnLoadComplete += _ => initialAlpha = hideTarget.Alpha); createNew(h => h.OnLoadComplete += _ => initialAlpha = hideTarget.Alpha);
AddUntilStep("wait for load", () => hudOverlay.IsAlive); AddUntilStep("wait for load", () => hudOverlay.IsAlive);
AddAssert("initial alpha was less than 1", () => initialAlpha != null && initialAlpha < 1); AddAssert("initial alpha was less than 1", () => initialAlpha < 1);
} }
[Test] [Test]

View File

@ -1,68 +0,0 @@
// 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 NUnit.Framework;
using osu.Framework.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Screens.Play.HUD;
using osuTK;
namespace osu.Game.Tests.Visual.Gameplay
{
[TestFixture]
public class TestSceneScoreCounter : OsuTestScene
{
public TestSceneScoreCounter()
{
int numerator = 0, denominator = 0;
ScoreCounter score = new DefaultScoreCounter
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
Margin = new MarginPadding(20),
};
Add(score);
LegacyComboCounter comboCounter = new LegacyComboCounter
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.BottomLeft,
Margin = new MarginPadding(10),
};
Add(comboCounter);
PercentageCounter accuracyCounter = new PercentageCounter
{
Origin = Anchor.TopRight,
Anchor = Anchor.TopRight,
Position = new Vector2(-20, 60),
};
Add(accuracyCounter);
AddStep(@"Reset all", delegate
{
score.Current.Value = 0;
comboCounter.Current.Value = 0;
numerator = denominator = 0;
accuracyCounter.SetFraction(0, 0);
});
AddStep(@"Hit! :D", delegate
{
score.Current.Value += 300 + (ulong)(300.0 * (comboCounter.Current.Value > 0 ? comboCounter.Current.Value - 1 : 0) / 25.0);
comboCounter.Current.Value++;
numerator++;
denominator++;
accuracyCounter.SetFraction(numerator, denominator);
});
AddStep(@"miss...", delegate
{
comboCounter.Current.Value = 0;
denominator++;
accuracyCounter.SetFraction(numerator, denominator);
});
}
}
}

View File

@ -394,7 +394,7 @@ namespace osu.Game.Tests.Visual.SongSelect
AddStep("Sort by author", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Author }, false)); AddStep("Sort by author", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Author }, false));
AddAssert("Check zzzzz is at bottom", () => carousel.BeatmapSets.Last().Metadata.AuthorString == "zzzzz"); AddAssert("Check zzzzz is at bottom", () => carousel.BeatmapSets.Last().Metadata.AuthorString == "zzzzz");
AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false)); AddStep("Sort by artist", () => carousel.Filter(new FilterCriteria { Sort = SortMode.Artist }, false));
AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!")); AddAssert($"Check #{set_count} is at bottom", () => carousel.BeatmapSets.Last().Metadata.Title.EndsWith($"#{set_count}!", StringComparison.Ordinal));
} }
[Test] [Test]

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using osu.Framework.Audio; using osu.Framework.Audio;
@ -59,7 +60,7 @@ namespace osu.Game.Tests
get get
{ {
using (var reader = getZipReader()) using (var reader = getZipReader())
return reader.Filenames.First(f => f.EndsWith(".mp3")); return reader.Filenames.First(f => f.EndsWith(".mp3", StringComparison.Ordinal));
} }
} }
@ -73,7 +74,7 @@ namespace osu.Game.Tests
protected override Beatmap CreateBeatmap() protected override Beatmap CreateBeatmap()
{ {
using (var reader = getZipReader()) using (var reader = getZipReader())
using (var beatmapStream = reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu")))) using (var beatmapStream = reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu", StringComparison.Ordinal))))
using (var beatmapReader = new LineBufferedReader(beatmapStream)) using (var beatmapReader = new LineBufferedReader(beatmapStream))
return Decoder.GetDecoder<Beatmap>(beatmapReader).Decode(beatmapReader); return Decoder.GetDecoder<Beatmap>(beatmapReader).Decode(beatmapReader);
} }

View File

@ -234,7 +234,7 @@ namespace osu.Game.Tournament.Screens.Drawings
if (string.IsNullOrEmpty(line)) if (string.IsNullOrEmpty(line))
continue; continue;
if (line.ToUpperInvariant().StartsWith("GROUP")) if (line.ToUpperInvariant().StartsWith("GROUP", StringComparison.Ordinal))
continue; continue;
// ReSharper disable once AccessToModifiedClosure // ReSharper disable once AccessToModifiedClosure

View File

@ -98,7 +98,7 @@ namespace osu.Game.Beatmaps
[JsonIgnore] [JsonIgnore]
public string StoredBookmarks public string StoredBookmarks
{ {
get => string.Join(",", Bookmarks); get => string.Join(',', Bookmarks);
set set
{ {
if (string.IsNullOrEmpty(value)) if (string.IsNullOrEmpty(value))

View File

@ -391,7 +391,7 @@ namespace osu.Game.Beatmaps
protected override BeatmapSetInfo CreateModel(ArchiveReader reader) protected override BeatmapSetInfo CreateModel(ArchiveReader reader)
{ {
// let's make sure there are actually .osu files to import. // let's make sure there are actually .osu files to import.
string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu")); string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu", StringComparison.OrdinalIgnoreCase));
if (string.IsNullOrEmpty(mapName)) if (string.IsNullOrEmpty(mapName))
{ {
@ -419,7 +419,7 @@ namespace osu.Game.Beatmaps
{ {
var beatmapInfos = new List<BeatmapInfo>(); var beatmapInfos = new List<BeatmapInfo>();
foreach (var file in files.Where(f => f.Filename.EndsWith(".osu"))) foreach (var file in files.Where(f => f.Filename.EndsWith(".osu", StringComparison.OrdinalIgnoreCase)))
{ {
using (var raw = Files.Store.GetStream(file.FileInfo.StoragePath)) using (var raw = Files.Store.GetStream(file.FileInfo.StoragePath))
using (var ms = new MemoryStream()) // we need a memory stream so we can seek using (var ms = new MemoryStream()) // we need a memory stream so we can seek

View File

@ -57,7 +57,7 @@ namespace osu.Game.Beatmaps
public string Hash { get; set; } public string Hash { get; set; }
public string StoryboardFile => Files?.Find(f => f.Filename.EndsWith(".osb"))?.Filename; public string StoryboardFile => Files?.Find(f => f.Filename.EndsWith(".osb", StringComparison.OrdinalIgnoreCase))?.Filename;
public List<BeatmapSetFileInfo> Files { get; set; } public List<BeatmapSetFileInfo> Files { get; set; }

View File

@ -92,7 +92,7 @@ namespace osu.Game.Beatmaps.Formats
{ {
var pair = SplitKeyVal(line); var pair = SplitKeyVal(line);
bool isCombo = pair.Key.StartsWith(@"Combo"); bool isCombo = pair.Key.StartsWith(@"Combo", StringComparison.Ordinal);
string[] split = pair.Value.Split(','); string[] split = pair.Value.Split(',');

View File

@ -279,7 +279,7 @@ namespace osu.Game.Database
// for now, concatenate all .osu files in the set to create a unique hash. // for now, concatenate all .osu files in the set to create a unique hash.
MemoryStream hashable = new MemoryStream(); MemoryStream hashable = new MemoryStream();
foreach (TFileModel file in item.Files.Where(f => HashableFileTypes.Any(f.Filename.EndsWith)).OrderBy(f => f.Filename)) foreach (TFileModel file in item.Files.Where(f => HashableFileTypes.Any(ext => f.Filename.EndsWith(ext, StringComparison.OrdinalIgnoreCase))).OrderBy(f => f.Filename))
{ {
using (Stream s = Files.Store.GetStream(file.FileInfo.StoragePath)) using (Stream s = Files.Store.GetStream(file.FileInfo.StoragePath))
s.CopyTo(hashable); s.CopyTo(hashable);
@ -593,7 +593,7 @@ namespace osu.Game.Database
var fileInfos = new List<TFileModel>(); var fileInfos = new List<TFileModel>();
string prefix = reader.Filenames.GetCommonPrefix(); string prefix = reader.Filenames.GetCommonPrefix();
if (!(prefix.EndsWith("/") || prefix.EndsWith("\\"))) if (!(prefix.EndsWith('/') || prefix.EndsWith('\\')))
prefix = string.Empty; prefix = string.Empty;
// import files to manager // import files to manager

View File

@ -196,7 +196,7 @@ namespace osu.Game.Online.Chat
if (target == null) if (target == null)
return; return;
var parameters = text.Split(new[] { ' ' }, 2); var parameters = text.Split(' ', 2);
string command = parameters[0]; string command = parameters[0];
string content = parameters.Length == 2 ? parameters[1] : string.Empty; string content = parameters.Length == 2 ? parameters[1] : string.Empty;

View File

@ -111,7 +111,7 @@ namespace osu.Game.Online.Chat
public static LinkDetails GetLinkDetails(string url) public static LinkDetails GetLinkDetails(string url)
{ {
var args = url.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries); var args = url.Split('/', StringSplitOptions.RemoveEmptyEntries);
args[0] = args[0].TrimEnd(':'); args[0] = args[0].TrimEnd(':');
switch (args[0]) switch (args[0])

View File

@ -181,7 +181,7 @@ namespace osu.Game
if (args?.Length > 0) if (args?.Length > 0)
{ {
var paths = args.Where(a => !a.StartsWith(@"-")).ToArray(); var paths = args.Where(a => !a.StartsWith('-')).ToArray();
if (paths.Length > 0) if (paths.Length > 0)
Task.Run(() => Import(paths)); Task.Run(() => Import(paths));
} }
@ -289,7 +289,7 @@ namespace osu.Game
public void OpenUrlExternally(string url) => waitForReady(() => externalLinkOpener, _ => public void OpenUrlExternally(string url) => waitForReady(() => externalLinkOpener, _ =>
{ {
if (url.StartsWith("/")) if (url.StartsWith('/'))
url = $"{API.Endpoint}{url}"; url = $"{API.Endpoint}{url}";
externalLinkOpener.OpenUrlExternally(url); externalLinkOpener.OpenUrlExternally(url);

View File

@ -135,7 +135,6 @@ namespace osu.Game.Overlays.Profile.Header
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}");
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Discord, user.Discord); anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Discord, user.Discord);
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat"); anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Skype, user.Skype, @"skype:" + user.Skype + @"?chat");
anyInfoAdded |= tryAddInfo(FontAwesome.Brands.Lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}");
anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website); anyInfoAdded |= tryAddInfo(FontAwesome.Solid.Link, websiteWithoutProtocol, user.Website);
// If no information was added to the bottomLinkContainer, hide it to avoid unwanted padding // If no information was added to the bottomLinkContainer, hide it to avoid unwanted padding
@ -149,7 +148,7 @@ namespace osu.Game.Overlays.Profile.Header
if (string.IsNullOrEmpty(content)) return false; if (string.IsNullOrEmpty(content)) return false;
// newlines could be contained in API returned user content. // newlines could be contained in API returned user content.
content = content.Replace("\n", " "); content = content.Replace('\n', ' ');
bottomLinkContainer.AddIcon(icon, text => bottomLinkContainer.AddIcon(icon, text =>
{ {

View File

@ -159,7 +159,7 @@ namespace osu.Game.Rulesets.Objects.Legacy
{ {
string[] ss = split[5].Split(':'); string[] ss = split[5].Split(':');
endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0])); endTime = Math.Max(startTime, Parsing.ParseDouble(ss[0]));
readCustomSampleBanks(string.Join(":", ss.Skip(1)), bankInfo); readCustomSampleBanks(string.Join(':', ss.Skip(1)), bankInfo);
} }
result = CreateHold(pos, combo, comboOffset, endTime + Offset - startTime); result = CreateHold(pos, combo, comboOffset, endTime + Offset - startTime);

View File

@ -100,7 +100,7 @@ namespace osu.Game.Rulesets
{ {
// todo: StartsWith can be changed to Equals on 2020-11-08 // todo: StartsWith can be changed to Equals on 2020-11-08
// This is to give users enough time to have their database use new abbreviated info). // This is to give users enough time to have their database use new abbreviated info).
if (context.RulesetInfo.FirstOrDefault(ri => ri.InstantiationInfo.StartsWith(r.RulesetInfo.InstantiationInfo)) == null) if (context.RulesetInfo.FirstOrDefault(ri => ri.InstantiationInfo.StartsWith(r.RulesetInfo.InstantiationInfo, StringComparison.Ordinal)) == null)
context.RulesetInfo.Add(r.RulesetInfo); context.RulesetInfo.Add(r.RulesetInfo);
} }

View File

@ -57,7 +57,7 @@ namespace osu.Game.Scoring
if (archive == null) if (archive == null)
return null; return null;
using (var stream = archive.GetStream(archive.Filenames.First(f => f.EndsWith(".osr")))) using (var stream = archive.GetStream(archive.Filenames.First(f => f.EndsWith(".osr", StringComparison.OrdinalIgnoreCase))))
{ {
try try
{ {

View File

@ -79,9 +79,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
private void updatePlacementNewCombo() private void updatePlacementNewCombo()
{ {
if (currentPlacement == null) return; if (currentPlacement?.HitObject is IHasComboInformation c)
if (currentPlacement.HitObject is IHasComboInformation c)
c.NewCombo = NewCombo.Value == TernaryState.True; c.NewCombo = NewCombo.Value == TernaryState.True;
} }

View File

@ -597,10 +597,20 @@ namespace osu.Game.Screens.Edit
{ {
double amount = e.ShiftPressed ? 4 : 1; double amount = e.ShiftPressed ? 4 : 1;
bool trackPlaying = clock.IsRunning;
if (trackPlaying)
{
// generally users are not looking to perform tiny seeks when the track is playing,
// so seeks should always be by one full beat, bypassing the beatDivisor.
// this multiplication undoes the division that will be applied in the underlying seek operation.
amount *= beatDivisor.Value;
}
if (direction < 1) if (direction < 1)
clock.SeekBackward(!clock.IsRunning, amount); clock.SeekBackward(!trackPlaying, amount);
else else
clock.SeekForward(!clock.IsRunning, amount); clock.SeekForward(!trackPlaying, amount);
} }
private void exportBeatmap() private void exportBeatmap()

View File

@ -6,6 +6,7 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
using osu.Game.Skinning; using osu.Game.Skinning;
using osuTK; using osuTK;
@ -246,6 +247,6 @@ namespace osu.Game.Screens.Play.HUD
return difference * rolling_duration; return difference * rolling_duration;
} }
private Drawable createSpriteText() => new LegacySpriteText(skin); private OsuSpriteText createSpriteText() => (OsuSpriteText)skin.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ComboText));
} }
} }

View File

@ -79,10 +79,10 @@ namespace osu.Game.Screens.Select
} }
private static int getLengthScale(string value) => private static int getLengthScale(string value) =>
value.EndsWith("ms") ? 1 : value.EndsWith("ms", StringComparison.Ordinal) ? 1 :
value.EndsWith("s") ? 1000 : value.EndsWith('s') ? 1000 :
value.EndsWith("m") ? 60000 : value.EndsWith('m') ? 60000 :
value.EndsWith("h") ? 3600000 : 1000; value.EndsWith('h') ? 3600000 : 1000;
private static bool parseFloatWithPoint(string value, out float result) => private static bool parseFloatWithPoint(string value, out float result) =>
float.TryParse(value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out result); float.TryParse(value, NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture, out result);

View File

@ -18,6 +18,6 @@ namespace osu.Game.Skinning
protected virtual string ComponentName => Component.ToString(); protected virtual string ComponentName => Component.ToString();
public string LookupName => public string LookupName =>
string.Join("/", new[] { "Gameplay", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s))); string.Join('/', new[] { "Gameplay", RulesetPrefix, ComponentName }.Where(s => !string.IsNullOrEmpty(s)));
} }
} }

View File

@ -17,6 +17,6 @@ namespace osu.Game.Skinning
protected virtual string ComponentName => Component.ToString(); protected virtual string ComponentName => Component.ToString();
public string LookupName => public string LookupName =>
string.Join("/", new[] { "HUD", ComponentName }.Where(s => !string.IsNullOrEmpty(s))); string.Join('/', new[] { "HUD", ComponentName }.Where(s => !string.IsNullOrEmpty(s)));
} }
} }

View File

@ -8,6 +8,8 @@ namespace osu.Game.Skinning
ComboCounter, ComboCounter,
ScoreCounter, ScoreCounter,
AccuracyCounter, AccuracyCounter,
HealthDisplay HealthDisplay,
ScoreText,
ComboText,
} }
} }

View File

@ -29,12 +29,7 @@ namespace osu.Game.Skinning
[Resolved(canBeNull: true)] [Resolved(canBeNull: true)]
private HUDOverlay hud { get; set; } private HUDOverlay hud { get; set; }
protected sealed override OsuSpriteText CreateSpriteText() => protected sealed override OsuSpriteText CreateSpriteText() => (OsuSpriteText)skin?.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText));
new LegacySpriteText(skin, "score" /*, true*/)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
};
protected override void Update() protected override void Update()
{ {

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Globalization; using System.Globalization;
@ -115,16 +116,16 @@ namespace osu.Game.Skinning
currentConfig.MinimumColumnWidth = minWidth; currentConfig.MinimumColumnWidth = minWidth;
break; break;
case string _ when pair.Key.StartsWith("Colour"): case string _ when pair.Key.StartsWith("Colour", StringComparison.Ordinal):
HandleColours(currentConfig, line); HandleColours(currentConfig, line);
break; break;
// Custom sprite paths // Custom sprite paths
case string _ when pair.Key.StartsWith("NoteImage"): case string _ when pair.Key.StartsWith("NoteImage", StringComparison.Ordinal):
case string _ when pair.Key.StartsWith("KeyImage"): case string _ when pair.Key.StartsWith("KeyImage", StringComparison.Ordinal):
case string _ when pair.Key.StartsWith("Hit"): case string _ when pair.Key.StartsWith("Hit", StringComparison.Ordinal):
case string _ when pair.Key.StartsWith("Stage"): case string _ when pair.Key.StartsWith("Stage", StringComparison.Ordinal):
case string _ when pair.Key.StartsWith("Lighting"): case string _ when pair.Key.StartsWith("Lighting", StringComparison.Ordinal):
currentConfig.ImageLookups[pair.Key] = pair.Value; currentConfig.ImageLookups[pair.Key] = pair.Value;
break; break;
} }

View File

@ -25,17 +25,12 @@ namespace osu.Game.Skinning
this.skin = skin; this.skin = skin;
// base class uses int for display, but externally we bind to ScoreProcesssor as a double for now. // base class uses int for display, but externally we bind to ScoreProcessor as a double for now.
Current.BindValueChanged(v => base.Current.Value = (int)v.NewValue); Current.BindValueChanged(v => base.Current.Value = (int)v.NewValue);
Margin = new MarginPadding(10); Margin = new MarginPadding(10);
} }
protected sealed override OsuSpriteText CreateSpriteText() => protected sealed override OsuSpriteText CreateSpriteText() => (OsuSpriteText)skin.GetDrawableComponent(new HUDSkinComponent(HUDSkinComponents.ScoreText));
new LegacySpriteText(skin, "score" /*, true*/)
{
Anchor = Anchor.TopRight,
Origin = Anchor.TopRight,
};
} }
} }

View File

@ -19,6 +19,7 @@ using osu.Game.Beatmaps.Formats;
using osu.Game.IO; using osu.Game.IO;
using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play.HUD; using osu.Game.Screens.Play.HUD;
using osuTK;
using osuTK.Graphics; using osuTK.Graphics;
namespace osu.Game.Skinning namespace osu.Game.Skinning
@ -324,9 +325,11 @@ namespace osu.Game.Skinning
return null; return null;
} }
private const string score_font = "score"; private string scorePrefix => GetConfig<LegacySkinConfiguration.LegacySetting, string>(LegacySkinConfiguration.LegacySetting.ScorePrefix)?.Value ?? "score";
private bool hasScoreFont => this.HasFont(score_font); private string comboPrefix => GetConfig<LegacySkinConfiguration.LegacySetting, string>(LegacySkinConfiguration.LegacySetting.ComboPrefix)?.Value ?? "score";
private bool hasScoreFont => this.HasFont(scorePrefix);
public override Drawable GetDrawableComponent(ISkinComponent component) public override Drawable GetDrawableComponent(ISkinComponent component)
{ {
@ -350,6 +353,18 @@ namespace osu.Game.Skinning
case HUDSkinComponents.HealthDisplay: case HUDSkinComponents.HealthDisplay:
return new LegacyHealthDisplay(this); return new LegacyHealthDisplay(this);
case HUDSkinComponents.ComboText:
return new LegacySpriteText(this, comboPrefix)
{
Spacing = new Vector2(-(GetConfig<LegacySkinConfiguration.LegacySetting, int>(LegacySkinConfiguration.LegacySetting.ComboOverlap)?.Value ?? -2), 0)
};
case HUDSkinComponents.ScoreText:
return new LegacySpriteText(this, scorePrefix)
{
Spacing = new Vector2(-(GetConfig<LegacySkinConfiguration.LegacySetting, int>(LegacySkinConfiguration.LegacySetting.ScoreOverlap)?.Value ?? -2), 0)
};
} }
return null; return null;
@ -425,7 +440,7 @@ namespace osu.Game.Skinning
// Fall back to using the last piece for components coming from lazer (e.g. "Gameplay/osu/approachcircle" -> "approachcircle"). // Fall back to using the last piece for components coming from lazer (e.g. "Gameplay/osu/approachcircle" -> "approachcircle").
string lastPiece = componentName.Split('/').Last(); string lastPiece = componentName.Split('/').Last();
yield return componentName.StartsWith("Gameplay/taiko/") ? "taiko-" + lastPiece : lastPiece; yield return componentName.StartsWith("Gameplay/taiko/", StringComparison.Ordinal) ? "taiko-" + lastPiece : lastPiece;
} }
private IEnumerable<string> getLegacyLookupNames(HitSampleInfo hitSample) private IEnumerable<string> getLegacyLookupNames(HitSampleInfo hitSample)
@ -436,7 +451,7 @@ namespace osu.Game.Skinning
// for compatibility with stable, exclude the lookup names with the custom sample bank suffix, if they are not valid for use in this skin. // for compatibility with stable, exclude the lookup names with the custom sample bank suffix, if they are not valid for use in this skin.
// using .EndsWith() is intentional as it ensures parity in all edge cases // using .EndsWith() is intentional as it ensures parity in all edge cases
// (see LegacyTaikoSampleInfo for an example of one - prioritising the taiko prefix should still apply, but the sample bank should not). // (see LegacyTaikoSampleInfo for an example of one - prioritising the taiko prefix should still apply, but the sample bank should not).
lookupNames = hitSample.LookupNames.Where(name => !name.EndsWith(hitSample.Suffix)); lookupNames = hitSample.LookupNames.Where(name => !name.EndsWith(hitSample.Suffix, StringComparison.Ordinal));
// also for compatibility, try falling back to non-bank samples (so-called "universal" samples) as the last resort. // also for compatibility, try falling back to non-bank samples (so-called "universal" samples) as the last resort.
// going forward specifying banks shall always be required, even for elements that wouldn't require it on stable, // going forward specifying banks shall always be required, even for elements that wouldn't require it on stable,

View File

@ -17,6 +17,8 @@ namespace osu.Game.Skinning
Version, Version,
ComboPrefix, ComboPrefix,
ComboOverlap, ComboOverlap,
ScorePrefix,
ScoreOverlap,
AnimationFramerate, AnimationFramerate,
LayeredHitSounds LayeredHitSounds
} }

View File

@ -1,6 +1,7 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Threading.Tasks; using System.Threading.Tasks;
using Newtonsoft.Json; using Newtonsoft.Json;
@ -73,15 +74,15 @@ namespace osu.Game.Updater
switch (RuntimeInfo.OS) switch (RuntimeInfo.OS)
{ {
case RuntimeInfo.Platform.Windows: case RuntimeInfo.Platform.Windows:
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe")); bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe", StringComparison.Ordinal));
break; break;
case RuntimeInfo.Platform.MacOsx: case RuntimeInfo.Platform.MacOsx:
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip")); bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip", StringComparison.Ordinal));
break; break;
case RuntimeInfo.Platform.Linux: case RuntimeInfo.Platform.Linux:
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".AppImage")); bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".AppImage", StringComparison.Ordinal));
break; break;
case RuntimeInfo.Platform.iOS: case RuntimeInfo.Platform.iOS:

View File

@ -111,9 +111,6 @@ namespace osu.Game.Users
[JsonProperty(@"twitter")] [JsonProperty(@"twitter")]
public string Twitter; public string Twitter;
[JsonProperty(@"lastfm")]
public string Lastfm;
[JsonProperty(@"skype")] [JsonProperty(@"skype")]
public string Skype; public string Skype;

View File

@ -45,7 +45,7 @@ namespace osu.Game.Utils
// since we let unhandled exceptions go ignored at times, we want to ensure they don't get submitted on subsequent reports. // since we let unhandled exceptions go ignored at times, we want to ensure they don't get submitted on subsequent reports.
if (lastException != null && if (lastException != null &&
lastException.Message == exception.Message && exception.StackTrace.StartsWith(lastException.StackTrace)) lastException.Message == exception.Message && exception.StackTrace.StartsWith(lastException.StackTrace, StringComparison.Ordinal))
return; return;
lastException = exception; lastException = exception;

View File

@ -199,7 +199,9 @@
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E3/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E3/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E4/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=ReplaceWithSingleOrDefault_002E4/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SeparateControlTransferStatement/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SeparateControlTransferStatement/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringEndsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue">HINT</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringLiteralTypo/@EntryIndexedValue">HINT</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StringStartsWithIsCultureSpecific/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StructCanBeMadeReadOnly/@EntryIndexedValue">WARNING</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=StructCanBeMadeReadOnly/@EntryIndexedValue">WARNING</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FBuiltInTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
<s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String> <s:String x:Key="/Default/CodeInspection/Highlighting/InspectionSeverities/=SuggestVarOrType_005FSimpleTypes/@EntryIndexedValue">DO_NOT_SHOW</s:String>
@ -773,6 +775,7 @@ See the LICENCE file in the repository root for full licence text.&#xD;
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FFIELD/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String> <s:String x:Key="/Default/CodeStyle/Naming/XamlNaming/UserRules/=XAML_005FRESOURCE/@EntryIndexedValue">&lt;Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /&gt;</s:String>
<s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String> <s:String x:Key="/Default/CustomTools/CustomToolsData/@EntryValue"></s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EFeature_002EServices_002EDaemon_002ESettings_002EMigration_002ESwaWarningsModeSettingsMigrate/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpAttributeForSingleLineMethodUpgrade/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean> <s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>