1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-11 13:37:25 +08:00

Merge branch 'sh-xh-grading-2' of https://github.com/iiSaLMaN/osu into sh-xh-grading-2

This commit is contained in:
KingLuigi4932 2019-04-25 14:04:12 +03:00
commit 4e0f21102b
29 changed files with 318 additions and 176 deletions

View File

@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
default:
return 0;
case HitResult.Perfect:
return 8;
return 0.008;
}
}

View File

@ -23,9 +23,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
switch (result)
{
default:
return 0;
return base.HealthIncreaseFor(result);
case HitResult.Perfect:
return 7;
return 0.007;
}
}
}

View File

@ -27,9 +27,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
switch (result)
{
default:
return 0;
return -0.02;
case HitResult.Perfect:
return 10.2;
return 0.01;
}
}

View File

@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
default:
return 0;
case HitResult.Perfect:
return 4;
return 0.004;
}
}
}

View File

@ -1,7 +1,6 @@
// 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;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Judgements;
@ -27,20 +26,15 @@ namespace osu.Game.Rulesets.Catch.Scoring
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
}
private const double harshness = 0.01;
protected override void ApplyResult(JudgementResult result)
protected override double HealthAdjustmentFactorFor(JudgementResult result)
{
base.ApplyResult(result);
if (result.Type == HitResult.Miss)
switch (result.Type)
{
if (!result.Judgement.IsBonus)
Health.Value -= hpDrainRate * (harshness * 2);
return;
case HitResult.Miss:
return hpDrainRate;
default:
return 10.2 - hpDrainRate; // Award less HP as drain rate is increased
}
Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
}
public override HitWindows CreateHitWindows() => new CatchHitWindows();

View File

@ -10,5 +10,16 @@ namespace osu.Game.Rulesets.Mania.Judgements
public override bool AffectsCombo => false;
protected override int NumericResultFor(HitResult result) => 20;
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return 0;
default:
return 0.040;
}
}
}
}

View File

@ -25,5 +25,26 @@ namespace osu.Game.Rulesets.Mania.Judgements
return 300;
}
}
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return -0.125;
case HitResult.Meh:
return 0.005;
case HitResult.Ok:
return 0.010;
case HitResult.Good:
return 0.035;
case HitResult.Great:
return 0.055;
case HitResult.Perfect:
return 0.065;
default:
return 0;
}
}
}
}

View File

@ -3,7 +3,6 @@
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
@ -28,36 +27,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
/// </summary>
private const double hp_multiplier_max = 1;
/// <summary>
/// The default BAD hit HP increase.
/// </summary>
private const double hp_increase_bad = 0.005;
/// <summary>
/// The default OK hit HP increase.
/// </summary>
private const double hp_increase_ok = 0.010;
/// <summary>
/// The default GOOD hit HP increase.
/// </summary>
private const double hp_increase_good = 0.035;
/// <summary>
/// The default tick hit HP increase.
/// </summary>
private const double hp_increase_tick = 0.040;
/// <summary>
/// The default GREAT hit HP increase.
/// </summary>
private const double hp_increase_great = 0.055;
/// <summary>
/// The default PERFECT hit HP increase.
/// </summary>
private const double hp_increase_perfect = 0.065;
/// <summary>
/// The MISS HP multiplier at OD = 0.
/// </summary>
@ -73,11 +42,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
/// </summary>
private const double hp_multiplier_miss_max = 1;
/// <summary>
/// The default MISS HP increase.
/// </summary>
private const double hp_increase_miss = -0.125;
/// <summary>
/// The MISS HP multiplier. This is multiplied to the miss hp increase.
/// </summary>
@ -88,10 +52,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
/// </summary>
private double hpMultiplier = 1;
public ManiaScoreProcessor()
{
}
public ManiaScoreProcessor(DrawableRuleset<ManiaHitObject> drawableRuleset)
: base(drawableRuleset)
{
@ -122,42 +82,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
}
}
protected override void ApplyResult(JudgementResult result)
{
base.ApplyResult(result);
bool isTick = result.Judgement is HoldNoteTickJudgement;
if (isTick)
{
if (result.IsHit)
Health.Value += hpMultiplier * hp_increase_tick;
}
else
{
switch (result.Type)
{
case HitResult.Miss:
Health.Value += hpMissMultiplier * hp_increase_miss;
break;
case HitResult.Meh:
Health.Value += hpMultiplier * hp_increase_bad;
break;
case HitResult.Ok:
Health.Value += hpMultiplier * hp_increase_ok;
break;
case HitResult.Good:
Health.Value += hpMultiplier * hp_increase_good;
break;
case HitResult.Great:
Health.Value += hpMultiplier * hp_increase_great;
break;
case HitResult.Perfect:
Health.Value += hpMultiplier * hp_increase_perfect;
break;
}
}
}
protected override double HealthAdjustmentFactorFor(JudgementResult result)
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
}

