Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

LBP1 Playlists #649

Merged
merged 13 commits into from
Sep 5, 2024
30 changes: 16 additions & 14 deletions Refresh.GameServer/Database/GameDatabaseContext.Levels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ public GameLevel GetStoryLevelById(int id)
{
Title = $"Story level #{id}",
Publisher = null,
Source = GameLevelSource.Story,
StoryId = id,
};

Expand Down Expand Up @@ -180,8 +179,11 @@ public void DeleteLevel(GameLevel level)
});
}


private IQueryable<GameLevel> GetLevelsByGameVersion(TokenGame gameVersion)
=> this.GameLevels.Where(l => l._Source == (int)GameLevelSource.User).FilterByGameVersion(gameVersion);
=> this.GameLevels
.Where(l => l.StoryId == 0) // Filter out any user levels
.FilterByGameVersion(gameVersion);

[Pure]
public DatabaseList<GameLevel> GetLevelsByUser(GameUser user, int count, int skip, LevelFilterSettings levelFilterSettings, GameUser? accessor)
Expand All @@ -193,7 +195,7 @@ public DatabaseList<GameLevel> GetLevelsByUser(GameUser user, int count, int ski

if (user.Username == SystemUsers.UnknownUserName)
{
return new DatabaseList<GameLevel>(this.GetLevelsByGameVersion(levelFilterSettings.GameVersion).FilterByLevelFilterSettings(null, levelFilterSettings).Where(l => l.IsReUpload && String.IsNullOrEmpty(l.OriginalPublisher)), skip, count);
return new DatabaseList<GameLevel>(this.GetLevelsByGameVersion(levelFilterSettings.GameVersion).FilterByLevelFilterSettings(null, levelFilterSettings).Where(l => l.IsReUpload && string.IsNullOrEmpty(l.OriginalPublisher)), skip, count);
}

if (user.Username.StartsWith(SystemUsers.SystemPrefix))
Expand All @@ -209,11 +211,11 @@ public DatabaseList<GameLevel> GetLevelsByUser(GameUser user, int count, int ski

[Pure]
public DatabaseList<GameLevel> GetUserLevelsChunk(int skip, int count)
=> new(this.GameLevels.Where(l => l._Source == (int)GameLevelSource.User), skip, count);
=> new(this.GameLevels.Where(l => l.StoryId == 0), skip, count);

[Pure]
public IQueryable<GameLevel> GetAllUserLevels()
=> this.GameLevels.Where(l => l._Source == (int)GameLevelSource.User);
=> this.GameLevels.Where(l => l.StoryId == 0);

[Pure]
public DatabaseList<GameLevel> GetNewestLevels(int count, int skip, GameUser? user, LevelFilterSettings levelFilterSettings) =>
Expand Down Expand Up @@ -245,7 +247,7 @@ public DatabaseList<GameLevel> GetMostHeartedLevels(int count, int skip, GameUse
.OrderByDescending(x => x.Count)
.Select(x => x.Level)
.Where(l => l != null)
.Where(l => l._Source == (int)GameLevelSource.User)
.Where(l => l.StoryId == 0)
.FilterByLevelFilterSettings(user, levelFilterSettings)
.FilterByGameVersion(levelFilterSettings.GameVersion);

Expand All @@ -262,7 +264,7 @@ public DatabaseList<GameLevel> GetLevelsByTag(int count, int skip, GameUser? use
.AsEnumerable()
.Select(x => x.Level)
.Distinct()
.Where(l => l._Source == (int)GameLevelSource.User)
.Where(l => l.StoryId == 0)
.OrderByDescending(l => l.PublishDate)
.FilterByLevelFilterSettings(user, levelFilterSettings)
.FilterByGameVersion(levelFilterSettings.GameVersion);
Expand All @@ -282,7 +284,7 @@ public DatabaseList<GameLevel> GetMostUniquelyPlayedLevels(int count, int skip,
.OrderByDescending(x => x.Count)
.Select(x => x.Level)
.Where(l => l != null)
.Where(l => l._Source == (int)GameLevelSource.User)
.Where(l => l.StoryId == 0)
.FilterByLevelFilterSettings(user, levelFilterSettings)
.FilterByGameVersion(levelFilterSettings.GameVersion);

Expand Down Expand Up @@ -319,7 +321,7 @@ public DatabaseList<GameLevel> GetHighestRatedLevels(int count, int skip, GameUs
.OrderByDescending(x => x.Karma) // reddit moment
.Select(x => x.Level)
.Where(l => l != null)
.Where(l => l._Source == (int)GameLevelSource.User)
.Where(l => l.StoryId == 0)
.FilterByLevelFilterSettings(user, levelFilterSettings)
.FilterByGameVersion(levelFilterSettings.GameVersion);

Expand All @@ -336,7 +338,7 @@ public DatabaseList<GameLevel> GetTeamPickedLevels(int count, int skip, GameUser
[Pure]
public DatabaseList<GameLevel> GetDeveloperLevels(int count, int skip, LevelFilterSettings levelFilterSettings) =>
new(this.GameLevels
.Where(l => l._Source == (int)GameLevelSource.Story)
.Where(l => l.StoryId != 0) // filter to only levels with a story ID set
.FilterByLevelFilterSettings(null, levelFilterSettings)
.OrderByDescending(l => l.Title), skip, count);

Expand All @@ -349,7 +351,7 @@ public DatabaseList<GameLevel> GetBusiestLevels(int count, int skip, MatchServic
.OrderBy(r => r.Sum(room => room.PlayerIds.Count));

return new DatabaseList<GameLevel>(rooms.Select(r => r.Key)
.Where(l => l != null && l._Source == (int)GameLevelSource.User)!
.Where(l => l != null && l.StoryId == 0)!
.FilterByLevelFilterSettings(user, levelFilterSettings)
.FilterByGameVersion(levelFilterSettings.GameVersion), skip, count);
}
Expand Down Expand Up @@ -402,13 +404,13 @@ public DatabaseList<GameLevel> SearchForLevels(int count, int skip, GameUser? us
}

[Pure]
public int GetTotalLevelCount(TokenGame game) => this.GameLevels.FilterByGameVersion(game).Count(l => l._Source == (int)GameLevelSource.User);
public int GetTotalLevelCount(TokenGame game) => this.GameLevels.FilterByGameVersion(game).Count(l => l.StoryId == 0);

[Pure]
public int GetTotalLevelCount() => this.GameLevels.Count(l => l._Source == (int)GameLevelSource.User);
public int GetTotalLevelCount() => this.GameLevels.Count(l => l.StoryId == 0);

[Pure]
public int GetModdedLevelCount() => this.GameLevels.Count(l => l._Source == (int)GameLevelSource.User && l.IsModded);
public int GetModdedLevelCount() => this.GameLevels.Count(l => l.StoryId == 0 && l.IsModded);

public int GetTotalLevelsPublishedByUser(GameUser user)
=> this.GameLevels
Expand Down
156 changes: 156 additions & 0 deletions Refresh.GameServer/Database/GameDatabaseContext.Playlists.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
using Refresh.GameServer.Authentication;
using Refresh.GameServer.Extensions;
using Refresh.GameServer.Types.Levels;
using Refresh.GameServer.Types.Playlists;
using Refresh.GameServer.Types.UserData;

namespace Refresh.GameServer.Database;

public partial class GameDatabaseContext // Playlists
{
public GamePlaylist CreatePlaylist(GameUser user, SerializedPlaylist createInfo, bool rootPlaylist)
jvyden marked this conversation as resolved.
Show resolved Hide resolved
{
GamePlaylist playlist = new()
{
Publisher = user,
Name = createInfo.Name,
Description = createInfo.Description,
IconHash = createInfo.Icon,
LocationX = createInfo.Location.X,
LocationY = createInfo.Location.Y,
IsRoot = rootPlaylist,
};

this.Write(() =>
{
this.AddSequentialObject(playlist);
});

return playlist;
}

public GamePlaylist? GetPlaylistById(int playlistId)
=> this.GamePlaylists.FirstOrDefault(p => p.PlaylistId == playlistId);

public void UpdatePlaylist(GamePlaylist playlist, SerializedPlaylist updateInfo)
{
this.Write(() =>
{
playlist.Name = updateInfo.Name;
playlist.Description = updateInfo.Description;
playlist.IconHash = updateInfo.Icon;
playlist.LocationX = updateInfo.Location.X;
playlist.LocationY = updateInfo.Location.Y;
});
}

public void DeletePlaylist(GamePlaylist playlist)
{
this.Write(() =>
{
// Remove all relations relating to this playlist
this.LevelPlaylistRelations.RemoveRange(l => l.Playlist == playlist);
this.SubPlaylistRelations.RemoveRange(l => l.Playlist == playlist || l.SubPlaylist == playlist);

// Remove the playlist object
this.GamePlaylists.Remove(playlist);
});
}

public void AddPlaylistToPlaylist(GamePlaylist child, GamePlaylist parent)
{
this.Write(() =>
{
// Make sure to not create a duplicate object
if (this.SubPlaylistRelations.Any(p => p.SubPlaylist == child && p.Playlist == parent))
return;

// Add the relation
this.SubPlaylistRelations.Add(new SubPlaylistRelation
{
Playlist = parent,
SubPlaylist = child,
});
});
}

public void RemovePlaylistFromPlaylist(GamePlaylist child, GamePlaylist parent)
{
this.Write(() =>
{
SubPlaylistRelation? relation =
this.SubPlaylistRelations.FirstOrDefault(r => r.SubPlaylist == child && r.Playlist == parent);

if (relation == null)
return;

this.SubPlaylistRelations.Remove(relation);
});
}

public void AddLevelToPlaylist(GameLevel level, GamePlaylist parent)
{
this.Write(() =>
{
// Make sure to not create a duplicate object
if (this.LevelPlaylistRelations.Any(p => p.Level == level && p.Playlist == parent))
return;

// Add the relation
this.LevelPlaylistRelations.Add(new LevelPlaylistRelation
{
Level = level,
Playlist = parent,
});
});
}

public void RemoveLevelFromPlaylist(GameLevel level, GamePlaylist parent)
{
this.Write(() =>
{
LevelPlaylistRelation? relation =
this.LevelPlaylistRelations.FirstOrDefault(r => r.Level == level && r.Playlist == parent);

if (relation == null)
return;

this.LevelPlaylistRelations.Remove(relation);
});
}

public IEnumerable<GamePlaylist> GetPlaylistsContainingPlaylist(GamePlaylist playlist)
// TODO: with postgres this can be IQueryable
=> this.SubPlaylistRelations.Where(p => p.SubPlaylist == playlist).AsEnumerable()
.Select(r => this.GamePlaylists.First(p => p.PlaylistId == r.Playlist.PlaylistId))
.Where(p => !p.IsRoot);

public IEnumerable<GamePlaylist> GetPlaylistsByAuthorContainingPlaylist(GameUser user, GamePlaylist playlist)
// TODO: with postgres this can be IQueryable
=> this.SubPlaylistRelations.Where(p => p.SubPlaylist == playlist).AsEnumerable()
.Select(r => this.GamePlaylists.First(p => p.PlaylistId == r.Playlist.PlaylistId))
.Where(p => p.Publisher.UserId == user.UserId)
.Where(p => !p.IsRoot);

public IEnumerable<GameLevel> GetLevelsInPlaylist(GamePlaylist playlist, TokenGame game) =>
// TODO: When we have postgres, remove the `AsEnumerable` call for performance.
this.LevelPlaylistRelations.Where(l => l.Playlist == playlist).AsEnumerable()
.Select(l => l.Level)
.FilterByGameVersion(game);

public IEnumerable<GamePlaylist> GetPlaylistsInPlaylist(GamePlaylist playlist)
// TODO: When we have postgres, remove the `AsEnumerable` call for performance.
=> this.SubPlaylistRelations.Where(p => p.Playlist == playlist).AsEnumerable()
.Select(l => l.SubPlaylist);

public IEnumerable<GamePlaylist> GetPlaylistsByAuthorContainingLevel(GameUser author, GameLevel level)
// TODO: When we have postgres, remove the `AsEnumerable` call for performance.
=> this.LevelPlaylistRelations.Where(p => p.Level == level).AsEnumerable()
.Select(r => this.GamePlaylists.First(p => p.PlaylistId == r.Playlist.PlaylistId))
.Where(p => p.Publisher.UserId == author.UserId);

public IEnumerable<GamePlaylist> GetPlaylistsContainingLevel(GameLevel level)
// TODO: When we have postgres, remove the `AsEnumerable` call for performance.
=> this.LevelPlaylistRelations.Where(p => p.Level == level).AsEnumerable()
.Select(r => this.GamePlaylists.First(p => p.PlaylistId == r.Playlist.PlaylistId));
}
11 changes: 9 additions & 2 deletions Refresh.GameServer/Database/GameDatabaseContext.Users.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,9 @@
using Refresh.Common.Constants;
using Refresh.GameServer.Authentication;
using Refresh.GameServer.Endpoints.ApiV3.DataTypes.Request;
using Refresh.GameServer.Types;
using Refresh.GameServer.Types.Levels;
using Refresh.GameServer.Types.Photos;
using Refresh.GameServer.Types.Relations;
using Refresh.GameServer.Types.Playlists;
using Refresh.GameServer.Types.Roles;
using Refresh.GameServer.Types.UserData;

Expand Down Expand Up @@ -448,4 +447,12 @@ public void MarkAllReuploads(GameUser user)
}
});
}

public void SetUserRootPlaylist(GameUser user, GamePlaylist playlist)
{
this.Write(() =>
{
user.RootPlaylist = playlist;
});
}
}
4 changes: 4 additions & 0 deletions Refresh.GameServer/Database/GameDatabaseContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Refresh.GameServer.Types.Levels;
using Refresh.GameServer.Types.Notifications;
using Refresh.GameServer.Types.Photos;
using Refresh.GameServer.Types.Playlists;
using Refresh.GameServer.Types.Relations;
using Refresh.GameServer.Types.Reviews;
using Refresh.GameServer.Types.UserData;
Expand Down Expand Up @@ -57,6 +58,9 @@ public partial class GameDatabaseContext : RealmDatabaseContext
private RealmDbSet<DisallowedUser> DisallowedUsers => new(this._realm);
private RealmDbSet<RateReviewRelation> RateReviewRelations => new(this._realm);
private RealmDbSet<TagLevelRelation> TagLevelRelations => new(this._realm);
private RealmDbSet<GamePlaylist> GamePlaylists => new(this._realm);
private RealmDbSet<LevelPlaylistRelation> LevelPlaylistRelations => new(this._realm);
private RealmDbSet<SubPlaylistRelation> SubPlaylistRelations => new(this._realm);

internal GameDatabaseContext(IDateTimeProvider time)
{
Expand Down
Loading
Loading