mirror of
https://github.com/ppy/osu.git
synced 2024-11-19 01:03:02 +08:00
Merge branch 'master' into osu-random-mod-improvements
This commit is contained in:
commit
ac7b9b9663
@ -195,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private void addSeekStep(double time)
|
private void addSeekStep(double time)
|
||||||
{
|
{
|
||||||
AddStep($"seek to {time}", () => MusicController.SeekTo(time));
|
AddStep($"seek to {time}", () => Player.GameplayClockContainer.Seek(time));
|
||||||
|
|
||||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||||
}
|
}
|
||||||
|
@ -217,7 +217,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private void addSeekStep(double time)
|
private void addSeekStep(double time)
|
||||||
{
|
{
|
||||||
AddStep($"seek to {time}", () => MusicController.SeekTo(time));
|
AddStep($"seek to {time}", () => Player.GameplayClockContainer.Seek(time));
|
||||||
|
|
||||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,9 @@ using osu.Game.Database;
|
|||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
|
using osu.Game.Tests.Scores.IO;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using SharpCompress.Archives;
|
using SharpCompress.Archives;
|
||||||
using SharpCompress.Archives.Zip;
|
using SharpCompress.Archives.Zip;
|
||||||
@ -185,10 +187,58 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private string hashFile(string filename)
|
[Test]
|
||||||
|
public async Task TestImportThenImportWithChangedHashedFile()
|
||||||
{
|
{
|
||||||
using (var s = File.OpenRead(filename))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost(nameof(ImportBeatmapTest)))
|
||||||
return s.ComputeMD5Hash();
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var osu = LoadOsuIntoHost(host);
|
||||||
|
|
||||||
|
var temp = TestResources.GetTestBeatmapForImport();
|
||||||
|
|
||||||
|
string extractedFolder = $"{temp}_extracted";
|
||||||
|
Directory.CreateDirectory(extractedFolder);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
|
await createScoreForBeatmap(osu, imported.Beatmaps.First());
|
||||||
|
|
||||||
|
using (var zip = ZipArchive.Open(temp))
|
||||||
|
zip.WriteToDirectory(extractedFolder);
|
||||||
|
|
||||||
|
// arbitrary write to hashed file
|
||||||
|
// this triggers the special BeatmapManager.PreImport deletion/replacement flow.
|
||||||
|
using (var sw = new FileInfo(Directory.GetFiles(extractedFolder, "*.osu").First()).AppendText())
|
||||||
|
await sw.WriteLineAsync("// changed");
|
||||||
|
|
||||||
|
using (var zip = ZipArchive.Create())
|
||||||
|
{
|
||||||
|
zip.AddAllFromDirectory(extractedFolder);
|
||||||
|
zip.SaveTo(temp, new ZipWriterOptions(CompressionType.Deflate));
|
||||||
|
}
|
||||||
|
|
||||||
|
var importedSecondTime = await osu.Dependencies.Get<BeatmapManager>().Import(new ImportTask(temp));
|
||||||
|
|
||||||
|
ensureLoaded(osu);
|
||||||
|
|
||||||
|
// check the newly "imported" beatmap is not the original.
|
||||||
|
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||||
|
Assert.IsTrue(imported.Beatmaps.First().ID != importedSecondTime.Beatmaps.First().ID);
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
Directory.Delete(extractedFolder, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
host.Exit();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -894,7 +944,17 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
|
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBeatmapSetCount(OsuGameBase osu, int expected, bool includeDeletePending = false)
|
private static Task createScoreForBeatmap(OsuGameBase osu, BeatmapInfo beatmap)
|
||||||
|
{
|
||||||
|
return ImportScoreTest.LoadScoreIntoOsu(osu, new ScoreInfo
|
||||||
|
{
|
||||||
|
OnlineScoreID = 2,
|
||||||
|
Beatmap = beatmap,
|
||||||
|
BeatmapInfoID = beatmap.ID
|
||||||
|
}, new ImportScoreTest.TestArchiveReader());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkBeatmapSetCount(OsuGameBase osu, int expected, bool includeDeletePending = false)
|
||||||
{
|
{
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
@ -903,12 +963,18 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
: manager.GetAllUsableBeatmapSets().Count);
|
: manager.GetAllUsableBeatmapSets().Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBeatmapCount(OsuGameBase osu, int expected)
|
private static string hashFile(string filename)
|
||||||
|
{
|
||||||
|
using (var s = File.OpenRead(filename))
|
||||||
|
return s.ComputeMD5Hash();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void checkBeatmapCount(OsuGameBase osu, int expected)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(expected, osu.Dependencies.Get<BeatmapManager>().QueryBeatmaps(_ => true).ToList().Count);
|
Assert.AreEqual(expected, osu.Dependencies.Get<BeatmapManager>().QueryBeatmaps(_ => true).ToList().Count);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkSingleReferencedFileCount(OsuGameBase osu, int expected)
|
private static void checkSingleReferencedFileCount(OsuGameBase osu, int expected)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(expected, osu.Dependencies.Get<FileStore>().QueryFiles(f => f.ReferenceCount == 1).Count());
|
Assert.AreEqual(expected, osu.Dependencies.Get<FileStore>().QueryFiles(f => f.ReferenceCount == 1).Count());
|
||||||
}
|
}
|
||||||
|
105
osu.Game.Tests/Chat/TestSceneChannelManager.cs
Normal file
105
osu.Game.Tests/Chat/TestSceneChannelManager.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Online.API.Requests;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using osu.Game.Users;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Chat
|
||||||
|
{
|
||||||
|
[HeadlessTest]
|
||||||
|
public class TestSceneChannelManager : OsuTestScene
|
||||||
|
{
|
||||||
|
private ChannelManager channelManager;
|
||||||
|
private int currentMessageId;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
var container = new ChannelManagerContainer();
|
||||||
|
Child = container;
|
||||||
|
channelManager = container.ChannelManager;
|
||||||
|
});
|
||||||
|
|
||||||
|
[SetUpSteps]
|
||||||
|
public void SetUpSteps()
|
||||||
|
{
|
||||||
|
AddStep("register request handling", () =>
|
||||||
|
{
|
||||||
|
currentMessageId = 0;
|
||||||
|
|
||||||
|
((DummyAPIAccess)API).HandleRequest = req =>
|
||||||
|
{
|
||||||
|
switch (req)
|
||||||
|
{
|
||||||
|
case JoinChannelRequest joinChannel:
|
||||||
|
joinChannel.TriggerSuccess();
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case PostMessageRequest postMessage:
|
||||||
|
postMessage.TriggerSuccess(new Message(++currentMessageId)
|
||||||
|
{
|
||||||
|
IsAction = postMessage.Message.IsAction,
|
||||||
|
ChannelId = postMessage.Message.ChannelId,
|
||||||
|
Content = postMessage.Message.Content,
|
||||||
|
Links = postMessage.Message.Links,
|
||||||
|
Timestamp = postMessage.Message.Timestamp,
|
||||||
|
Sender = postMessage.Message.Sender
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCommandsPostedToCorrectChannelWhenNotCurrent()
|
||||||
|
{
|
||||||
|
Channel channel1 = null;
|
||||||
|
Channel channel2 = null;
|
||||||
|
|
||||||
|
AddStep("join 2 rooms", () =>
|
||||||
|
{
|
||||||
|
channelManager.JoinChannel(channel1 = createChannel(1, ChannelType.Public));
|
||||||
|
channelManager.JoinChannel(channel2 = createChannel(2, ChannelType.Public));
|
||||||
|
});
|
||||||
|
|
||||||
|
AddStep("select channel 1", () => channelManager.CurrentChannel.Value = channel1);
|
||||||
|
|
||||||
|
AddStep("post /me command to channel 2", () => channelManager.PostCommand("me dances", channel2));
|
||||||
|
AddAssert("/me command received by channel 2", () => channel2.Messages.Last().Content == "dances");
|
||||||
|
|
||||||
|
AddStep("post /np command to channel 2", () => channelManager.PostCommand("np", channel2));
|
||||||
|
AddAssert("/np command received by channel 2", () => channel2.Messages.Last().Content.Contains("is listening to"));
|
||||||
|
}
|
||||||
|
|
||||||
|
private Channel createChannel(int id, ChannelType type) => new Channel(new User())
|
||||||
|
{
|
||||||
|
Id = id,
|
||||||
|
Name = $"Channel {id}",
|
||||||
|
Topic = $"Topic of channel {id} with type {type}",
|
||||||
|
Type = type,
|
||||||
|
};
|
||||||
|
|
||||||
|
private class ChannelManagerContainer : CompositeDrawable
|
||||||
|
{
|
||||||
|
[Cached]
|
||||||
|
public ChannelManager ChannelManager { get; } = new ChannelManager();
|
||||||
|
|
||||||
|
public ChannelManagerContainer()
|
||||||
|
{
|
||||||
|
InternalChild = ChannelManager;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,7 +17,8 @@ namespace osu.Game.Tests
|
|||||||
protected virtual TestOsuGameBase LoadOsuIntoHost(GameHost host, bool withBeatmap = false)
|
protected virtual TestOsuGameBase LoadOsuIntoHost(GameHost host, bool withBeatmap = false)
|
||||||
{
|
{
|
||||||
var osu = new TestOsuGameBase(withBeatmap);
|
var osu = new TestOsuGameBase(withBeatmap);
|
||||||
Task.Run(() => host.Run(osu));
|
Task.Run(() => host.Run(osu))
|
||||||
|
.ContinueWith(t => Assert.Fail($"Host threw exception {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted);
|
||||||
|
|
||||||
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
OnlineScoreID = 12345,
|
OnlineScoreID = 12345,
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = await loadScoreIntoOsu(osu, toImport);
|
var imported = await LoadScoreIntoOsu(osu, toImport);
|
||||||
|
|
||||||
Assert.AreEqual(toImport.Rank, imported.Rank);
|
Assert.AreEqual(toImport.Rank, imported.Rank);
|
||||||
Assert.AreEqual(toImport.TotalScore, imported.TotalScore);
|
Assert.AreEqual(toImport.TotalScore, imported.TotalScore);
|
||||||
@ -75,7 +75,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = await loadScoreIntoOsu(osu, toImport);
|
var imported = await LoadScoreIntoOsu(osu, toImport);
|
||||||
|
|
||||||
Assert.IsTrue(imported.Mods.Any(m => m is OsuModHardRock));
|
Assert.IsTrue(imported.Mods.Any(m => m is OsuModHardRock));
|
||||||
Assert.IsTrue(imported.Mods.Any(m => m is OsuModDoubleTime));
|
Assert.IsTrue(imported.Mods.Any(m => m is OsuModDoubleTime));
|
||||||
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = await loadScoreIntoOsu(osu, toImport);
|
var imported = await LoadScoreIntoOsu(osu, toImport);
|
||||||
|
|
||||||
Assert.AreEqual(toImport.Statistics[HitResult.Perfect], imported.Statistics[HitResult.Perfect]);
|
Assert.AreEqual(toImport.Statistics[HitResult.Perfect], imported.Statistics[HitResult.Perfect]);
|
||||||
Assert.AreEqual(toImport.Statistics[HitResult.Miss], imported.Statistics[HitResult.Miss]);
|
Assert.AreEqual(toImport.Statistics[HitResult.Miss], imported.Statistics[HitResult.Miss]);
|
||||||
@ -136,7 +136,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = await loadScoreIntoOsu(osu, toImport);
|
var imported = await LoadScoreIntoOsu(osu, toImport);
|
||||||
|
|
||||||
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||||
@ -144,7 +144,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
beatmapManager.Delete(beatmapManager.QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == imported.Beatmap.ID)));
|
beatmapManager.Delete(beatmapManager.QueryBeatmapSet(s => s.Beatmaps.Any(b => b.ID == imported.Beatmap.ID)));
|
||||||
Assert.That(scoreManager.Query(s => s.ID == imported.ID).DeletePending, Is.EqualTo(true));
|
Assert.That(scoreManager.Query(s => s.ID == imported.ID).DeletePending, Is.EqualTo(true));
|
||||||
|
|
||||||
var secondImport = await loadScoreIntoOsu(osu, imported);
|
var secondImport = await LoadScoreIntoOsu(osu, imported);
|
||||||
Assert.That(secondImport, Is.Null);
|
Assert.That(secondImport, Is.Null);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
@ -163,7 +163,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
{
|
{
|
||||||
var osu = LoadOsuIntoHost(host, true);
|
var osu = LoadOsuIntoHost(host, true);
|
||||||
|
|
||||||
await loadScoreIntoOsu(osu, new ScoreInfo { OnlineScoreID = 2 }, new TestArchiveReader());
|
await LoadScoreIntoOsu(osu, new ScoreInfo { OnlineScoreID = 2 }, new TestArchiveReader());
|
||||||
|
|
||||||
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||||
|
|
||||||
@ -177,7 +177,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task<ScoreInfo> loadScoreIntoOsu(OsuGameBase osu, ScoreInfo score, ArchiveReader archive = null)
|
public static async Task<ScoreInfo> LoadScoreIntoOsu(OsuGameBase osu, ScoreInfo score, ArchiveReader archive = null)
|
||||||
{
|
{
|
||||||
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
return scoreManager.GetAllUsableScores().FirstOrDefault();
|
return scoreManager.GetAllUsableScores().FirstOrDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestArchiveReader : ArchiveReader
|
internal class TestArchiveReader : ArchiveReader
|
||||||
{
|
{
|
||||||
public TestArchiveReader()
|
public TestArchiveReader()
|
||||||
: base("test_archive")
|
: base("test_archive")
|
||||||
|
@ -82,7 +82,8 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
switch (req)
|
switch (req)
|
||||||
{
|
{
|
||||||
case JoinChannelRequest _:
|
case JoinChannelRequest joinChannel:
|
||||||
|
joinChannel.TriggerSuccess();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,8 +40,6 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, Resources, host, Beatmap.Default));
|
||||||
|
|
||||||
manager.Import(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Wait();
|
|
||||||
|
|
||||||
((DummyAPIAccess)API).HandleRequest = req =>
|
((DummyAPIAccess)API).HandleRequest = req =>
|
||||||
{
|
{
|
||||||
switch (req)
|
switch (req)
|
||||||
@ -58,6 +56,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
[SetUpSteps]
|
[SetUpSteps]
|
||||||
public void SetupSteps()
|
public void SetupSteps()
|
||||||
{
|
{
|
||||||
|
AddStep("ensure has beatmap", () => manager.Import(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo.BeatmapSet).Wait());
|
||||||
AddStep("load match", () => LoadScreen(match = new TestPlaylistsRoomSubScreen(Room)));
|
AddStep("load match", () => LoadScreen(match = new TestPlaylistsRoomSubScreen(Room)));
|
||||||
AddUntilStep("wait for load", () => match.IsCurrentScreen());
|
AddUntilStep("wait for load", () => match.IsCurrentScreen());
|
||||||
}
|
}
|
||||||
@ -111,10 +110,27 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
public void TestBeatmapUpdatedOnReImport()
|
public void TestBeatmapUpdatedOnReImport()
|
||||||
{
|
{
|
||||||
BeatmapSetInfo importedSet = null;
|
BeatmapSetInfo importedSet = null;
|
||||||
|
TestBeatmap beatmap = null;
|
||||||
|
|
||||||
|
// this step is required to make sure the further imports actually get online IDs.
|
||||||
|
// all the playlist logic relies on online ID matching.
|
||||||
|
AddStep("remove all matching online IDs", () =>
|
||||||
|
{
|
||||||
|
beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
|
|
||||||
|
var existing = manager.QueryBeatmapSets(s => s.OnlineBeatmapSetID == beatmap.BeatmapInfo.BeatmapSet.OnlineBeatmapSetID).ToList();
|
||||||
|
|
||||||
|
foreach (var s in existing)
|
||||||
|
{
|
||||||
|
s.OnlineBeatmapSetID = null;
|
||||||
|
foreach (var b in s.Beatmaps)
|
||||||
|
b.OnlineBeatmapID = null;
|
||||||
|
manager.Update(s);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
AddStep("import altered beatmap", () =>
|
AddStep("import altered beatmap", () =>
|
||||||
{
|
{
|
||||||
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo);
|
|
||||||
beatmap.BeatmapInfo.BaseDifficulty.CircleSize = 1;
|
beatmap.BeatmapInfo.BaseDifficulty.CircleSize = 1;
|
||||||
|
|
||||||
importedSet = manager.Import(beatmap.BeatmapInfo.BeatmapSet).Result;
|
importedSet = manager.Import(beatmap.BeatmapInfo.BeatmapSet).Result;
|
||||||
|
@ -149,7 +149,8 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
|||||||
private TournamentGameBase loadOsu(GameHost host)
|
private TournamentGameBase loadOsu(GameHost host)
|
||||||
{
|
{
|
||||||
var osu = new TournamentGameBase();
|
var osu = new TournamentGameBase();
|
||||||
Task.Run(() => host.Run(osu));
|
Task.Run(() => host.Run(osu))
|
||||||
|
.ContinueWith(t => Assert.Fail($"Host threw exception {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted);
|
||||||
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
||||||
return osu;
|
return osu;
|
||||||
}
|
}
|
||||||
|
@ -55,7 +55,8 @@ namespace osu.Game.Tournament.Tests.NonVisual
|
|||||||
private TournamentGameBase loadOsu(GameHost host)
|
private TournamentGameBase loadOsu(GameHost host)
|
||||||
{
|
{
|
||||||
var osu = new TournamentGameBase();
|
var osu = new TournamentGameBase();
|
||||||
Task.Run(() => host.Run(osu));
|
Task.Run(() => host.Run(osu))
|
||||||
|
.ContinueWith(t => Assert.Fail($"Host threw exception {t.Exception}"), TaskContinuationOptions.OnlyOnFaulted);
|
||||||
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
||||||
return osu;
|
return osu;
|
||||||
}
|
}
|
||||||
|
@ -181,8 +181,13 @@ namespace osu.Game.Beatmaps
|
|||||||
if (existingOnlineId != null)
|
if (existingOnlineId != null)
|
||||||
{
|
{
|
||||||
Delete(existingOnlineId);
|
Delete(existingOnlineId);
|
||||||
beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID);
|
|
||||||
LogForModel(beatmapSet, $"Found existing beatmap set with same OnlineBeatmapSetID ({beatmapSet.OnlineBeatmapSetID}). It has been purged.");
|
// in order to avoid a unique key constraint, immediately remove the online ID from the previous set.
|
||||||
|
existingOnlineId.OnlineBeatmapSetID = null;
|
||||||
|
foreach (var b in existingOnlineId.Beatmaps)
|
||||||
|
b.OnlineBeatmapID = null;
|
||||||
|
|
||||||
|
LogForModel(beatmapSet, $"Found existing beatmap set with same OnlineBeatmapSetID ({beatmapSet.OnlineBeatmapSetID}). It has been deleted.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,12 +89,18 @@ namespace osu.Game.Database
|
|||||||
if (IsDisposed)
|
if (IsDisposed)
|
||||||
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
throw new ObjectDisposedException(nameof(RealmContextFactory));
|
||||||
|
|
||||||
|
Logger.Log(@"Blocking realm operations.", LoggingTarget.Database);
|
||||||
|
|
||||||
blockingLock.Wait();
|
blockingLock.Wait();
|
||||||
flushContexts();
|
flushContexts();
|
||||||
|
|
||||||
return new InvokeOnDisposal<RealmContextFactory>(this, endBlockingSection);
|
return new InvokeOnDisposal<RealmContextFactory>(this, endBlockingSection);
|
||||||
|
|
||||||
static void endBlockingSection(RealmContextFactory factory) => factory.blockingLock.Release();
|
static void endBlockingSection(RealmContextFactory factory)
|
||||||
|
{
|
||||||
|
factory.blockingLock.Release();
|
||||||
|
Logger.Log(@"Restoring realm operations.", LoggingTarget.Database);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
@ -147,6 +153,8 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
private void flushContexts()
|
private void flushContexts()
|
||||||
{
|
{
|
||||||
|
Logger.Log(@"Flushing realm contexts...", LoggingTarget.Database);
|
||||||
|
|
||||||
var previousContext = context;
|
var previousContext = context;
|
||||||
context = null;
|
context = null;
|
||||||
|
|
||||||
@ -155,6 +163,8 @@ namespace osu.Game.Database
|
|||||||
Thread.Sleep(50);
|
Thread.Sleep(50);
|
||||||
|
|
||||||
previousContext?.Dispose();
|
previousContext?.Dispose();
|
||||||
|
|
||||||
|
Logger.Log(@"Realm contexts flushed.", LoggingTarget.Database);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
|
@ -9,11 +9,11 @@ namespace osu.Game.Online.API.Requests
|
|||||||
{
|
{
|
||||||
public class PostMessageRequest : APIRequest<Message>
|
public class PostMessageRequest : APIRequest<Message>
|
||||||
{
|
{
|
||||||
private readonly Message message;
|
public readonly Message Message;
|
||||||
|
|
||||||
public PostMessageRequest(Message message)
|
public PostMessageRequest(Message message)
|
||||||
{
|
{
|
||||||
this.message = message;
|
Message = message;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WebRequest CreateWebRequest()
|
protected override WebRequest CreateWebRequest()
|
||||||
@ -21,12 +21,12 @@ namespace osu.Game.Online.API.Requests
|
|||||||
var req = base.CreateWebRequest();
|
var req = base.CreateWebRequest();
|
||||||
|
|
||||||
req.Method = HttpMethod.Post;
|
req.Method = HttpMethod.Post;
|
||||||
req.AddParameter(@"is_action", message.IsAction.ToString().ToLowerInvariant());
|
req.AddParameter(@"is_action", Message.IsAction.ToString().ToLowerInvariant());
|
||||||
req.AddParameter(@"message", message.Content);
|
req.AddParameter(@"message", Message.Content);
|
||||||
|
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string Target => $@"chat/channels/{message.ChannelId}/messages";
|
protected override string Target => $@"chat/channels/{Message.ChannelId}/messages";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -225,7 +225,7 @@ namespace osu.Game.Online.Chat
|
|||||||
switch (command)
|
switch (command)
|
||||||
{
|
{
|
||||||
case "np":
|
case "np":
|
||||||
AddInternal(new NowPlayingCommand());
|
AddInternal(new NowPlayingCommand(target));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "me":
|
case "me":
|
||||||
@ -235,7 +235,7 @@ namespace osu.Game.Online.Chat
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
PostMessage(content, true);
|
PostMessage(content, true, target);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "join":
|
case "join":
|
||||||
|
@ -21,6 +21,17 @@ namespace osu.Game.Online.Chat
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private Bindable<WorkingBeatmap> currentBeatmap { get; set; }
|
private Bindable<WorkingBeatmap> currentBeatmap { get; set; }
|
||||||
|
|
||||||
|
private readonly Channel target;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates a new <see cref="NowPlayingCommand"/> to post the currently-playing beatmap to a parenting <see cref="IChannelPostTarget"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="target">The target channel to post to. If <c>null</c>, the currently-selected channel will be posted to.</param>
|
||||||
|
public NowPlayingCommand(Channel target = null)
|
||||||
|
{
|
||||||
|
this.target = target;
|
||||||
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -48,7 +59,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
var beatmapString = beatmap.OnlineBeatmapID.HasValue ? $"[{api.WebsiteRootUrl}/b/{beatmap.OnlineBeatmapID} {beatmap}]" : beatmap.ToString();
|
var beatmapString = beatmap.OnlineBeatmapID.HasValue ? $"[{api.WebsiteRootUrl}/b/{beatmap.OnlineBeatmapID} {beatmap}]" : beatmap.ToString();
|
||||||
|
|
||||||
channelManager.PostMessage($"is {verb} {beatmapString}", true);
|
channelManager.PostMessage($"is {verb} {beatmapString}", true, target);
|
||||||
Expire();
|
Expire();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -422,11 +422,15 @@ namespace osu.Game
|
|||||||
|
|
||||||
public void Migrate(string path)
|
public void Migrate(string path)
|
||||||
{
|
{
|
||||||
|
Logger.Log($@"Migrating osu! data from ""{Storage.GetFullPath(string.Empty)}"" to ""{path}""...");
|
||||||
|
|
||||||
using (realmFactory.BlockAllOperations())
|
using (realmFactory.BlockAllOperations())
|
||||||
{
|
{
|
||||||
contextFactory.FlushConnections();
|
contextFactory.FlushConnections();
|
||||||
(Storage as OsuStorage)?.Migrate(Host.GetStorage(path));
|
(Storage as OsuStorage)?.Migrate(Host.GetStorage(path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Logger.Log(@"Migration complete!");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
|
protected override UserInputManager CreateUserInputManager() => new OsuUserInputManager();
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Scoring
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int Combo { get; set; } // Todo: Shouldn't exist in here
|
public int Combo { get; set; } // Todo: Shouldn't exist in here
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonProperty("ruleset_id")]
|
||||||
public int RulesetID { get; set; }
|
public int RulesetID { get; set; }
|
||||||
|
|
||||||
[JsonProperty("passed")]
|
[JsonProperty("passed")]
|
||||||
|
Loading…
Reference in New Issue
Block a user