Skip to content

Commit

Permalink
Create a backing database object for all fake users
Browse files Browse the repository at this point in the history
Realm does not let you compare against non-managed objects, so we need to make these objects managed by creating a backing user object.
  • Loading branch information
Beyley authored and jvyden committed Jul 28, 2024
1 parent e87c7dd commit c0910e4
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 31 deletions.
9 changes: 9 additions & 0 deletions Refresh.Common/Constants/FakeUserConstants.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace Refresh.Common.Constants;

public class FakeUserConstants
{
public const char Prefix = '!';

public const string DeletedUserName = "!DeletedUser";
public const string UnknownUserName = "!Unknown";
}
6 changes: 3 additions & 3 deletions Refresh.GameServer/Database/GameDatabaseContext.Levels.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,17 +180,17 @@ private IQueryable<GameLevel> GetLevelsByGameVersion(TokenGame gameVersion)
[Pure]
public DatabaseList<GameLevel> GetLevelsByUser(GameUser user, int count, int skip, LevelFilterSettings levelFilterSettings, GameUser? accessor)
{
if (user.Username == DeletedUser.Username)
if (user.Username == FakeUserConstants.DeletedUserName)
{
return new DatabaseList<GameLevel>(this.GetLevelsByGameVersion(levelFilterSettings.GameVersion).FilterByLevelFilterSettings(accessor, levelFilterSettings).Where(l => l.Publisher == null), skip, count);
}

if (user.Username == "!Unknown")
if (user.Username == FakeUserConstants.UnknownUserName)
{
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("!"))
if (user.Username.StartsWith(FakeUserConstants.Prefix))
{
string withoutPrefix = user.Username[1..];
return new DatabaseList<GameLevel>(this.GetLevelsByGameVersion(levelFilterSettings.GameVersion).FilterByLevelFilterSettings(accessor, levelFilterSettings).Where(l => l.OriginalPublisher == withoutPrefix), skip, count);
Expand Down
57 changes: 36 additions & 21 deletions Refresh.GameServer/Database/GameDatabaseContext.Users.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using JetBrains.Annotations;
using MongoDB.Bson;
using Refresh.Common.Constants;
using Refresh.GameServer.Authentication;
using Refresh.GameServer.Endpoints.ApiV3.DataTypes.Request;
using Refresh.GameServer.Types;
Expand All @@ -13,32 +14,46 @@ namespace Refresh.GameServer.Database;

public partial class GameDatabaseContext // Users
{
private static readonly GameUser DeletedUser = new()
{
Username = "!DeletedUser",
Description = "I'm a fake user that represents deleted users for levels.",
FakeUser = true,
};

[Pure]
[ContractAnnotation("null => null; notnull => canbenull")]
[ContractAnnotation("username:null => null; username:notnull => canbenull")]
public GameUser? GetUserByUsername(string? username, bool caseSensitive = true)
{
if (username == null) return null;
if (username == "!DeletedUser")
return DeletedUser;
if (username.StartsWith("!"))
return new()
{
Username = username,
Description = "I'm a fake user that represents a non existent publisher for re-published levels.",
FakeUser = true,
};
if (username == null)
return null;

// Try the first pass to get the user
GameUser? user = caseSensitive
? this.GameUsers.FirstOrDefault(u => u.Username == username)
: this.GameUsers.FirstOrDefault(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase));

if (!caseSensitive)
return this.GameUsers.FirstOrDefault(u => u.Username.Equals(username, StringComparison.OrdinalIgnoreCase));
// If that failed and the username is the deleted user, then we need to create the backing deleted user
if (username == FakeUserConstants.DeletedUserName && user == null)
{
this.Write(() =>
{
this.GameUsers.Add(user = new GameUser
{
Username = FakeUserConstants.DeletedUserName,
Description = "I'm a fake user that represents deleted users for levels.",
FakeUser = true,
});
});
}
// If that failed and the username is a fake re-upload user, then we need to create the backing fake user
else if (username.StartsWith(FakeUserConstants.Prefix) && user == null)
{
this.Write(() =>
{
this.GameUsers.Add(user = new GameUser
{
Username = username,
Description = "I'm a fake user that represents a non existent publisher for re-published levels.",
FakeUser = true,
});
});
}

return this.GameUsers.FirstOrDefault(u => u.Username == username);
return user;
}

[Pure]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
using System.Diagnostics;
using System.Xml.Serialization;
using Bunkum.Core.Storage;
using Refresh.Common.Constants;
using Refresh.GameServer.Authentication;
using Refresh.GameServer.Database;
using Refresh.GameServer.Endpoints.ApiV3.DataTypes;
using Refresh.GameServer.Extensions;
using Refresh.GameServer.Services;
using Refresh.GameServer.Types;
using Refresh.GameServer.Types.Assets;
using Refresh.GameServer.Types.Data;
using Refresh.GameServer.Types.Levels;
using Refresh.GameServer.Types.Levels.SkillRewards;
using Refresh.GameServer.Types.Matching;
using Refresh.GameServer.Types.Relations;
using Refresh.GameServer.Types.Reviews;
using Refresh.GameServer.Types.UserData;

Expand Down Expand Up @@ -190,8 +186,8 @@ public static GameLevelResponse FromHash(string hash, DataContext dataContext)
publisher = "!DeletedUser";
else
publisher = string.IsNullOrEmpty(old.OriginalPublisher)
? "!Unknown"
: "!" + old.OriginalPublisher;
? FakeUserConstants.UnknownUserName
: FakeUserConstants.Prefix + old.OriginalPublisher;

response.Handle = new SerializedUserHandle
{
Expand Down

0 comments on commit c0910e4

Please sign in to comment.