Added preferences backend (#465)
* Added preferences backend * Gender -> Sex * ClientPreferencesManager properties * Username validation * Fixed client init * WIP db * Actually working sqlite db * Dropped shitty sqlite libraries, dropped DbUp, added MigrationManager * Added profile deletion, test * Docs, sanity, tests, cleanup * Cleaned up profile and appearance, fixed running on .net core Co-authored-by: Pieter-Jan Briers <pieterjan.briers@gmail.com>
This commit is contained in:
committed by
Pieter-Jan Briers
parent
c1b9bb348d
commit
f19795edaf
20
Content.Shared/Preferences/GameSettings.cs
Normal file
20
Content.Shared/Preferences/GameSettings.cs
Normal file
@@ -0,0 +1,20 @@
|
||||
using System;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
/// <summary>
|
||||
/// Information needed for character setup.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class GameSettings
|
||||
{
|
||||
private int _maxCharacterSlots;
|
||||
|
||||
public int MaxCharacterSlots
|
||||
{
|
||||
get => _maxCharacterSlots;
|
||||
set => _maxCharacterSlots = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
42
Content.Shared/Preferences/HumanoidCharacterAppearance.cs
Normal file
42
Content.Shared/Preferences/HumanoidCharacterAppearance.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using System;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public class HumanoidCharacterAppearance : ICharacterAppearance
|
||||
{
|
||||
public string HairStyleName { get; set; }
|
||||
public Color HairColor { get; set; }
|
||||
public string FacialHairStyleName { get; set; }
|
||||
public Color FacialHairColor { get; set; }
|
||||
public Color EyeColor { get; set; }
|
||||
public Color SkinColor { get; set; }
|
||||
|
||||
public static HumanoidCharacterAppearance Default()
|
||||
{
|
||||
return new HumanoidCharacterAppearance
|
||||
{
|
||||
HairStyleName = "Bald",
|
||||
HairColor = Color.Black,
|
||||
FacialHairStyleName = "Shaved",
|
||||
FacialHairColor = Color.Black,
|
||||
EyeColor = Color.Black,
|
||||
SkinColor = Color.Black
|
||||
};
|
||||
}
|
||||
|
||||
public bool MemberwiseEquals(ICharacterAppearance maybeOther)
|
||||
{
|
||||
if (!(maybeOther is HumanoidCharacterAppearance other)) return false;
|
||||
if (HairStyleName != other.HairStyleName) return false;
|
||||
if (HairColor != other.HairColor) return false;
|
||||
if (FacialHairStyleName != other.FacialHairStyleName) return false;
|
||||
if (FacialHairColor != other.FacialHairColor) return false;
|
||||
if (EyeColor != other.EyeColor) return false;
|
||||
if (SkinColor != other.SkinColor) return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
36
Content.Shared/Preferences/HumanoidCharacterProfile.cs
Normal file
36
Content.Shared/Preferences/HumanoidCharacterProfile.cs
Normal file
@@ -0,0 +1,36 @@
|
||||
using System;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
[Serializable, NetSerializable]
|
||||
public class HumanoidCharacterProfile : ICharacterProfile
|
||||
{
|
||||
public static HumanoidCharacterProfile Default()
|
||||
{
|
||||
return new HumanoidCharacterProfile
|
||||
{
|
||||
Name = "John Doe",
|
||||
Age = 18,
|
||||
Sex = Sex.Male,
|
||||
CharacterAppearance = HumanoidCharacterAppearance.Default()
|
||||
};
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
public Sex Sex { get; set; }
|
||||
public ICharacterAppearance CharacterAppearance { get; set; }
|
||||
|
||||
public bool MemberwiseEquals(ICharacterProfile maybeOther)
|
||||
{
|
||||
if (!(maybeOther is HumanoidCharacterProfile other)) return false;
|
||||
if (Name != other.Name) return false;
|
||||
if (Age != other.Age) return false;
|
||||
if (Sex != other.Sex) return false;
|
||||
if (CharacterAppearance is null)
|
||||
return other.CharacterAppearance is null;
|
||||
return CharacterAppearance.MemberwiseEquals(other.CharacterAppearance);
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Content.Shared/Preferences/ICharacterAppearance.cs
Normal file
7
Content.Shared/Preferences/ICharacterAppearance.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
public interface ICharacterAppearance
|
||||
{
|
||||
bool MemberwiseEquals(ICharacterAppearance other);
|
||||
}
|
||||
}
|
||||
7
Content.Shared/Preferences/ICharacterProfile.cs
Normal file
7
Content.Shared/Preferences/ICharacterProfile.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
public interface ICharacterProfile
|
||||
{
|
||||
bool MemberwiseEquals(ICharacterProfile other);
|
||||
}
|
||||
}
|
||||
54
Content.Shared/Preferences/PlayerPreferences.cs
Normal file
54
Content.Shared/Preferences/PlayerPreferences.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.Serialization;
|
||||
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
/// <summary>
|
||||
/// Contains all player characters and the index of the currently selected character.
|
||||
/// Serialized both over the network and to disk.
|
||||
/// </summary>
|
||||
[Serializable, NetSerializable]
|
||||
public class PlayerPreferences
|
||||
{
|
||||
public static PlayerPreferences Default()
|
||||
{
|
||||
return new PlayerPreferences
|
||||
{
|
||||
Characters = new List<ICharacterProfile>
|
||||
{
|
||||
HumanoidCharacterProfile.Default()
|
||||
},
|
||||
SelectedCharacterIndex = 0
|
||||
};
|
||||
}
|
||||
|
||||
private List<ICharacterProfile> _characters;
|
||||
private int _selectedCharacterIndex;
|
||||
|
||||
/// <summary>
|
||||
/// All player characters.
|
||||
/// </summary>
|
||||
public List<ICharacterProfile> Characters
|
||||
{
|
||||
get => _characters;
|
||||
set => _characters = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Index of the currently selected character.
|
||||
/// </summary>
|
||||
public int SelectedCharacterIndex
|
||||
{
|
||||
get => _selectedCharacterIndex;
|
||||
set => _selectedCharacterIndex = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the currently selected character.
|
||||
/// </summary>
|
||||
public ICharacterProfile SelectedCharacter => Characters.ElementAtOrDefault(SelectedCharacterIndex);
|
||||
}
|
||||
}
|
||||
8
Content.Shared/Preferences/Sex.cs
Normal file
8
Content.Shared/Preferences/Sex.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
public enum Sex
|
||||
{
|
||||
Male,
|
||||
Female
|
||||
}
|
||||
}
|
||||
133
Content.Shared/Preferences/SharedPreferencesManager.cs
Normal file
133
Content.Shared/Preferences/SharedPreferencesManager.cs
Normal file
@@ -0,0 +1,133 @@
|
||||
using System.IO;
|
||||
using Lidgren.Network;
|
||||
using Robust.Shared.Interfaces.Network;
|
||||
using Robust.Shared.Interfaces.Serialization;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Network;
|
||||
|
||||
namespace Content.Shared.Preferences
|
||||
{
|
||||
public abstract class SharedPreferencesManager
|
||||
{
|
||||
/// <summary>
|
||||
/// The server sends this before the client joins the lobby.
|
||||
/// </summary>
|
||||
protected class MsgPreferencesAndSettings : NetMessage
|
||||
{
|
||||
#region REQUIRED
|
||||
|
||||
public const MsgGroups GROUP = MsgGroups.Command;
|
||||
public const string NAME = nameof(MsgPreferencesAndSettings);
|
||||
|
||||
public MsgPreferencesAndSettings(INetChannel channel) : base(NAME, GROUP) { }
|
||||
|
||||
#endregion
|
||||
|
||||
public PlayerPreferences Preferences;
|
||||
public GameSettings Settings;
|
||||
|
||||
public override void ReadFromBuffer(NetIncomingMessage buffer)
|
||||
{
|
||||
var serializer = IoCManager.Resolve<IRobustSerializer>();
|
||||
var length = buffer.ReadInt32();
|
||||
var bytes = buffer.ReadBytes(length);
|
||||
using (var stream = new MemoryStream(bytes))
|
||||
{
|
||||
Preferences = serializer.Deserialize<PlayerPreferences>(stream);
|
||||
}
|
||||
length = buffer.ReadInt32();
|
||||
bytes = buffer.ReadBytes(length);
|
||||
using (var stream = new MemoryStream(bytes))
|
||||
{
|
||||
Settings = serializer.Deserialize<GameSettings>(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteToBuffer(NetOutgoingMessage buffer)
|
||||
{
|
||||
var serializer = IoCManager.Resolve<IRobustSerializer>();
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
serializer.Serialize(stream, Preferences);
|
||||
buffer.Write((int)stream.Length);
|
||||
buffer.Write(stream.ToArray());
|
||||
}
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
serializer.Serialize(stream, Settings);
|
||||
buffer.Write((int)stream.Length);
|
||||
buffer.Write(stream.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The client sends this to select a character slot.
|
||||
/// </summary>
|
||||
protected class MsgSelectCharacter : NetMessage
|
||||
{
|
||||
#region REQUIRED
|
||||
|
||||
public const MsgGroups GROUP = MsgGroups.Command;
|
||||
public const string NAME = nameof(MsgSelectCharacter);
|
||||
|
||||
public MsgSelectCharacter(INetChannel channel) : base(NAME, GROUP) { }
|
||||
|
||||
#endregion
|
||||
|
||||
public int SelectedCharacterIndex;
|
||||
|
||||
public override void ReadFromBuffer(NetIncomingMessage buffer)
|
||||
{
|
||||
SelectedCharacterIndex = buffer.ReadInt32();
|
||||
}
|
||||
|
||||
public override void WriteToBuffer(NetOutgoingMessage buffer)
|
||||
{
|
||||
buffer.Write(SelectedCharacterIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The client sends this to update a character profile.
|
||||
/// </summary>
|
||||
protected class MsgUpdateCharacter : NetMessage
|
||||
{
|
||||
#region REQUIRED
|
||||
|
||||
public const MsgGroups GROUP = MsgGroups.Command;
|
||||
public const string NAME = nameof(MsgUpdateCharacter);
|
||||
|
||||
public MsgUpdateCharacter(INetChannel channel) : base(NAME, GROUP) { }
|
||||
|
||||
#endregion
|
||||
|
||||
public int Slot;
|
||||
public ICharacterProfile Profile;
|
||||
|
||||
public override void ReadFromBuffer(NetIncomingMessage buffer)
|
||||
{
|
||||
Slot = buffer.ReadInt32();
|
||||
var serializer = IoCManager.Resolve<IRobustSerializer>();
|
||||
var length = buffer.ReadInt32();
|
||||
var bytes = buffer.ReadBytes(length);
|
||||
using (var stream = new MemoryStream(bytes))
|
||||
{
|
||||
Profile = serializer.Deserialize<ICharacterProfile>(stream);
|
||||
}
|
||||
}
|
||||
|
||||
public override void WriteToBuffer(NetOutgoingMessage buffer)
|
||||
{
|
||||
buffer.Write(Slot);
|
||||
var serializer = IoCManager.Resolve<IRobustSerializer>();
|
||||
using (var stream = new MemoryStream())
|
||||
{
|
||||
serializer.Serialize(stream, Profile);
|
||||
buffer.Write((int)stream.Length);
|
||||
buffer.Write(stream.ToArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user