Make the client validate character information (#3563)
Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
@@ -201,96 +201,12 @@ namespace Content.Shared.Preferences
|
||||
return new(this, _jobPriorities, list);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Makes this profile valid so there's no bad data like negative ages.
|
||||
/// </summary>
|
||||
public static HumanoidCharacterProfile EnsureValid(
|
||||
HumanoidCharacterProfile profile,
|
||||
IPrototypeManager prototypeManager)
|
||||
{
|
||||
var age = Math.Clamp(profile.Age, MinimumAge, MaximumAge);
|
||||
var sex = profile.Sex switch
|
||||
{
|
||||
Sex.Male => Sex.Male,
|
||||
Sex.Female => Sex.Female,
|
||||
_ => Sex.Male // Invalid enum values.
|
||||
};
|
||||
var gender = profile.Gender switch
|
||||
{
|
||||
Gender.Epicene => Gender.Epicene,
|
||||
Gender.Female => Gender.Female,
|
||||
Gender.Male => Gender.Male,
|
||||
Gender.Neuter => Gender.Neuter,
|
||||
_ => Gender.Epicene // Invalid enum values.
|
||||
};
|
||||
|
||||
string name;
|
||||
if (string.IsNullOrEmpty(profile.Name))
|
||||
{
|
||||
name = "Urist McHands";
|
||||
}
|
||||
else if (profile.Name.Length > MaxNameLength)
|
||||
{
|
||||
name = profile.Name[..MaxNameLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = profile.Name;
|
||||
}
|
||||
|
||||
// TODO: Avoid Z̨͇̙͉͎̭͔̼̿͋A͚̖̞̗̞͈̓̾̀ͩͩ̔L̟ͮ̈͝G̙O͍͎̗̺̺ͫ̀̽͊̓͝ͅ tier shenanigans.
|
||||
// And other stuff like RTL overrides and such.
|
||||
// Probably also emojis...
|
||||
|
||||
name = name.Trim();
|
||||
|
||||
var appearance = HumanoidCharacterAppearance.EnsureValid(profile.Appearance);
|
||||
|
||||
var prefsUnavailableMode = profile.PreferenceUnavailable switch
|
||||
{
|
||||
PreferenceUnavailableMode.StayInLobby => PreferenceUnavailableMode.StayInLobby,
|
||||
PreferenceUnavailableMode.SpawnAsOverflow => PreferenceUnavailableMode.SpawnAsOverflow,
|
||||
_ => PreferenceUnavailableMode.StayInLobby // Invalid enum values.
|
||||
};
|
||||
|
||||
var clothing = profile.Clothing switch
|
||||
{
|
||||
ClothingPreference.Jumpsuit => ClothingPreference.Jumpsuit,
|
||||
ClothingPreference.Jumpskirt => ClothingPreference.Jumpskirt,
|
||||
_ => ClothingPreference.Jumpsuit // Invalid enum values.
|
||||
};
|
||||
|
||||
var backpack = profile.Backpack switch
|
||||
{
|
||||
BackpackPreference.Backpack => BackpackPreference.Backpack,
|
||||
BackpackPreference.Satchel => BackpackPreference.Satchel,
|
||||
BackpackPreference.Duffelbag => BackpackPreference.Duffelbag,
|
||||
_ => BackpackPreference.Backpack // Invalid enum values.
|
||||
};
|
||||
|
||||
var priorities = new Dictionary<string, JobPriority>(profile.JobPriorities
|
||||
.Where(p => prototypeManager.HasIndex<JobPrototype>(p.Key) && p.Value switch
|
||||
{
|
||||
JobPriority.Never => false, // Drop never since that's assumed default.
|
||||
JobPriority.Low => true,
|
||||
JobPriority.Medium => true,
|
||||
JobPriority.High => true,
|
||||
_ => false
|
||||
}));
|
||||
|
||||
var antags = profile.AntagPreferences
|
||||
.Where(prototypeManager.HasIndex<AntagPrototype>)
|
||||
.ToList();
|
||||
|
||||
return new HumanoidCharacterProfile(name, age, sex, gender, appearance, clothing, backpack, priorities, prefsUnavailableMode, antags);
|
||||
}
|
||||
|
||||
public string Summary =>
|
||||
Loc.GetString(
|
||||
"humanoid-character-profile-summary",
|
||||
("name", Name),
|
||||
("gender", Gender.ToString().ToLowerInvariant()),
|
||||
("age", Age)
|
||||
Loc.GetString(
|
||||
"humanoid-character-profile-summary",
|
||||
("name", Name),
|
||||
("gender", Gender.ToString().ToLowerInvariant()),
|
||||
("age", Age)
|
||||
);
|
||||
|
||||
public bool MemberwiseEquals(ICharacterProfile maybeOther)
|
||||
@@ -308,6 +224,107 @@ namespace Content.Shared.Preferences
|
||||
return Appearance.MemberwiseEquals(other.Appearance);
|
||||
}
|
||||
|
||||
public void EnsureValid()
|
||||
{
|
||||
var age = Math.Clamp(Age, MinimumAge, MaximumAge);
|
||||
|
||||
var sex = Sex switch
|
||||
{
|
||||
Sex.Male => Sex.Male,
|
||||
Sex.Female => Sex.Female,
|
||||
_ => Sex.Male // Invalid enum values.
|
||||
};
|
||||
|
||||
var gender = Gender switch
|
||||
{
|
||||
Gender.Epicene => Gender.Epicene,
|
||||
Gender.Female => Gender.Female,
|
||||
Gender.Male => Gender.Male,
|
||||
Gender.Neuter => Gender.Neuter,
|
||||
_ => Gender.Epicene // Invalid enum values.
|
||||
};
|
||||
|
||||
string name;
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
{
|
||||
name = "Urist McHands";
|
||||
}
|
||||
else if (Name.Length > MaxNameLength)
|
||||
{
|
||||
name = Name[..MaxNameLength];
|
||||
}
|
||||
else
|
||||
{
|
||||
name = Name;
|
||||
}
|
||||
|
||||
// TODO: Avoid Z̨͇̙͉͎̭͔̼̿͋A͚̖̞̗̞͈̓̾̀ͩͩ̔L̟ͮ̈͝G̙O͍͎̗̺̺ͫ̀̽͊̓͝ͅ tier shenanigans.
|
||||
// And other stuff like RTL overrides and such.
|
||||
// Probably also emojis...
|
||||
|
||||
name = name.Trim();
|
||||
|
||||
var appearance = HumanoidCharacterAppearance.EnsureValid(Appearance);
|
||||
|
||||
var prefsUnavailableMode = PreferenceUnavailable switch
|
||||
{
|
||||
PreferenceUnavailableMode.StayInLobby => PreferenceUnavailableMode.StayInLobby,
|
||||
PreferenceUnavailableMode.SpawnAsOverflow => PreferenceUnavailableMode.SpawnAsOverflow,
|
||||
_ => PreferenceUnavailableMode.StayInLobby // Invalid enum values.
|
||||
};
|
||||
|
||||
var clothing = Clothing switch
|
||||
{
|
||||
ClothingPreference.Jumpsuit => ClothingPreference.Jumpsuit,
|
||||
ClothingPreference.Jumpskirt => ClothingPreference.Jumpskirt,
|
||||
_ => ClothingPreference.Jumpsuit // Invalid enum values.
|
||||
};
|
||||
|
||||
var backpack = Backpack switch
|
||||
{
|
||||
BackpackPreference.Backpack => BackpackPreference.Backpack,
|
||||
BackpackPreference.Satchel => BackpackPreference.Satchel,
|
||||
BackpackPreference.Duffelbag => BackpackPreference.Duffelbag,
|
||||
_ => BackpackPreference.Backpack // Invalid enum values.
|
||||
};
|
||||
|
||||
var prototypeManager = IoCManager.Resolve<IPrototypeManager>();
|
||||
|
||||
var priorities = new Dictionary<string, JobPriority>(JobPriorities
|
||||
.Where(p => prototypeManager.HasIndex<JobPrototype>(p.Key) && p.Value switch
|
||||
{
|
||||
JobPriority.Never => false, // Drop never since that's assumed default.
|
||||
JobPriority.Low => true,
|
||||
JobPriority.Medium => true,
|
||||
JobPriority.High => true,
|
||||
_ => false
|
||||
}));
|
||||
|
||||
var antags = AntagPreferences
|
||||
.Where(prototypeManager.HasIndex<AntagPrototype>)
|
||||
.ToList();
|
||||
|
||||
Name = name;
|
||||
Age = age;
|
||||
Sex = sex;
|
||||
Gender = gender;
|
||||
Appearance = appearance;
|
||||
Clothing = clothing;
|
||||
Backpack = backpack;
|
||||
|
||||
_jobPriorities.Clear();
|
||||
|
||||
foreach (var (job, priority) in priorities)
|
||||
{
|
||||
_jobPriorities.Add(job, priority);
|
||||
}
|
||||
|
||||
PreferenceUnavailable = prefsUnavailableMode;
|
||||
|
||||
_antagPreferences.Clear();
|
||||
_antagPreferences.AddRange(antags);
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is HumanoidCharacterProfile other && MemberwiseEquals(other);
|
||||
@@ -328,7 +345,7 @@ namespace Content.Shared.Preferences
|
||||
PreferenceUnavailable,
|
||||
_jobPriorities,
|
||||
_antagPreferences
|
||||
);
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user