2019-01-24 16:43:03 +08:00
|
|
|
|
// 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.
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2022-06-17 15:37:17 +08:00
|
|
|
|
#nullable disable
|
|
|
|
|
|
2021-09-17 15:24:21 +08:00
|
|
|
|
using System;
|
2021-11-24 16:59:23 +08:00
|
|
|
|
using System.Collections.Generic;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
using System.IO;
|
2021-12-13 15:34:48 +08:00
|
|
|
|
using System.Linq;
|
2021-11-24 16:59:23 +08:00
|
|
|
|
using System.Text;
|
|
|
|
|
using System.Threading;
|
2019-01-28 17:19:57 +08:00
|
|
|
|
using NUnit.Framework;
|
2021-11-24 16:59:23 +08:00
|
|
|
|
using osu.Framework.Extensions;
|
2019-01-28 17:19:57 +08:00
|
|
|
|
using osu.Framework.IO.Stores;
|
2021-09-17 15:24:21 +08:00
|
|
|
|
using osu.Framework.Testing;
|
2021-11-24 16:59:23 +08:00
|
|
|
|
using osu.Framework.Utils;
|
|
|
|
|
using osu.Game.Beatmaps;
|
2021-12-13 15:34:48 +08:00
|
|
|
|
using osu.Game.Online.API.Requests.Responses;
|
2021-11-24 16:59:23 +08:00
|
|
|
|
using osu.Game.Rulesets;
|
2021-12-13 15:34:48 +08:00
|
|
|
|
using osu.Game.Rulesets.Mods;
|
2021-11-24 16:59:23 +08:00
|
|
|
|
using osu.Game.Rulesets.Osu;
|
2021-12-13 15:34:48 +08:00
|
|
|
|
using osu.Game.Rulesets.Scoring;
|
|
|
|
|
using osu.Game.Scoring;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
|
|
|
|
namespace osu.Game.Tests.Resources
|
|
|
|
|
{
|
2019-01-28 17:19:57 +08:00
|
|
|
|
public static class TestResources
|
2018-04-13 17:19:50 +08:00
|
|
|
|
{
|
2021-08-24 12:20:01 +08:00
|
|
|
|
public const double QUICK_BEATMAP_LENGTH = 10000;
|
|
|
|
|
|
2021-09-17 15:24:21 +08:00
|
|
|
|
private static readonly TemporaryNativeStorage temp_storage = new TemporaryNativeStorage("TestResources");
|
|
|
|
|
|
2019-12-28 21:13:18 +08:00
|
|
|
|
public static DllResourceStore GetStore() => new DllResourceStore(typeof(TestResources).Assembly);
|
2019-01-28 17:19:57 +08:00
|
|
|
|
|
2019-12-13 18:00:28 +08:00
|
|
|
|
public static Stream OpenResource(string name) => GetStore().GetStream($"Resources/{name}");
|
|
|
|
|
|
2021-02-24 11:45:00 +08:00
|
|
|
|
public static Stream GetTestBeatmapStream(bool virtualTrack = false) => OpenResource($"Archives/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
|
2019-01-28 17:19:57 +08:00
|
|
|
|
|
2021-02-22 13:48:04 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
/// Retrieve a path to a copy of a shortened (~10 second) beatmap archive with a virtual track.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <remarks>
|
|
|
|
|
/// This is intended for use in tests which need to run to completion as soon as possible and don't need to test a full length beatmap.</remarks>
|
|
|
|
|
/// <returns>A path to a copy of a beatmap archive (osz). Should be deleted after use.</returns>
|
|
|
|
|
public static string GetQuickTestBeatmapForImport()
|
|
|
|
|
{
|
2021-10-27 12:04:41 +08:00
|
|
|
|
string tempPath = getTempFilename();
|
2021-02-24 11:46:35 +08:00
|
|
|
|
using (var stream = OpenResource("Archives/241526 Soleily - Renatus_virtual_quick.osz"))
|
2021-02-22 13:48:04 +08:00
|
|
|
|
using (var newFile = File.Create(tempPath))
|
|
|
|
|
stream.CopyTo(newFile);
|
|
|
|
|
|
|
|
|
|
Assert.IsTrue(File.Exists(tempPath));
|
|
|
|
|
return tempPath;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Retrieve a path to a copy of a full-fledged beatmap archive.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="virtualTrack">Whether the audio track should be virtual.</param>
|
|
|
|
|
/// <returns>A path to a copy of a beatmap archive (osz). Should be deleted after use.</returns>
|
2019-10-10 16:39:41 +08:00
|
|
|
|
public static string GetTestBeatmapForImport(bool virtualTrack = false)
|
2018-04-13 17:19:50 +08:00
|
|
|
|
{
|
2021-10-27 12:04:41 +08:00
|
|
|
|
string tempPath = getTempFilename();
|
2019-01-28 17:19:57 +08:00
|
|
|
|
|
2019-10-10 16:39:41 +08:00
|
|
|
|
using (var stream = GetTestBeatmapStream(virtualTrack))
|
2020-06-01 16:57:32 +08:00
|
|
|
|
using (var newFile = File.Create(tempPath))
|
2019-01-28 17:19:57 +08:00
|
|
|
|
stream.CopyTo(newFile);
|
2018-04-13 17:19:50 +08:00
|
|
|
|
|
2020-06-01 16:57:32 +08:00
|
|
|
|
Assert.IsTrue(File.Exists(tempPath));
|
|
|
|
|
return tempPath;
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
2021-09-17 15:24:21 +08:00
|
|
|
|
|
|
|
|
|
private static string getTempFilename() => temp_storage.GetFullPath(Guid.NewGuid() + ".osz");
|
2021-11-24 16:59:23 +08:00
|
|
|
|
|
|
|
|
|
private static int importId;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Create a test beatmap set model.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="difficultyCount">Number of difficulties. If null, a random number between 1 and 20 will be used.</param>
|
|
|
|
|
/// <param name="rulesets">Rulesets to cycle through when creating difficulties. If <c>null</c>, osu! ruleset will be used.</param>
|
|
|
|
|
public static BeatmapSetInfo CreateTestBeatmapSetInfo(int? difficultyCount = null, RulesetInfo[] rulesets = null)
|
|
|
|
|
{
|
|
|
|
|
int j = 0;
|
2022-01-23 19:27:35 +08:00
|
|
|
|
|
|
|
|
|
rulesets ??= new[] { new OsuRuleset().RulesetInfo };
|
|
|
|
|
|
|
|
|
|
RulesetInfo getRuleset() => rulesets?[j++ % rulesets.Length];
|
2021-11-24 16:59:23 +08:00
|
|
|
|
|
|
|
|
|
int setId = Interlocked.Increment(ref importId);
|
|
|
|
|
|
|
|
|
|
var metadata = new BeatmapMetadata
|
|
|
|
|
{
|
|
|
|
|
// Create random metadata, then we can check if sorting works based on these
|
|
|
|
|
Artist = "Some Artist " + RNG.Next(0, 9),
|
|
|
|
|
Title = $"Some Song (set id {setId}) {Guid.NewGuid()}",
|
2022-01-18 22:30:40 +08:00
|
|
|
|
Author = { Username = "Some Guy " + RNG.Next(0, 9) },
|
2021-11-24 16:59:23 +08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
var beatmapSet = new BeatmapSetInfo
|
|
|
|
|
{
|
|
|
|
|
OnlineID = setId,
|
|
|
|
|
Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(),
|
|
|
|
|
DateAdded = DateTimeOffset.UtcNow,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
foreach (var b in getBeatmaps(difficultyCount ?? RNG.Next(1, 20)))
|
|
|
|
|
beatmapSet.Beatmaps.Add(b);
|
|
|
|
|
|
|
|
|
|
return beatmapSet;
|
|
|
|
|
|
|
|
|
|
IEnumerable<BeatmapInfo> getBeatmaps(int count)
|
|
|
|
|
{
|
|
|
|
|
for (int i = 0; i < count; i++)
|
|
|
|
|
{
|
|
|
|
|
int beatmapId = setId * 1000 + i;
|
|
|
|
|
|
|
|
|
|
int length = RNG.Next(30000, 200000);
|
|
|
|
|
double bpm = RNG.NextSingle(80, 200);
|
|
|
|
|
|
|
|
|
|
float diff = (float)i / count * 10;
|
|
|
|
|
|
|
|
|
|
string version = "Normal";
|
|
|
|
|
if (diff > 6.6)
|
|
|
|
|
version = "Insane";
|
|
|
|
|
else if (diff > 3.3)
|
|
|
|
|
version = "Hard";
|
|
|
|
|
|
|
|
|
|
var rulesetInfo = getRuleset();
|
|
|
|
|
|
2022-08-12 13:44:19 +08:00
|
|
|
|
string hash = Guid.NewGuid().ToString().ComputeMD5Hash();
|
|
|
|
|
|
2021-11-24 16:59:23 +08:00
|
|
|
|
yield return new BeatmapInfo
|
|
|
|
|
{
|
|
|
|
|
OnlineID = beatmapId,
|
|
|
|
|
DifficultyName = $"{version} {beatmapId} (length {TimeSpan.FromMilliseconds(length):m\\:ss}, bpm {bpm:0.#})",
|
|
|
|
|
StarRating = diff,
|
|
|
|
|
Length = length,
|
2022-07-13 18:40:57 +08:00
|
|
|
|
BeatmapSet = beatmapSet,
|
2021-11-24 16:59:23 +08:00
|
|
|
|
BPM = bpm,
|
2022-08-12 13:44:19 +08:00
|
|
|
|
Hash = hash,
|
|
|
|
|
MD5Hash = hash,
|
2021-11-24 16:59:23 +08:00
|
|
|
|
Ruleset = rulesetInfo,
|
2022-07-18 16:01:45 +08:00
|
|
|
|
Metadata = metadata.DeepClone(),
|
2022-01-18 21:57:39 +08:00
|
|
|
|
Difficulty = new BeatmapDifficulty
|
2021-11-24 16:59:23 +08:00
|
|
|
|
{
|
|
|
|
|
OverallDifficulty = diff,
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-12-13 15:34:48 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Create a test score model.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="ruleset">The ruleset for which the score was set against.</param>
|
|
|
|
|
/// <returns></returns>
|
2021-12-13 15:41:29 +08:00
|
|
|
|
public static ScoreInfo CreateTestScoreInfo(RulesetInfo ruleset = null) =>
|
|
|
|
|
CreateTestScoreInfo(CreateTestBeatmapSetInfo(1, new[] { ruleset ?? new OsuRuleset().RulesetInfo }).Beatmaps.First());
|
2021-12-13 15:34:48 +08:00
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// Create a test score model.
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="beatmap">The beatmap for which the score was set against.</param>
|
|
|
|
|
/// <returns></returns>
|
2021-12-13 15:41:29 +08:00
|
|
|
|
public static ScoreInfo CreateTestScoreInfo(BeatmapInfo beatmap) => new ScoreInfo
|
2021-12-13 15:34:48 +08:00
|
|
|
|
{
|
|
|
|
|
User = new APIUser
|
|
|
|
|
{
|
|
|
|
|
Id = 2,
|
|
|
|
|
Username = "peppy",
|
|
|
|
|
CoverUrl = "https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
|
|
|
|
|
},
|
|
|
|
|
BeatmapInfo = beatmap,
|
|
|
|
|
Ruleset = beatmap.Ruleset,
|
2021-12-13 15:41:29 +08:00
|
|
|
|
Mods = new Mod[] { new TestModHardRock(), new TestModDoubleTime() },
|
2021-12-13 15:34:48 +08:00
|
|
|
|
TotalScore = 2845370,
|
|
|
|
|
Accuracy = 0.95,
|
|
|
|
|
MaxCombo = 999,
|
|
|
|
|
Position = 1,
|
|
|
|
|
Rank = ScoreRank.S,
|
|
|
|
|
Date = DateTimeOffset.Now,
|
|
|
|
|
Statistics = new Dictionary<HitResult, int>
|
|
|
|
|
{
|
|
|
|
|
[HitResult.Miss] = 1,
|
|
|
|
|
[HitResult.Meh] = 50,
|
|
|
|
|
[HitResult.Ok] = 100,
|
|
|
|
|
[HitResult.Good] = 200,
|
|
|
|
|
[HitResult.Great] = 300,
|
|
|
|
|
[HitResult.Perfect] = 320,
|
|
|
|
|
[HitResult.SmallTickHit] = 50,
|
|
|
|
|
[HitResult.SmallTickMiss] = 25,
|
|
|
|
|
[HitResult.LargeTickHit] = 100,
|
|
|
|
|
[HitResult.LargeTickMiss] = 50,
|
|
|
|
|
[HitResult.SmallBonus] = 10,
|
|
|
|
|
[HitResult.SmallBonus] = 50
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
private class TestModHardRock : ModHardRock
|
|
|
|
|
{
|
|
|
|
|
public override double ScoreMultiplier => 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private class TestModDoubleTime : ModDoubleTime
|
|
|
|
|
{
|
|
|
|
|
public override double ScoreMultiplier => 1;
|
|
|
|
|
}
|
2018-04-13 17:19:50 +08:00
|
|
|
|
}
|
|
|
|
|
}
|