mirror of
https://github.com/ppy/osu.git
synced 2024-11-11 11:20:04 +08:00
Merge branch 'master'
Conflicts: osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
This commit is contained in:
commit
c0bcbfd892
@ -2,7 +2,5 @@ clone_depth: 1
|
||||
version: '{branch}-{build}'
|
||||
image: Previous Visual Studio 2017
|
||||
test: off
|
||||
install:
|
||||
- cmd: git submodule update --init --recursive --depth=5
|
||||
build_script:
|
||||
- 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)
|
||||
{
|
||||
case "Gameplay/Catch/fruit-catcher-idle":
|
||||
case "Gameplay/catch/fruit-catcher-idle":
|
||||
return new CatcherCustomSkin();
|
||||
}
|
||||
|
||||
|
@ -143,7 +143,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
||||
// 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 string SampleNamespace => "Taiko";
|
||||
protected override string SampleNamespace => "taiko";
|
||||
|
||||
protected virtual TaikoPiece CreateMainPiece() => new CirclePiece();
|
||||
|
||||
|
@ -132,10 +132,10 @@ namespace osu.Game.Rulesets.Taiko.UI
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(TextureStore textures, OsuColour colours)
|
||||
{
|
||||
rim.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer");
|
||||
rimHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-outer-hit");
|
||||
centre.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner");
|
||||
centreHit.Texture = textures.Get(@"Gameplay/Taiko/taiko-drum-inner-hit");
|
||||
rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer");
|
||||
rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit");
|
||||
centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner");
|
||||
centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit");
|
||||
|
||||
rimHit.Colour = colours.Blue;
|
||||
centreHit.Colour = colours.Pink;
|
||||
|
@ -119,6 +119,53 @@ namespace osu.Game.Tests.Chat
|
||||
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]
|
||||
public void TestNewFormatLink()
|
||||
{
|
||||
@ -131,6 +178,42 @@ namespace osu.Game.Tests.Chat
|
||||
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]
|
||||
public void TestMarkdownFormatLink()
|
||||
{
|
||||
@ -143,6 +226,53 @@ namespace osu.Game.Tests.Chat
|
||||
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]
|
||||
public void TestChannelLink()
|
||||
{
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
@ -134,6 +135,48 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
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
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
private class SkinSourceContainer : Container, ISkin
|
||||
[Cached(typeof(ISkinSource))]
|
||||
private class SkinSourceContainer : Container, ISkinSource
|
||||
{
|
||||
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 IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) => throw new NotImplementedException();
|
||||
|
||||
public event Action SourceChanged;
|
||||
}
|
||||
|
||||
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("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 });
|
||||
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)
|
||||
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);
|
||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Beatmaps.Drawables
|
||||
Origin = Anchor.Centre,
|
||||
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)
|
||||
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 List<DatabasedSetting> databasedSettings;
|
||||
private List<DatabasedSetting> databasedSettings;
|
||||
|
||||
private readonly RulesetInfo ruleset;
|
||||
|
||||
private readonly bool legacySettingsExist;
|
||||
private bool legacySettingsExist;
|
||||
|
||||
protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int? variant = null)
|
||||
{
|
||||
@ -28,21 +28,31 @@ namespace osu.Game.Configuration
|
||||
this.ruleset = ruleset;
|
||||
this.variant = variant;
|
||||
|
||||
databasedSettings = settings.Query(ruleset?.ID, variant);
|
||||
legacySettingsExist = databasedSettings.Any(s => int.TryParse(s.Key, out var _));
|
||||
Load();
|
||||
|
||||
InitialiseDefaults();
|
||||
}
|
||||
|
||||
protected override void PerformLoad()
|
||||
{
|
||||
databasedSettings = settings.Query(ruleset?.ID, variant);
|
||||
legacySettingsExist = databasedSettings.Any(s => int.TryParse(s.Key, out var _));
|
||||
}
|
||||
|
||||
protected override bool PerformSave()
|
||||
{
|
||||
lock (dirtySettings)
|
||||
{
|
||||
foreach (var setting in dirtySettings)
|
||||
settings.Update(setting);
|
||||
dirtySettings.Clear();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private readonly List<DatabasedSetting> dirtySettings = new List<DatabasedSetting>();
|
||||
|
||||
protected override void AddBindable<TBindable>(T lookup, Bindable<TBindable> bindable)
|
||||
{
|
||||
base.AddBindable(lookup, bindable);
|
||||
@ -80,7 +90,12 @@ namespace osu.Game.Configuration
|
||||
bindable.ValueChanged += b =>
|
||||
{
|
||||
setting.Value = b.NewValue;
|
||||
settings.Update(setting);
|
||||
|
||||
lock (dirtySettings)
|
||||
{
|
||||
if (!dirtySettings.Contains(setting))
|
||||
dirtySettings.Add(setting);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace osu.Game.Online.Chat
|
||||
@ -10,16 +11,16 @@ namespace osu.Game.Online.Chat
|
||||
public static class MessageFormatter
|
||||
{
|
||||
// [[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)
|
||||
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)
|
||||
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
|
||||
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
|
||||
// This is in the format (<required>, [optional]):
|
||||
@ -48,7 +49,7 @@ namespace osu.Game.Online.Chat
|
||||
// Unicode emojis
|
||||
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;
|
||||
|
||||
@ -58,16 +59,20 @@ namespace osu.Game.Online.Chat
|
||||
|
||||
var displayText = string.Format(display,
|
||||
m.Groups[0],
|
||||
m.Groups.Count > 1 ? m.Groups[1].Value : "",
|
||||
m.Groups.Count > 2 ? m.Groups[2].Value : "").Trim();
|
||||
m.Groups["text"].Value,
|
||||
m.Groups["url"].Value).Trim();
|
||||
|
||||
var linkText = string.Format(link,
|
||||
m.Groups[0],
|
||||
m.Groups.Count > 1 ? m.Groups[1].Value : "",
|
||||
m.Groups.Count > 2 ? m.Groups[2].Value : "").Trim();
|
||||
m.Groups["text"].Value,
|
||||
m.Groups["url"].Value).Trim();
|
||||
|
||||
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
|
||||
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);
|
||||
|
||||
// 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
|
||||
handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex);
|
||||
handleMatches(markdown_link_regex, "{1}", "{2}", result, startIndex, escapeChars: new[] { '[', ']' });
|
||||
|
||||
// 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
|
||||
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.Sprites;
|
||||
using osu.Framework.Input.Bindings;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Overlays.Settings;
|
||||
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 IResourceStore<byte[]> CreateReourceStore() => new NamespacedResourceStore<byte[]>(new DllResourceStore(GetType().Assembly.Location), @"Resources");
|
||||
|
||||
public abstract string Description { get; }
|
||||
|
||||
public virtual RulesetSettingsSubsection CreateSettings() => null;
|
||||
|
@ -20,7 +20,12 @@ namespace osu.Game.Rulesets
|
||||
[JsonIgnore]
|
||||
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;
|
||||
|
||||
|
@ -14,10 +14,14 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.Cursor;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.Input;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Cursor;
|
||||
using osu.Game.Input.Handlers;
|
||||
@ -51,6 +55,10 @@ namespace osu.Game.Rulesets.UI
|
||||
|
||||
private readonly Lazy<Playfield> playfield;
|
||||
|
||||
private TextureStore textureStore;
|
||||
|
||||
private ISampleStore sampleStore;
|
||||
|
||||
/// <summary>
|
||||
/// The playfield.
|
||||
/// </summary>
|
||||
@ -142,6 +150,18 @@ namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
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>();
|
||||
|
||||
Config = dependencies.Get<RulesetConfigCache>().GetConfigFor(Ruleset);
|
||||
|
@ -6,6 +6,7 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Game.Audio;
|
||||
@ -20,7 +21,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
private SampleChannel[] channels;
|
||||
|
||||
private AudioManager audio;
|
||||
private ISampleStore samples;
|
||||
|
||||
public SkinnableSound(IEnumerable<ISampleInfo> hitSamples)
|
||||
{
|
||||
@ -33,9 +34,9 @@ namespace osu.Game.Skinning
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(AudioManager audio)
|
||||
private void load(ISampleStore samples)
|
||||
{
|
||||
this.audio = audio;
|
||||
this.samples = samples;
|
||||
}
|
||||
|
||||
private bool looping;
|
||||
@ -81,7 +82,7 @@ namespace osu.Game.Skinning
|
||||
|
||||
if (ch == null && allowFallback)
|
||||
foreach (var lookup in s.LookupNames)
|
||||
if ((ch = audio.Samples.Get($"Gameplay/{lookup}")) != null)
|
||||
if ((ch = samples.Get($"Gameplay/{lookup}")) != null)
|
||||
break;
|
||||
|
||||
if (ch != null)
|
||||
@ -102,8 +103,9 @@ namespace osu.Game.Skinning
|
||||
{
|
||||
base.Dispose(isDisposing);
|
||||
|
||||
foreach (var c in channels)
|
||||
c.Dispose();
|
||||
if (channels != null)
|
||||
foreach (var c in channels)
|
||||
c.Dispose();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -64,5 +64,11 @@ namespace osu.Game.Storyboards.Drawables
|
||||
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);
|
||||
|
||||
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)
|
||||
{
|
||||
|
@ -6,6 +6,17 @@
|
||||
<PlatformTarget>AnyCPU</PlatformTarget>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
</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">
|
||||
<Service Include="{82a7f48d-3b50-4b1e-b82e-3ada8210c358}" />
|
||||
</ItemGroup>
|
||||
|
Loading…
Reference in New Issue
Block a user