Skip to content

Commit

Permalink
Merge pull request #248 from bdach/invalid-ruleset-updates
Browse files Browse the repository at this point in the history
Fix add/edit playlist item operations not checking ruleset conversion eligibility
  • Loading branch information
smoogipoo authored Oct 28, 2024
2 parents 2beec71 + 3c552d6 commit 3abe99f
Show file tree
Hide file tree
Showing 3 changed files with 125 additions and 0 deletions.
118 changes: 118 additions & 0 deletions osu.Server.Spectator.Tests/Multiplayer/MultiplayerQueueTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,51 @@ await Assert.ThrowsAsync<InvalidStateException>(() => Hub.AddPlaylistItem(new Mu
}));
}

[Fact]
public async Task AddingItemWithRulesetIncompatibleWithBeatmapThrows()
{
Database.Setup(d => d.GetBeatmapAsync(9999)).ReturnsAsync(new database_beatmap
{
checksum = "checksum",
playmode = 2,
});

await Hub.JoinRoom(ROOM_ID);
await Assert.ThrowsAsync<InvalidStateException>(() => Hub.AddPlaylistItem(new MultiplayerPlaylistItem
{
BeatmapID = 9999,
BeatmapChecksum = "checksum",
RulesetID = 3,
}));
}

[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(0, 2)]
[InlineData(0, 3)]
[InlineData(1, 1)]
[InlineData(2, 2)]
[InlineData(3, 3)]
public async Task AddingItemWithRulesetCompatibleWithBeatmapSucceeds(ushort beatmapRulesetId, ushort scoreRulesetId)
{
Database.Setup(d => d.GetBeatmapAsync(9999)).ReturnsAsync(new database_beatmap
{
checksum = "checksum",
playmode = beatmapRulesetId,
});

await Hub.JoinRoom(ROOM_ID);
await Hub.AddPlaylistItem(new MultiplayerPlaylistItem
{
BeatmapID = 9999,
BeatmapChecksum = "checksum",
RulesetID = scoreRulesetId,
});

Database.Verify(d => d.AddPlaylistItemAsync(It.IsAny<multiplayer_playlist_item>()), Times.Once);
}

[Fact]
public async Task RoomStartsWithCurrentPlaylistItem()
{
Expand Down Expand Up @@ -332,6 +377,79 @@ await Hub.EditPlaylistItem(new MultiplayerPlaylistItem
}
}

[Fact]
public async Task EditingItemWithRulesetIncompatibleWithBeatmapThrows()
{
Database.Setup(d => d.GetBeatmapAsync(3333)).ReturnsAsync(new database_beatmap
{
checksum = "3333",
playmode = 1,
});
Database.Setup(d => d.GetBeatmapAsync(4444)).ReturnsAsync(new database_beatmap
{
checksum = "4444",
playmode = 3,
});

await Hub.JoinRoom(ROOM_ID);
await Hub.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers });

SetUserContext(ContextUser2);
await Hub.JoinRoom(ROOM_ID);
await Hub.AddPlaylistItem(new MultiplayerPlaylistItem
{
BeatmapID = 3333,
BeatmapChecksum = "3333",
RulesetID = 1,
});

await Assert.ThrowsAsync<InvalidStateException>(() => Hub.EditPlaylistItem(new MultiplayerPlaylistItem
{
ID = 2,
BeatmapID = 4444,
BeatmapChecksum = "4444",
RulesetID = 1,
}));
}

[Theory]
[InlineData(0, 0)]
[InlineData(0, 1)]
[InlineData(0, 2)]
[InlineData(0, 3)]
[InlineData(1, 1)]
[InlineData(2, 2)]
[InlineData(3, 3)]
public async Task EditingItemWithRulesetCompatibleWithBeatmapSucceeds(ushort beatmapRulesetId, ushort scoreRulesetId)
{
Database.Setup(d => d.GetBeatmapAsync(3333)).ReturnsAsync(new database_beatmap { checksum = "3333", });
Database.Setup(d => d.GetBeatmapAsync(4444)).ReturnsAsync(new database_beatmap
{
checksum = "4444",
playmode = beatmapRulesetId,
});

await Hub.JoinRoom(ROOM_ID);
await Hub.ChangeSettings(new MultiplayerRoomSettings { QueueMode = QueueMode.AllPlayers });

SetUserContext(ContextUser2);
await Hub.JoinRoom(ROOM_ID);
await Hub.AddPlaylistItem(new MultiplayerPlaylistItem
{
BeatmapID = 3333,
BeatmapChecksum = "3333",
});

await Hub.EditPlaylistItem(new MultiplayerPlaylistItem
{
ID = 2,
BeatmapID = 4444,
BeatmapChecksum = "4444",
RulesetID = scoreRulesetId,
});
Database.Verify(d => d.UpdatePlaylistItemAsync(It.IsAny<multiplayer_playlist_item>()), Times.AtLeastOnce);
}

[Fact]
public async Task HostCanUpdateGuestsItems()
{
Expand Down
1 change: 1 addition & 0 deletions osu.Server.Spectator/Database/Models/database_beatmap.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,6 @@ public class database_beatmap
public string? checksum { get; set; }
public BeatmapOnlineStatus approved { get; set; }
public double difficultyrating { get; set; }
public ushort playmode { get; set; }
}
}
6 changes: 6 additions & 0 deletions osu.Server.Spectator/Hubs/Multiplayer/MultiplayerQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ public async Task AddItem(MultiplayerPlaylistItem item, MultiplayerRoomUser user
if (item.RulesetID < 0 || item.RulesetID > ILegacyRuleset.MAX_LEGACY_RULESET_ID)
throw new InvalidStateException("Attempted to select an unsupported ruleset.");

if (beatmap.playmode != 0 && item.RulesetID != beatmap.playmode)
throw new InvalidStateException("Attempted to select an invalid beatmap and ruleset combination.");

item.EnsureModsValid();
item.OwnerID = user.UserID;
item.StarRating = beatmap.difficultyrating;
Expand All @@ -156,6 +159,9 @@ public async Task EditItem(MultiplayerPlaylistItem item, MultiplayerRoomUser use
if (item.RulesetID < 0 || item.RulesetID > ILegacyRuleset.MAX_LEGACY_RULESET_ID)
throw new InvalidStateException("Attempted to select an unsupported ruleset.");

if (beatmap.playmode != 0 && item.RulesetID != beatmap.playmode)
throw new InvalidStateException("Attempted to select an invalid beatmap and ruleset combination.");

item.EnsureModsValid();
item.OwnerID = user.UserID;
item.StarRating = beatmap.difficultyrating;
Expand Down

0 comments on commit 3abe99f

Please sign in to comment.