Persist construction menu favorites server-side (#35867)

* Persist construction menu favorites to player profile

* Use `ProtoId`s for construction favorites

* Validate construction favorites updates from the client

* Actually await the async database call
This commit is contained in:
YotaXP
2025-05-17 13:37:19 -04:00
committed by GitHub
parent 1141dcb868
commit e404e45ffc
16 changed files with 4424 additions and 25 deletions

View File

@@ -9,6 +9,7 @@ using System.Threading.Tasks;
using Content.Server.Administration.Logs;
using Content.Server.Administration.Managers;
using Content.Shared.Administration.Logs;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Database;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
@@ -65,7 +66,11 @@ namespace Content.Server.Database
profiles[profile.Slot] = ConvertProfiles(profile);
}
return new PlayerPreferences(profiles, prefs.SelectedCharacterSlot, Color.FromHex(prefs.AdminOOCColor));
var constructionFavorites = new List<ProtoId<ConstructionPrototype>>(prefs.ConstructionFavorites.Count);
foreach (var favorite in prefs.ConstructionFavorites)
constructionFavorites.Add(new ProtoId<ConstructionPrototype>(favorite));
return new PlayerPreferences(profiles, prefs.SelectedCharacterSlot, Color.FromHex(prefs.AdminOOCColor), constructionFavorites);
}
public async Task SaveSelectedCharacterIndexAsync(NetUserId userId, int index)
@@ -143,7 +148,8 @@ namespace Content.Server.Database
{
UserId = userId.UserId,
SelectedCharacterSlot = 0,
AdminOOCColor = Color.Red.ToHex()
AdminOOCColor = Color.Red.ToHex(),
ConstructionFavorites = [],
};
prefs.Profiles.Add(profile);
@@ -152,7 +158,7 @@ namespace Content.Server.Database
await db.DbContext.SaveChangesAsync();
return new PlayerPreferences(new[] {new KeyValuePair<int, ICharacterProfile>(0, defaultProfile)}, 0, Color.FromHex(prefs.AdminOOCColor));
return new PlayerPreferences(new[] { new KeyValuePair<int, ICharacterProfile>(0, defaultProfile) }, 0, Color.FromHex(prefs.AdminOOCColor), []);
}
public async Task DeleteSlotAndSetSelectedIndex(NetUserId userId, int deleteSlot, int newSlot)
@@ -178,6 +184,19 @@ namespace Content.Server.Database
}
public async Task SaveConstructionFavoritesAsync(NetUserId userId, List<ProtoId<ConstructionPrototype>> constructionFavorites)
{
await using var db = await GetDb();
var prefs = await db.DbContext.Preference.SingleAsync(p => p.UserId == userId.UserId);
var favorites = new List<string>(constructionFavorites.Count);
foreach (var favorite in constructionFavorites)
favorites.Add(favorite.Id);
prefs.ConstructionFavorites = favorites;
await db.DbContext.SaveChangesAsync();
}
private static async Task SetSelectedCharacterSlotAsync(NetUserId userId, int newSlot, ServerDbContext db)
{
var prefs = await db.Preference.SingleAsync(p => p.UserId == userId.UserId);

View File

@@ -7,6 +7,7 @@ using System.Threading.Tasks;
using Content.Server.Administration.Logs;
using Content.Shared.Administration.Logs;
using Content.Shared.CCVar;
using Content.Shared.Construction.Prototypes;
using Content.Shared.Database;
using Content.Shared.Preferences;
using Content.Shared.Roles;
@@ -42,6 +43,8 @@ namespace Content.Server.Database
Task SaveAdminOOCColorAsync(NetUserId userId, Color color);
Task SaveConstructionFavoritesAsync(NetUserId userId, List<ProtoId<ConstructionPrototype>> constructionFavorites);
// Single method for two operations for transaction.
Task DeleteSlotAndSetSelectedIndex(NetUserId userId, int deleteSlot, int newSlot);
Task<PlayerPreferences?> GetPlayerPreferencesAsync(NetUserId userId, CancellationToken cancel);
@@ -489,6 +492,12 @@ namespace Content.Server.Database
return RunDbCommand(() => _db.SaveAdminOOCColorAsync(userId, color));
}
public Task SaveConstructionFavoritesAsync(NetUserId userId, List<ProtoId<ConstructionPrototype>> constructionFavorites)
{
DbWriteOpsMetric.Inc();
return RunDbCommand(() => _db.SaveConstructionFavoritesAsync(userId, constructionFavorites));
}
public Task<PlayerPreferences?> GetPlayerPreferencesAsync(NetUserId userId, CancellationToken cancel)
{
DbReadOpsMetric.Inc();