View File

@ -24,5 +24,20 @@ namespace osu.Game.Rulesets.Osu.Judgements
return 300;
}
}
protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
case HitResult.Miss:
return -0.02;
case HitResult.Meh:
case HitResult.Good:
case HitResult.Great:
return 0.01;
default:
return 0;
}
}
}
}

View File

@ -37,8 +37,6 @@ namespace osu.Game.Rulesets.Osu.Scoring
comboResultCounts.Clear();
}
private const double harshness = 0.01;
protected override void ApplyResult(JudgementResult result)
{
base.ApplyResult(result);
@ -47,28 +45,29 @@ namespace osu.Game.Rulesets.Osu.Scoring
if (result.Type != HitResult.None)
comboResultCounts[osuResult.ComboType] = comboResultCounts.GetOrDefault(osuResult.ComboType) + 1;
}
protected override double HealthAdjustmentFactorFor(JudgementResult result)
{
switch (result.Type)
{
case HitResult.Great:
Health.Value += (10.2 - hpDrainRate) * harshness;
break;
return 10.2 - hpDrainRate;
case HitResult.Good:
Health.Value += (8 - hpDrainRate) * harshness;
break;
return 8 - hpDrainRate;
case HitResult.Meh:
Health.Value += (4 - hpDrainRate) * harshness;
break;
return 4 - hpDrainRate;
/*case HitResult.SliderTick:
Health.Value += Math.Max(7 - hpDrainRate, 0) * 0.01;
break;*/
// case HitResult.SliderTick:
// return Math.Max(7 - hpDrainRate, 0) * 0.01;
case HitResult.Miss:
Health.Value -= hpDrainRate * (harshness * 2);
break;
return hpDrainRate;
default:
return 0;
}
}

View File

@ -46,19 +46,8 @@ namespace osu.Game.Rulesets.Taiko.Scoring
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.DrainRate, 0.0018, 0.0075, 0.0120);
}
protected override void ApplyResult(JudgementResult result)
{
base.ApplyResult(result);
double hpIncrease = result.Judgement.HealthIncreaseFor(result);
if (result.Type == HitResult.Miss)
hpIncrease *= hpMissMultiplier;
else
hpIncrease *= hpMultiplier;
Health.Value += hpIncrease;
}
protected override double HealthAdjustmentFactorFor(JudgementResult result)
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
protected override void Reset(bool storeResults)
{

View File

@ -0,0 +1,150 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.UI;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCaseFrameStabilityContainer : OsuTestCase
{
private readonly ManualClock manualClock;
private readonly Container mainContainer;
private ClockConsumingChild consumer;
public TestCaseFrameStabilityContainer()
{
Child = mainContainer = new Container
{
RelativeSizeAxes = Axes.Both,
Clock = new FramedClock(manualClock = new ManualClock()),
};
}
[Test]
public void TestLargeJumps()
{
seekManualTo(0);
createStabilityContainer();
seekManualTo(100000);
confirmSeek(100000);
checkFrameCount(6000);
seekManualTo(0);
confirmSeek(0);
checkFrameCount(12000);
}
[Test]
public void TestSmallJumps()
{
seekManualTo(0);
createStabilityContainer();
seekManualTo(40);
confirmSeek(40);
checkFrameCount(3);
seekManualTo(0);
confirmSeek(0);
checkFrameCount(6);
}
[Test]
public void TestSingleFrameJump()
{
seekManualTo(0);
createStabilityContainer();
seekManualTo(8);
confirmSeek(8);
checkFrameCount(1);
seekManualTo(16);
confirmSeek(16);
checkFrameCount(2);
}
[Test]
public void TestInitialSeek()
{
seekManualTo(100000);
createStabilityContainer();
confirmSeek(100000);
checkFrameCount(0);
}
private void createStabilityContainer() => AddStep("create container", () => mainContainer.Child = new FrameStabilityContainer().WithChild(consumer = new ClockConsumingChild()));
private void seekManualTo(double time) => AddStep($"seek manual clock to {time}", () => manualClock.CurrentTime = time);
private void confirmSeek(double time) => AddUntilStep($"wait for seek to {time}", () => consumer.Clock.CurrentTime == time);
private void checkFrameCount(int frames) =>
AddAssert($"elapsed frames is {frames}", () => consumer.ElapsedFrames == frames);
public class ClockConsumingChild : CompositeDrawable
{
private readonly OsuSpriteText text;
private readonly OsuSpriteText text2;
private readonly OsuSpriteText text3;
public ClockConsumingChild()
{
Anchor = Anchor.Centre;
Origin = Anchor.Centre;
InternalChildren = new Drawable[]
{
new FillFlowContainer
{
RelativeSizeAxes = Axes.Both,
Direction = FillDirection.Vertical,
Children = new Drawable[]
{
text = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
text2 = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
text3 = new OsuSpriteText
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
}
},
};
}
public int ElapsedFrames;
protected override void Update()
{
base.Update();
if (Clock.ElapsedFrameTime != 0)
ElapsedFrames++;
text.Text = $"current time: {Clock.CurrentTime:F0}";
if (Clock.ElapsedFrameTime != 0)
text2.Text = $"last elapsed frame time: {Clock.ElapsedFrameTime:F0}";
text3.Text = $"total frames: {ElapsedFrames:F0}";
}
}
}
}

