Fix bug blocking character saves for species without hair. (#43170)

* Update ServerDbBase.cs

* Update ServerDbBase.cs

* Update ServerDbSqliteTests.cs

* :grumble grumble grumble:

* tests

* Update ServerDbSqliteTests.cs

* commit

* forgot this.

* relocation.

* nope, not doing that lmao

* Update ServerDbSqliteTests.cs

* test rerun

* GAAAAAA

* Update ServerDbSqliteTests.cs

* Update ServerDbSqliteTests.cs

* Update ServerDbSqliteTests.cs

* GAAAAAA

* go fish
This commit is contained in:
Kyle Tyo 2026-03-15 11:55:42 -04:00 committed by Coryler
parent 24b56cfe96
commit 6f6483f543
3 changed files with 41 additions and 9 deletions

View File

@ -1,19 +1,15 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using Content.Server.Database;
using Content.Server.Preferences.Managers;
using Content.Shared.GameTicking;
using Content.Shared.Body;
using Content.Shared.Humanoid;
using Content.Shared.Humanoid.Markings;
using Content.Shared.Humanoid.Prototypes;
using Content.Shared.Preferences;
using Content.Shared.Preferences.Loadouts;
using Content.Shared.Preferences.Loadouts.Effects;
using Microsoft.Data.Sqlite;
using Microsoft.EntityFrameworkCore;
using Robust.Shared.Asynchronous;
using Robust.Shared.Configuration;
using Robust.Shared.Enums;
using Robust.Shared.Log;
using Robust.Shared.Maths;
using Robust.Shared.Network;
@ -81,6 +77,39 @@ namespace Content.IntegrationTests.Tests.Preferences
await pair.CleanReturnAsync();
}
[Test]
public async Task TestAppearanceValidationAndSave()
{
var pair = await PoolManager.GetServerClient();
var db = GetDb(pair.Server);
var username = new NetUserId(new Guid("640bd619-fc8d-4fe2-bf3c-4a5fb17d6ddd"));
var profile = CharlieCharlieson();
profile.Appearance.Markings["Head"] = new Dictionary<HumanoidVisualLayers, List<Marking>>
{
[HumanoidVisualLayers.Hair] = [],
[HumanoidVisualLayers.FacialHair] = [],
};
profile.Appearance.Markings["OrganFake"] = new Dictionary<HumanoidVisualLayers, List<Marking>>();
await pair.Server.WaitAssertion(() =>
{
var updated = HumanoidCharacterAppearance.EnsureValid(profile.Appearance, profile.Species, profile.Sex);
Assert.That(updated.Markings["Head"], Is.Empty);
Assert.That(updated.Markings.ContainsKey("OrganFake"), Is.False);
profile.Appearance = updated;
});
Assert.DoesNotThrowAsync(async () => await db.InitPrefsAsync(username, profile));
var preferences = (ServerPreferencesManager)pair.Server.ResolveDependency<IServerPreferencesManager>();
var prefs = await db.GetPlayerPreferencesAsync(username);
var fetchedProfile = preferences.ConvertProfiles(prefs!.Profiles.Find(p => p.Slot == 0));
Assert.That(fetchedProfile.MemberwiseEquals(profile));
await pair.CleanReturnAsync();
}
[Test]
public async Task TestInitPrefs()
{

View File

@ -239,8 +239,8 @@ namespace Content.Server.Database
.ToList();
var flattenedMarkings = appearance.Markings.SelectMany(it => it.Value)
.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
var hairMarking = flattenedMarkings.FirstOrNull(kvp => kvp.Key == HumanoidVisualLayers.Hair)?.Value.FirstOrDefault();
var facialHairMarking = flattenedMarkings.FirstOrNull(kvp => kvp.Key == HumanoidVisualLayers.FacialHair)?.Value.FirstOrDefault();
var hairMarking = flattenedMarkings.FirstOrNull(kvp => kvp.Key == HumanoidVisualLayers.Hair)?.Value.FirstOrNull();
var facialHairMarking = flattenedMarkings.FirstOrNull(kvp => kvp.Key == HumanoidVisualLayers.FacialHair)?.Value.FirstOrNull();
profile.Markings =
JsonSerializer.SerializeToDocument(legacyMarkings.Select(marking => marking.ToString()).ToList());
profile.HairName = hairMarking?.MarkingId ?? HairStyles.DefaultHairStyle;

View File

@ -175,13 +175,16 @@ public sealed class MarkingManager
/// </summary>
public void EnsureValidLayers(Dictionary<HumanoidVisualLayers, List<Marking>> markingSets, HashSet<HumanoidVisualLayers> layers)
{
foreach (var markings in markingSets.Values)
foreach (var (markingSet, markings) in markingSets)
{
for (var i = markings.Count - 1; i >= 0; i--)
{
if (!TryGetMarking(markings[i], out var marking) || !layers.Contains(marking.BodyPart))
markings.RemoveAt(i);
}
if (markings.Count == 0)
markingSets.Remove(markingSet);
}
}