mirror of
https://github.com/osukey/osukey.git
synced 2025-07-01 16:29:58 +09:00
Give playlist items a PlayedAt date
This commit is contained in:
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -168,7 +169,8 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
Beatmap = { Value = importedBeatmap },
|
Beatmap = { Value = importedBeatmap },
|
||||||
BeatmapID = importedBeatmap.OnlineID ?? -1,
|
BeatmapID = importedBeatmap.OnlineID ?? -1,
|
||||||
Expired = expired
|
Expired = expired,
|
||||||
|
PlayedAt = DateTimeOffset.Now
|
||||||
})));
|
})));
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -742,7 +742,8 @@ namespace osu.Game.Online.Multiplayer
|
|||||||
Beatmap = { Value = apiBeatmap },
|
Beatmap = { Value = apiBeatmap },
|
||||||
Ruleset = { Value = ruleset },
|
Ruleset = { Value = ruleset },
|
||||||
Expired = item.Expired,
|
Expired = item.Expired,
|
||||||
PlaylistOrder = item.PlaylistOrder
|
PlaylistOrder = item.PlaylistOrder,
|
||||||
|
PlayedAt = item.PlayedAt
|
||||||
};
|
};
|
||||||
|
|
||||||
playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
|
playlistItem.RequiredMods.AddRange(item.RequiredMods.Select(m => m.ToMod(rulesetInstance)));
|
||||||
|
@ -46,11 +46,10 @@ namespace osu.Game.Online.Rooms
|
|||||||
public ushort PlaylistOrder { get; set; }
|
public ushort PlaylistOrder { get; set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The date when this <see cref="MultiplayerPlaylistItem"/> was last updated.
|
/// The date when this <see cref="MultiplayerPlaylistItem"/> was played.
|
||||||
/// Not serialised to/from the client.
|
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IgnoreMember]
|
[Key(9)]
|
||||||
public DateTimeOffset UpdatedAt { get; set; }
|
public DateTimeOffset? PlayedAt { get; set; }
|
||||||
|
|
||||||
public MultiplayerPlaylistItem()
|
public MultiplayerPlaylistItem()
|
||||||
{
|
{
|
||||||
@ -66,6 +65,7 @@ namespace osu.Game.Online.Rooms
|
|||||||
AllowedMods = item.AllowedMods.Select(m => new APIMod(m)).ToArray();
|
AllowedMods = item.AllowedMods.Select(m => new APIMod(m)).ToArray();
|
||||||
Expired = item.Expired;
|
Expired = item.Expired;
|
||||||
PlaylistOrder = item.PlaylistOrder ?? 0;
|
PlaylistOrder = item.PlaylistOrder ?? 0;
|
||||||
|
PlayedAt = item.PlayedAt;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -36,6 +36,9 @@ namespace osu.Game.Online.Rooms
|
|||||||
[JsonProperty("playlist_order")]
|
[JsonProperty("playlist_order")]
|
||||||
public ushort? PlaylistOrder { get; set; }
|
public ushort? PlaylistOrder { get; set; }
|
||||||
|
|
||||||
|
[JsonProperty("played_at")]
|
||||||
|
public DateTimeOffset? PlayedAt { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public IBindable<bool> Valid => valid;
|
public IBindable<bool> Valid => valid;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Match.Playlist
|
|||||||
|
|
||||||
private class HistoryFillFlowContainer : FillFlowContainer<RearrangeableListItem<PlaylistItem>>
|
private class HistoryFillFlowContainer : FillFlowContainer<RearrangeableListItem<PlaylistItem>>
|
||||||
{
|
{
|
||||||
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.OfType<RearrangeableListItem<PlaylistItem>>().OrderByDescending(item => item.Model.PlaylistOrder);
|
public override IEnumerable<Drawable> FlowingChildren => base.FlowingChildren.OfType<RearrangeableListItem<PlaylistItem>>().OrderByDescending(item => item.Model.PlayedAt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
// Expire the current playlist item.
|
// Expire the current playlist item.
|
||||||
currentItem.Expired = true;
|
currentItem.Expired = true;
|
||||||
currentItem.UpdatedAt = DateTimeOffset.Now;
|
currentItem.PlayedAt = DateTimeOffset.Now;
|
||||||
|
|
||||||
await ((IMultiplayerClient)this).PlaylistItemChanged(currentItem).ConfigureAwait(false);
|
await ((IMultiplayerClient)this).PlaylistItemChanged(currentItem).ConfigureAwait(false);
|
||||||
await updatePlaylistOrder(Room).ConfigureAwait(false);
|
await updatePlaylistOrder(Room).ConfigureAwait(false);
|
||||||
@ -430,9 +430,6 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
Debug.Assert(Room != null);
|
Debug.Assert(Room != null);
|
||||||
|
|
||||||
// Some tests can add items in already-expired states.
|
|
||||||
item.UpdatedAt = DateTimeOffset.Now;
|
|
||||||
|
|
||||||
// Add the item to the list first in order to compute gameplay order.
|
// Add the item to the list first in order to compute gameplay order.
|
||||||
serverSidePlaylist.Add(item);
|
serverSidePlaylist.Add(item);
|
||||||
await updatePlaylistOrder(Room).ConfigureAwait(false);
|
await updatePlaylistOrder(Room).ConfigureAwait(false);
|
||||||
@ -443,8 +440,12 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
private async Task updateCurrentItem(MultiplayerRoom room, bool notify = true)
|
private async Task updateCurrentItem(MultiplayerRoom room, bool notify = true)
|
||||||
{
|
{
|
||||||
// The playlist is already in correct gameplay order, so pick the next non-expired item or default to the last item.
|
MultiplayerPlaylistItem nextItem = serverSidePlaylist
|
||||||
MultiplayerPlaylistItem nextItem = serverSidePlaylist.FirstOrDefault(i => !i.Expired) ?? room.Playlist.Last();
|
.Where(i => !i.Expired)
|
||||||
|
.OrderBy(i => i.PlaylistOrder)
|
||||||
|
.FirstOrDefault()
|
||||||
|
?? room.Playlist.Last();
|
||||||
|
|
||||||
currentIndex = serverSidePlaylist.IndexOf(nextItem);
|
currentIndex = serverSidePlaylist.IndexOf(nextItem);
|
||||||
|
|
||||||
long lastItem = room.Settings.PlaylistItemId;
|
long lastItem = room.Settings.PlaylistItemId;
|
||||||
@ -494,29 +495,18 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// For expired items, it's important that they're ordered in ascending order such that the last updated item is the last in the list.
|
|
||||||
// This is so that the updated_at database column doesn't get refreshed as a result of change in ordering.
|
|
||||||
List<MultiplayerPlaylistItem> orderedExpiredItems = serverSidePlaylist.Where(item => item.Expired).OrderBy(item => item.UpdatedAt).ToList();
|
|
||||||
for (int i = 0; i < orderedExpiredItems.Count; i++)
|
|
||||||
await setOrder(orderedExpiredItems[i], (ushort)i).ConfigureAwait(false);
|
|
||||||
|
|
||||||
for (int i = 0; i < orderedActiveItems.Count; i++)
|
for (int i = 0; i < orderedActiveItems.Count; i++)
|
||||||
await setOrder(orderedActiveItems[i], (ushort)i).ConfigureAwait(false);
|
|
||||||
|
|
||||||
serverSidePlaylist.Clear();
|
|
||||||
serverSidePlaylist.AddRange(orderedExpiredItems);
|
|
||||||
serverSidePlaylist.AddRange(orderedActiveItems);
|
|
||||||
|
|
||||||
async Task setOrder(MultiplayerPlaylistItem item, ushort order)
|
|
||||||
{
|
{
|
||||||
if (item.PlaylistOrder == order)
|
var item = orderedActiveItems[i];
|
||||||
return;
|
|
||||||
|
|
||||||
item.PlaylistOrder = order;
|
if (item.PlaylistOrder == i)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
item.PlaylistOrder = (ushort)i;
|
||||||
|
|
||||||
// Items which have an ID of 0 are not in the database, so avoid propagating database/hub events for them.
|
// Items which have an ID of 0 are not in the database, so avoid propagating database/hub events for them.
|
||||||
if (item.ID <= 0)
|
if (item.ID <= 0)
|
||||||
return;
|
continue;
|
||||||
|
|
||||||
await ((IMultiplayerClient)this).PlaylistItemChanged(item).ConfigureAwait(false);
|
await ((IMultiplayerClient)this).PlaylistItemChanged(item).ConfigureAwait(false);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user