View File

@ -10,22 +10,26 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Screens;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Scoring;
using osu.Game.Scoring;
using osu.Game.Screens;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual.Gameplay
{
public class TestCasePlayerLoader : ManualInputManagerTestCase
{
private PlayerLoader loader;
private readonly OsuScreenStack stack;
private OsuScreenStack stack;
public TestCasePlayerLoader()
[SetUp]
public void Setup() => Schedule(() =>
{
InputManager.Add(stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both });
}
InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
Beatmap.Value = new TestWorkingBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo), Clock);
});
[Test]
public void TestLoadContinuation()
@ -34,8 +38,6 @@ namespace osu.Game.Tests.Visual.Gameplay
AddUntilStep("wait for current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for no longer current", () => !loader.IsCurrentScreen());
AddStep("exit loader", () => loader.Exit());
AddUntilStep("wait for no longer alive", () => !loader.IsAlive);
AddStep("load slow dummy beatmap", () =>
{
SlowLoadPlayer slow = null;
@ -59,41 +61,25 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep("load player", () =>
{
Mods.Value = new[] { gameMod = new TestMod() };
InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre);
stack.Push(new PlayerLoader(() => player = new TestPlayer()));
});
AddUntilStep("wait for player to become current", () =>
{
if (player.IsCurrentScreen())
{
playerMod1 = (TestMod)player.Mods.Value.Single();
return true;
}
return false;
stack.Push(loader = new PlayerLoader(() => player = new TestPlayer()));
});
AddUntilStep("wait for loader to become current", () => loader.IsCurrentScreen());
AddStep("mouse in centre", () => InputManager.MoveMouseTo(loader.ScreenSpaceDrawQuad.Centre));
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
AddStep("retrieve mods", () => playerMod1 = (TestMod)player.Mods.Value.Single());
AddAssert("game mods not applied", () => gameMod.Applied == false);
AddAssert("player mods applied", () => playerMod1.Applied);
AddStep("restart player", () =>
{
var lastPlayer = player;
player = null;
player.Restart();
});
AddUntilStep("wait for player to become current", () =>
{
if (player.IsCurrentScreen())
{
playerMod2 = (TestMod)player.Mods.Value.Single();
return true;
}
return false;
lastPlayer.Restart();
});
AddUntilStep("wait for player to be current", () => player.IsCurrentScreen());
AddStep("retrieve mods", () => playerMod2 = (TestMod)player.Mods.Value.Single());
AddAssert("game mods not applied", () => gameMod.Applied == false);
AddAssert("player has different mods", () => playerMod1 != playerMod2);
AddAssert("player mods applied", () => playerMod2.Applied);

View File

@ -23,7 +23,11 @@ namespace osu.Game.Tests.Visual.Menus
public TestCaseLoaderAnimation()
{
Child = logo = new OsuLogo { Depth = float.MinValue };
Child = logo = new OsuLogo
{
Alpha = 0,
Depth = float.MinValue
};
}
[Test]
@ -39,7 +43,7 @@ namespace osu.Game.Tests.Visual.Menus
LoadScreen(loader);
});
AddAssert("loaded", () =>
AddUntilStep("loaded", () =>
{
logoVisible = loader.Logo?.Alpha > 0;
return loader.Logo != null && loader.ScreenLoaded;

View File

@ -31,6 +31,11 @@ namespace osu.Game.Rulesets.Judgements
/// </summary>
public int MaxNumericResult => NumericResultFor(MaxResult);
/// <summary>
/// The health increase for the maximum achievable result.
/// </summary>
public double MaxHealthIncrease => HealthIncreaseFor(MaxResult);
/// <summary>
/// Retrieves the numeric score representation of a <see cref="HitResult"/>.
/// </summary>

View File

@ -37,6 +37,11 @@ namespace osu.Game.Rulesets.Judgements
/// </summary>
public int HighestComboAtJudgement { get; internal set; }
/// <summary>
/// The health prior to this <see cref="JudgementResult"/> occurring.
/// </summary>
public double HealthAtJudgement { get; internal set; }
/// <summary>
/// Whether a miss or hit occurred.
/// </summary>

View File

@ -312,6 +312,7 @@ namespace osu.Game.Rulesets.Scoring
{
result.ComboAtJudgement = Combo.Value;
result.HighestComboAtJudgement = HighestCombo.Value;
result.HealthAtJudgement = Health.Value;
JudgedHits++;
@ -343,6 +344,8 @@ namespace osu.Game.Rulesets.Scoring
baseScore += result.Judgement.NumericResultFor(result);
rollingMaxBaseScore += result.Judgement.MaxNumericResult;
}
Health.Value += HealthAdjustmentFactorFor(result) * result.Judgement.HealthIncreaseFor(result);
}
/// <summary>
@ -354,6 +357,7 @@ namespace osu.Game.Rulesets.Scoring
{
Combo.Value = result.ComboAtJudgement;
HighestCombo.Value = result.HighestComboAtJudgement;
Health.Value = result.HealthAtJudgement;
JudgedHits--;
@ -369,6 +373,13 @@ namespace osu.Game.Rulesets.Scoring
}
}
/// <summary>
/// An adjustment factor which is multiplied into the health increase provided by a <see cref="JudgementResult"/>.
/// </summary>
/// <param name="result">The <see cref="JudgementResult"/> for which the adjustment should apply.</param>
/// <returns>The adjustment factor.</returns>
protected virtual double HealthAdjustmentFactorFor(JudgementResult result) => 1;
private void updateScore()
{
if (rollingMaxBaseScore != 0)

View File

@ -225,6 +225,12 @@ namespace osu.Game.Rulesets.UI
if (replayInputManager.ReplayInputHandler != null)
replayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace;
if (!ProvidingUserCursor)
{
// The cursor is hidden by default (see Playfield.load()), but should be shown when there's a replay
Playfield.Cursor?.Show();
}
}
/// <summary>

View File

@ -68,6 +68,8 @@ namespace osu.Game.Rulesets.UI
private const double sixty_frame_time = 1000.0 / 60;
private bool firstConsumption = true;
public override bool UpdateSubTree()
{
requireMoreUpdateLoops = true;
@ -103,7 +105,18 @@ namespace osu.Game.Rulesets.UI
try
{
if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f)
if (firstConsumption)
{
// On the first update, frame-stability seeking would result in unexpected/unwanted behaviour.
// Instead we perform an initial seek to the proposed time.
manualClock.CurrentTime = newProposedTime;
// do a second process to clear out ElapsedTime
framedClock.ProcessFrame();
firstConsumption = false;
}
else if (Math.Abs(manualClock.CurrentTime - newProposedTime) > sixty_frame_time * 1.2f)
{
newProposedTime = newProposedTime > manualClock.CurrentTime
? Math.Min(newProposedTime, manualClock.CurrentTime + sixty_frame_time)

View File

@ -68,7 +68,12 @@ namespace osu.Game.Rulesets.UI
{
Cursor = CreateCursor();
if (Cursor != null)
{
// initial showing of the cursor will be handed by MenuCursorContainer (via DrawableRuleset's IProvideCursor implementation).
Cursor.Hide();
AddInternal(Cursor);
}
}
/// <summary>

View File

@ -92,13 +92,6 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
}
protected override void Update()
{
base.Update();
zoomedContent.Width = DrawWidth * currentZoom;
}
protected override bool OnScroll(ScrollEvent e)
{
if (e.IsPrecise)
@ -169,6 +162,11 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset;
d.currentZoom = newZoom;
d.zoomedContent.Width = d.DrawWidth * d.currentZoom;
// Temporarily here to make sure ScrollTo gets the correct DrawSize for scrollable area.
// TODO: Make sure draw size gets invalidated properly on the framework side, and remove this once it is.
d.Invalidate(Invalidation.DrawSize);
d.ScrollTo(targetOffset, false);
}

View File

@ -79,7 +79,7 @@ namespace osu.Game.Screens.Multi
[BackgroundDependencyLoader]
private void load(OsuColour colours)
{
Title = "multiplayer";
Title = "multi";
Icon = OsuIcon.Multi;
AccentColour = colours.Yellow;
}

View File

@ -276,7 +276,7 @@ namespace osu.Game.Screens.Multi
updatePollingRate(isIdle.Value);
if (screenStack.CurrentScreen == null)
if (screenStack.CurrentScreen == null && this.IsCurrentScreen())
this.Exit();
}

View File

@ -110,11 +110,8 @@ namespace osu.Game.Screens.Play
adjustableClock.ChangeSource(sourceClock);
updateRate();
this.Delay(750).Schedule(() =>
{
if (!IsPaused.Value)
Start();
});
if (!IsPaused.Value)
Start();
});
});
}
@ -123,7 +120,7 @@ namespace osu.Game.Screens.Play
{
// Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time
// This accounts for the audio clock source potentially taking time to enter a completely stopped state
adjustableClock.Seek(adjustableClock.CurrentTime);
Seek(GameplayClock.CurrentTime);
adjustableClock.Start();
IsPaused.Value = false;
}

