mirror of
https://github.com/osukey/osukey.git
synced 2025-07-22 19:00:05 +09:00
Merge branch 'master'
Conflicts: osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
This commit is contained in:
@ -2,7 +2,5 @@ clone_depth: 1
|
|||||||
version: '{branch}-{build}'
|
version: '{branch}-{build}'
|
||||||
image: Previous Visual Studio 2017
|
image: Previous Visual Studio 2017
|
||||||
test: off
|
test: off
|
||||||
install:
|
|
||||||
- cmd: git submodule update --init --recursive --depth=5
|
|
||||||
build_script:
|
build_script:
|
||||||
- cmd: PowerShell -Version 2.0 .\build.ps1
|
- cmd: PowerShell -Version 2.0 .\build.ps1
|
||||||
|
10
appveyor_deploy.yml
Normal file
10
appveyor_deploy.yml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
clone_depth: 1
|
||||||
|
version: '{build}'
|
||||||
|
image: Previous Visual Studio 2017
|
||||||
|
test: off
|
||||||
|
skip_non_tags: true
|
||||||
|
build_script:
|
||||||
|
- cmd: PowerShell -Version 2.0 .\build.ps1
|
||||||
|
deploy:
|
||||||
|
- provider: Environment
|
||||||
|
name: nuget
|
@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
switch (component.LookupName)
|
switch (component.LookupName)
|
||||||
{
|
{
|
||||||
case "Gameplay/Catch/fruit-catcher-idle":
|
case "Gameplay/catch/fruit-catcher-idle":
|
||||||
return new CatcherCustomSkin();
|
return new CatcherCustomSkin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
// Normal and clap samples are handled by the drum
|
// Normal and clap samples are handled by the drum
|
||||||
protected override IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
|
protected override IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
protected override string SampleNamespace => "Taiko";
|
protected override string SampleNamespace => "taiko";
|
||||||
|
|
||||||
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
||||||
|
|
||||||
|
@ -132,10 +132,10 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures, OsuColour colours)
|
private void load(TextureStore textures, OsuColour colours)
|
||||||
{
|
{
|
||||||
rim.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer");
|
rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer");
|
||||||
rimHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer-hit");
|
rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit");
|
||||||
centre.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner");
|
centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner");
|
||||||
centreHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner-hit");
|
centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit");
|
||||||
|
|
||||||
rimHit.Colour = colours.Blue;
|
rimHit.Colour = colours.Blue;
|
||||||
centreHit.Colour = colours.Pink;
|
centreHit.Colour = colours.Pink;
|
||||||
|
@ -119,6 +119,53 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(11, result.Links[0].Length);
|
Assert.AreEqual(11, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOldFormatLinkWithBalancedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a (tricky (one))[https://osu.ppy.sh]!" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a tricky (one)!", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(12, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOldFormatLinkWithEscapedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is (another loose bracket \\))[https://osu.ppy.sh]." });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is another loose bracket ).", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(8, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(23, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOldFormatWithBackslashes()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This link (should end with a backslash \\)[https://osu.ppy.sh]." });
|
||||||
|
Assert.AreEqual("This link should end with a backslash \\.", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(29, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOldFormatLinkWithEscapedAndBalancedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a (\\)super\\(\\( tricky (one))[https://osu.ppy.sh]!" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a )super(( tricky (one)!", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(21, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNewFormatLink()
|
public void TestNewFormatLink()
|
||||||
{
|
{
|
||||||
@ -131,6 +178,42 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(11, result.Links[0].Length);
|
Assert.AreEqual(11, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNewFormatLinkWithEscapedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [https://osu.ppy.sh nasty link with escaped brackets: \\] and \\[]" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a nasty link with escaped brackets: ] and [", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(41, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNewFormatLinkWithBackslashesInside()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [https://osu.ppy.sh link \\ with \\ backslashes \\]" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a link \\ with \\ backslashes \\", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(27, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNewFormatLinkWithEscapedAndBalancedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [https://osu.ppy.sh [link [with \\] too many brackets \\[ ]]]" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a [link [with ] too many brackets [ ]]", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(36, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMarkdownFormatLink()
|
public void TestMarkdownFormatLink()
|
||||||
{
|
{
|
||||||
@ -143,6 +226,53 @@ namespace osu.Game.Tests.Chat
|
|||||||
Assert.AreEqual(11, result.Links[0].Length);
|
Assert.AreEqual(11, result.Links[0].Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMarkdownFormatLinkWithBalancedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [tricky [one]](https://osu.ppy.sh)!" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a tricky [one]!", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(12, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMarkdownFormatLinkWithEscapedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is [another loose bracket \\]](https://osu.ppy.sh)." });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is another loose bracket ].", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(8, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(23, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMarkdownFormatWithBackslashes()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This link [should end with a backslash \\](https://osu.ppy.sh)." });
|
||||||
|
Assert.AreEqual("This link should end with a backslash \\.", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(29, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMarkdownFormatLinkWithEscapedAndBalancedBrackets()
|
||||||
|
{
|
||||||
|
Message result = MessageFormatter.FormatMessage(new Message { Content = "This is a [\\]super\\[\\[ tricky [one]](https://osu.ppy.sh)!" });
|
||||||
|
|
||||||
|
Assert.AreEqual("This is a ]super[[ tricky [one]!", result.DisplayContent);
|
||||||
|
Assert.AreEqual(1, result.Links.Count);
|
||||||
|
Assert.AreEqual("https://osu.ppy.sh", result.Links[0].Url);
|
||||||
|
Assert.AreEqual(10, result.Links[0].Index);
|
||||||
|
Assert.AreEqual(21, result.Links[0].Length);
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestChannelLink()
|
public void TestChannelLink()
|
||||||
{
|
{
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -134,6 +135,48 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
|
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSwitchOff()
|
||||||
|
{
|
||||||
|
SkinConsumer consumer = null;
|
||||||
|
SwitchableSkinProvidingContainer target = null;
|
||||||
|
|
||||||
|
AddStep("setup layout", () =>
|
||||||
|
{
|
||||||
|
Child = new SkinSourceContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = target = new SwitchableSkinProvidingContainer(new SecondarySource())
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"), source => true)));
|
||||||
|
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
||||||
|
AddStep("disable", () => target.Disable());
|
||||||
|
AddAssert("consumer using base source", () => consumer.Drawable is BaseSourceBox);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SwitchableSkinProvidingContainer : SkinProvidingContainer
|
||||||
|
{
|
||||||
|
private bool allow = true;
|
||||||
|
|
||||||
|
protected override bool AllowDrawableLookup(ISkinComponent component) => allow;
|
||||||
|
|
||||||
|
public void Disable()
|
||||||
|
{
|
||||||
|
allow = false;
|
||||||
|
TriggerSourceChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
public SwitchableSkinProvidingContainer(ISkin skin)
|
||||||
|
: base(skin)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class ExposedSkinnableDrawable : SkinnableDrawable
|
private class ExposedSkinnableDrawable : SkinnableDrawable
|
||||||
{
|
{
|
||||||
public new Drawable Drawable => base.Drawable;
|
public new Drawable Drawable => base.Drawable;
|
||||||
@ -272,7 +315,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SkinSourceContainer : Container, ISkin
|
[Cached(typeof(ISkinSource))]
|
||||||
|
private class SkinSourceContainer : Container, ISkinSource
|
||||||
{
|
{
|
||||||
public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox();
|
public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox();
|
||||||
|
|
||||||
@ -281,6 +325,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
public SampleChannel GetSample(ISampleInfo sampleInfo) => throw new NotImplementedException();
|
||||||
|
|
||||||
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public event Action SourceChanged;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestSkinComponent : ISkinComponent
|
private class TestSkinComponent : ISkinComponent
|
||||||
|
@ -127,6 +127,9 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
addMessageWithChecks("is now playing [https://osu.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", 1, true, expectedActions: LinkAction.OpenBeatmap);
|
addMessageWithChecks("is now playing [https://osu.ppy.sh/b/252238 IMAGE -MATERIAL- <Version 0>]", 1, true, expectedActions: LinkAction.OpenBeatmap);
|
||||||
addMessageWithChecks("Let's (try)[https://osu.ppy.sh/home] [https://osu.ppy.sh/b/252238 multiple links] https://osu.ppy.sh/home", 3,
|
addMessageWithChecks("Let's (try)[https://osu.ppy.sh/home] [https://osu.ppy.sh/b/252238 multiple links] https://osu.ppy.sh/home", 3,
|
||||||
expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External });
|
expectedActions: new[] { LinkAction.External, LinkAction.OpenBeatmap, LinkAction.External });
|
||||||
|
addMessageWithChecks("[https://osu.ppy.sh/home New link format with escaped [and \\[ paired] braces]", 1, expectedActions: LinkAction.External);
|
||||||
|
addMessageWithChecks("[Markdown link format with escaped [and \\[ paired] braces](https://osu.ppy.sh/home)", 1, expectedActions: LinkAction.External);
|
||||||
|
addMessageWithChecks("(Old link format with escaped (and \\( paired) parentheses)[https://osu.ppy.sh/home] and [[also a rogue wiki link]]", 2, expectedActions: new[] { LinkAction.External, LinkAction.External });
|
||||||
// note that there's 0 links here (they get removed if a channel is not found)
|
// note that there's 0 links here (they get removed if a channel is not found)
|
||||||
addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).");
|
addMessageWithChecks("#lobby or #osu would be blue (and work) in the ChatDisplay test (when a proper ChatOverlay is present).");
|
||||||
addMessageWithChecks("I am important!", 0, false, true);
|
addMessageWithChecks("I am important!", 0, false, true);
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
// the null coalesce here is only present to make unit tests work (ruleset dlls aren't copied correctly for testing at the moment)
|
||||||
Icon = ruleset?.CreateInstance().CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }
|
Icon = ruleset?.CreateInstance()?.CreateIcon() ?? new SpriteIcon { Icon = FontAwesome.Regular.QuestionCircle }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -16,11 +16,11 @@ namespace osu.Game.Configuration
|
|||||||
|
|
||||||
private readonly int? variant;
|
private readonly int? variant;
|
||||||
|
|
||||||
private readonly List<DatabasedSetting> databasedSettings;
|
private List<DatabasedSetting> databasedSettings;
|
||||||
|
|
||||||
private readonly RulesetInfo ruleset;
|
private readonly RulesetInfo ruleset;
|
||||||
|
|
||||||
private readonly bool legacySettingsExist;
|
private bool legacySettingsExist;
|
||||||
|
|
||||||
protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int? variant = null)
|
protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int? variant = null)
|
||||||
{
|
{
|
||||||
@ -28,21 +28,31 @@ namespace osu.Game.Configuration
|
|||||||
this.ruleset = ruleset;
|
this.ruleset = ruleset;
|
||||||
this.variant = variant;
|
this.variant = variant;
|
||||||
|
|
||||||
databasedSettings = settings.Query(ruleset?.ID, variant);
|
Load();
|
||||||
legacySettingsExist = databasedSettings.Any(s => int.TryParse(s.Key, out var _));
|
|
||||||
|
|
||||||
InitialiseDefaults();
|
InitialiseDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void PerformLoad()
|
protected override void PerformLoad()
|
||||||
{
|
{
|
||||||
|
databasedSettings = settings.Query(ruleset?.ID, variant);
|
||||||
|
legacySettingsExist = databasedSettings.Any(s => int.TryParse(s.Key, out var _));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool PerformSave()
|
protected override bool PerformSave()
|
||||||
{
|
{
|
||||||
|
lock (dirtySettings)
|
||||||
|
{
|
||||||
|
foreach (var setting in dirtySettings)
|
||||||
|
settings.Update(setting);
|
||||||
|
dirtySettings.Clear();
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private readonly List<DatabasedSetting> dirtySettings = new List<DatabasedSetting>();
|
||||||
|
|
||||||
protected override void AddBindable<TBindable>(T lookup, Bindable<TBindable> bindable)
|
protected override void AddBindable<TBindable>(T lookup, Bindable<TBindable> bindable)
|
||||||
{
|
{
|
||||||
base.AddBindable(lookup, bindable);
|
base.AddBindable(lookup, bindable);
|
||||||
@ -80,7 +90,12 @@ namespace osu.Game.Configuration
|
|||||||
bindable.ValueChanged += b =>
|
bindable.ValueChanged += b =>
|
||||||
{
|
{
|
||||||
setting.Value = b.NewValue;
|
setting.Value = b.NewValue;
|
||||||
settings.Update(setting);
|
|
||||||
|
lock (dirtySettings)
|
||||||
|
{
|
||||||
|
if (!dirtySettings.Contains(setting))
|
||||||
|
dirtySettings.Add(setting);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Text.RegularExpressions;
|
using System.Text.RegularExpressions;
|
||||||
|
|
||||||
namespace osu.Game.Online.Chat
|
namespace osu.Game.Online.Chat
|
||||||
@ -10,16 +11,16 @@ namespace osu.Game.Online.Chat
|
|||||||
public static class MessageFormatter
|
public static class MessageFormatter
|
||||||
{
|
{
|
||||||
// [[Performance Points]] -> wiki:Performance Points (https://osu.ppy.sh/wiki/Performance_Points)
|
// [[Performance Points]] -> wiki:Performance Points (https://osu.ppy.sh/wiki/Performance_Points)
|
||||||
private static readonly Regex wiki_regex = new Regex(@"\[\[([^\]]+)\]\]");
|
private static readonly Regex wiki_regex = new Regex(@"\[\[(?<text>[^\]]+)\]\]");
|
||||||
|
|
||||||
// (test)[https://osu.ppy.sh/b/1234] -> test (https://osu.ppy.sh/b/1234)
|
// (test)[https://osu.ppy.sh/b/1234] -> test (https://osu.ppy.sh/b/1234)
|
||||||
private static readonly Regex old_link_regex = new Regex(@"\(([^\)]*)\)\[([a-z]+://[^ ]+)\]");
|
private static readonly Regex old_link_regex = new Regex(@"\((?<text>(((?<=\\)[\(\)])|[^\(\)])*(((?<open>\()(((?<=\\)[\(\)])|[^\(\)])*)+((?<close-open>\))(((?<=\\)[\(\)])|[^\(\)])*)+)*(?(open)(?!)))\)\[(?<url>[a-z]+://[^ ]+)\]");
|
||||||
|
|
||||||
// [https://osu.ppy.sh/b/1234 Beatmap [Hard] (poop)] -> Beatmap [hard] (poop) (https://osu.ppy.sh/b/1234)
|
// [https://osu.ppy.sh/b/1234 Beatmap [Hard] (poop)] -> Beatmap [hard] (poop) (https://osu.ppy.sh/b/1234)
|
||||||
private static readonly Regex new_link_regex = new Regex(@"\[([a-z]+://[^ ]+) ([^\[\]]*(((?<open>\[)[^\[\]]*)+((?<close-open>\])[^\[\]]*)+)*(?(open)(?!)))\]");
|
private static readonly Regex new_link_regex = new Regex(@"\[(?<url>[a-z]+://[^ ]+) (?<text>(((?<=\\)[\[\]])|[^\[\]])*(((?<open>\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?<close-open>\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]");
|
||||||
|
|
||||||
// [test](https://osu.ppy.sh/b/1234) -> test (https://osu.ppy.sh/b/1234) aka correct markdown format
|
// [test](https://osu.ppy.sh/b/1234) -> test (https://osu.ppy.sh/b/1234) aka correct markdown format
|
||||||
private static readonly Regex markdown_link_regex = new Regex(@"\[([^\]]*)\]\(([a-z]+://[^ ]+)\)");
|
private static readonly Regex markdown_link_regex = new Regex(@"\[(?<text>(((?<=\\)[\[\]])|[^\[\]])*(((?<open>\[)(((?<=\\)[\[\]])|[^\[\]])*)+((?<close-open>\])(((?<=\\)[\[\]])|[^\[\]])*)+)*(?(open)(?!)))\]\((?<url>[a-z]+://[^ ]+)\)");
|
||||||
|
|
||||||
// advanced, RFC-compatible regular expression that matches any possible URL, *but* allows certain invalid characters that are widely used
|
// advanced, RFC-compatible regular expression that matches any possible URL, *but* allows certain invalid characters that are widely used
|
||||||
// This is in the format (<required>, [optional]):
|
// This is in the format (<required>, [optional]):
|
||||||
@ -48,7 +49,7 @@ namespace osu.Game.Online.Chat
|
|||||||
// Unicode emojis
|
// Unicode emojis
|
||||||
private static readonly Regex emoji_regex = new Regex(@"(\uD83D[\uDC00-\uDE4F])");
|
private static readonly Regex emoji_regex = new Regex(@"(\uD83D[\uDC00-\uDE4F])");
|
||||||
|
|
||||||
private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null)
|
private static void handleMatches(Regex regex, string display, string link, MessageFormatterResult result, int startIndex = 0, LinkAction? linkActionOverride = null, char[] escapeChars = null)
|
||||||
{
|
{
|
||||||
int captureOffset = 0;
|
int captureOffset = 0;
|
||||||
|
|
||||||
@ -58,16 +59,20 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
var displayText = string.Format(display,
|
var displayText = string.Format(display,
|
||||||
m.Groups[0],
|
m.Groups[0],
|
||||||
m.Groups.Count > 1 ? m.Groups[1].Value : "",
|
m.Groups["text"].Value,
|
||||||
m.Groups.Count > 2 ? m.Groups[2].Value : "").Trim();
|
m.Groups["url"].Value).Trim();
|
||||||
|
|
||||||
var linkText = string.Format(link,
|
var linkText = string.Format(link,
|
||||||
m.Groups[0],
|
m.Groups[0],
|
||||||
m.Groups.Count > 1 ? m.Groups[1].Value : "",
|
m.Groups["text"].Value,
|
||||||
m.Groups.Count > 2 ? m.Groups[2].Value : "").Trim();
|
m.Groups["url"].Value).Trim();
|
||||||
|
|
||||||
if (displayText.Length == 0 || linkText.Length == 0) continue;
|
if (displayText.Length == 0 || linkText.Length == 0) continue;
|
||||||
|
|
||||||
|
// Remove backslash escapes in front of the characters provided in escapeChars
|
||||||
|
if (escapeChars != null)
|
||||||
|
displayText = escapeChars.Aggregate(displayText, (current, c) => current.Replace($"\\{c}", c.ToString()));
|
||||||
|
|
||||||
// Check for encapsulated links
|
// Check for encapsulated links
|
||||||
if (result.Links.Find(l => (l.Index <= index && l.Index + l.Length >= index + m.Length) || (index <= l.Index && index + m.Length >= l.Index + l.Length)) == null)
|
if (result.Links.Find(l => (l.Index <= index && l.Index + l.Length >= index + m.Length) || (index <= l.Index && index + m.Length >= l.Index + l.Length)) == null)
|
||||||
{
|
{
|
||||||
@ -183,13 +188,13 @@ namespace osu.Game.Online.Chat
|
|||||||
var result = new MessageFormatterResult(toFormat);
|
var result = new MessageFormatterResult(toFormat);
|
||||||
|
|
||||||
// handle the [link display] format
|
// handle the [link display] format
|
||||||
handleMatches(new_link_regex, "{2}", "{1}", result, startIndex);
|
handleMatches(new_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' });
|
||||||
|
|
||||||
// handle the standard markdown []() format
|
// handle the standard markdown []() format
|
||||||
handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex);
|
handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' });
|
||||||
|
|
||||||
// handle the ()[] link format
|
// handle the ()[] link format
|
||||||
handleMatches(old_link_regex, "{1}", "{2}", result, startIndex);
|
handleMatches(old_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '(', ')' });
|
||||||
|
|
||||||
// handle wiki links
|
// handle wiki links
|
||||||
handleMatches(wiki_regex, "{1}", "https://osu.ppy.sh/wiki/{1}", result, startIndex);
|
handleMatches(wiki_regex, "{1}", "https://osu.ppy.sh/wiki/{1}", result, startIndex);
|
||||||
|
@ -7,6 +7,7 @@ using System.Linq;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
@ -83,6 +84,8 @@ namespace osu.Game.Rulesets
|
|||||||
|
|
||||||
public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.Solid.QuestionCircle };
|
public virtual Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.Solid.QuestionCircle };
|
||||||
|
|
||||||
|
public virtual IResourceStore<byte[]> CreateReourceStore() => new NamespacedResourceStore<byte[]>(new DllResourceStore(GetType().Assembly.Location), @"Resources");
|
||||||
|
|
||||||
public abstract string Description { get; }
|
public abstract string Description { get; }
|
||||||
|
|
||||||
public virtual RulesetSettingsSubsection CreateSettings() => null;
|
public virtual RulesetSettingsSubsection CreateSettings() => null;
|
||||||
|
@ -20,7 +20,12 @@ namespace osu.Game.Rulesets
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public bool Available { get; set; }
|
public bool Available { get; set; }
|
||||||
|
|
||||||
public virtual Ruleset CreateInstance() => (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this);
|
public virtual Ruleset CreateInstance()
|
||||||
|
{
|
||||||
|
if (!Available) return null;
|
||||||
|
|
||||||
|
return (Ruleset)Activator.CreateInstance(Type.GetType(InstantiationInfo), this);
|
||||||
|
}
|
||||||
|
|
||||||
public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
|
public bool Equals(RulesetInfo other) => other != null && ID == other.ID && Available == other.Available && Name == other.Name && InstantiationInfo == other.InstantiationInfo;
|
||||||
|
|
||||||
|
@ -14,10 +14,14 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
using osu.Game.Input.Handlers;
|
using osu.Game.Input.Handlers;
|
||||||
@ -51,6 +55,10 @@ namespace osu.Game.Rulesets.UI
|
|||||||
|
|
||||||
private readonly Lazy<Playfield> playfield;
|
private readonly Lazy<Playfield> playfield;
|
||||||
|
|
||||||
|
private TextureStore textureStore;
|
||||||
|
|
||||||
|
private ISampleStore sampleStore;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The playfield.
|
/// The playfield.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@ -142,6 +150,18 @@ namespace osu.Game.Rulesets.UI
|
|||||||
{
|
{
|
||||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
|
||||||
|
var resources = Ruleset.CreateReourceStore();
|
||||||
|
|
||||||
|
if (resources != null)
|
||||||
|
{
|
||||||
|
textureStore = new TextureStore(new TextureLoaderStore(new NamespacedResourceStore<byte[]>(resources, "Textures")));
|
||||||
|
textureStore.AddStore(dependencies.Get<TextureStore>());
|
||||||
|
dependencies.Cache(textureStore);
|
||||||
|
|
||||||
|
sampleStore = dependencies.Get<AudioManager>().GetSampleStore(new NamespacedResourceStore<byte[]>(resources, "Samples"));
|
||||||
|
dependencies.CacheAs(sampleStore);
|
||||||
|
}
|
||||||
|
|
||||||
onScreenDisplay = dependencies.Get<OnScreenDisplay>();
|
onScreenDisplay = dependencies.Get<OnScreenDisplay>();
|
||||||
|
|
||||||
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Sample;
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -20,7 +21,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private SampleChannel[] channels;
|
private SampleChannel[] channels;
|
||||||
|
|
||||||
private AudioManager audio;
|
private ISampleStore samples;
|
||||||
|
|
||||||
public SkinnableSound(IEnumerable<ISampleInfo> hitSamples)
|
public SkinnableSound(IEnumerable<ISampleInfo> hitSamples)
|
||||||
{
|
{
|
||||||
@ -33,9 +34,9 @@ namespace osu.Game.Skinning
|
|||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio)
|
private void load(ISampleStore samples)
|
||||||
{
|
{
|
||||||
this.audio = audio;
|
this.samples = samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool looping;
|
private bool looping;
|
||||||
@ -81,7 +82,7 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
if (ch == null && allowFallback)
|
if (ch == null && allowFallback)
|
||||||
foreach (var lookup in s.LookupNames)
|
foreach (var lookup in s.LookupNames)
|
||||||
if ((ch = audio.Samples.Get($"Gameplay/{lookup}")) != null)
|
if ((ch = samples.Get($"Gameplay/{lookup}")) != null)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (ch != null)
|
if (ch != null)
|
||||||
@ -102,8 +103,9 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
foreach (var c in channels)
|
if (channels != null)
|
||||||
c.Dispose();
|
foreach (var c in channels)
|
||||||
|
c.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,5 +64,11 @@ namespace osu.Game.Storyboards.Drawables
|
|||||||
LifetimeEnd = sampleInfo.StartTime;
|
LifetimeEnd = sampleInfo.StartTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
channel?.Stop();
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,11 @@ namespace osu.Game.Tests.Visual
|
|||||||
Beatmap.Value = CreateWorkingBeatmap(beatmap);
|
Beatmap.Value = CreateWorkingBeatmap(beatmap);
|
||||||
|
|
||||||
if (!AllowFail)
|
if (!AllowFail)
|
||||||
Mods.Value = new[] { ruleset.GetAllMods().First(m => m is ModNoFail) };
|
{
|
||||||
|
var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail);
|
||||||
|
if (noFailMod != null)
|
||||||
|
Mods.Value = new[] { noFailMod };
|
||||||
|
}
|
||||||
|
|
||||||
if (Autoplay)
|
if (Autoplay)
|
||||||
{
|
{
|
||||||
|
@ -6,6 +6,17 @@
|
|||||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Label="Nuget">
|
||||||
|
<Title>osu!</Title>
|
||||||
|
<PackageId>ppy.osu.Game</PackageId>
|
||||||
|
<Authors>ppy Pty Ltd</Authors>
|
||||||
|
<PackageLicenseUrl>https://github.com/ppy/osu/blob/master/LICENCE.md</PackageLicenseUrl>
|
||||||
|
<PackageProjectUrl>https://github.com/ppy/osu</PackageProjectUrl>
|
||||||
|
<RepositoryUrl>https://github.com/ppy/osu</RepositoryUrl>
|
||||||
|
<PackageReleaseNotes>Automated release.</PackageReleaseNotes>
|
||||||
|
<copyright>Copyright (c) 2019 ppy Pty Ltd</copyright>
|
||||||
|
<PackageTags>osu game</PackageTags>
|
||||||
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Service">
|
<ItemGroup Label="Service">
|
||||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
Reference in New Issue
Block a user