View File

@ -129,7 +129,7 @@ namespace osu.Game.Screens.Play.HUD
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Size = new Vector2(15),
Icon = FontAwesome.Solid.TimesCircle
Icon = FontAwesome.Solid.Times
},
}
};

View File

@ -4,17 +4,24 @@
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Testing.Input;
using osu.Game.Graphics.Cursor;
namespace osu.Game.Tests.Visual
{
public abstract class ManualInputManagerTestCase : OsuTestCase
{
protected override Container<Drawable> Content => InputManager;
protected override Container<Drawable> Content => content;
private readonly Container content;
protected readonly ManualInputManager InputManager;
protected ManualInputManagerTestCase()
{
base.Content.Add(InputManager = new ManualInputManager { UseParentInput = true });
base.Content.Add(InputManager = new ManualInputManager
{
UseParentInput = true,
Child = content = new MenuCursorContainer { RelativeSizeAxes = Axes.Both },
});
}
/// <summary>

View File

@ -26,7 +26,7 @@ namespace osu.Game.Tests.Visual
public void SetUpSteps()
{
AddStep(ruleset.RulesetInfo.Name, loadPlayer);
AddUntilStep(() => Player.IsLoaded, "player loaded");
AddUntilStep(() => Player.IsLoaded && Player.Alpha == 1, "player loaded");
}
protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo);

View File

@ -16,7 +16,7 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.3" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.415.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.425.0" />
<PackageReference Include="SharpCompress" Version="0.23.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />

View File

@ -105,8 +105,8 @@
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.1" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.128.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.415.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.415.0" />
<PackageReference Include="ppy.osu.Framework" Version="2019.425.0" />
<PackageReference Include="ppy.osu.Framework.iOS" Version="2019.425.0" />
<PackageReference Include="SharpCompress" Version="0.22.0" />
<PackageReference Include="NUnit" Version="3.11.0" />
<PackageReference Include="SharpRaven" Version="2.4.0" />