using System; using System.IO; using Content.Server.Database; using Content.Server.Interfaces; using Content.Shared.Preferences; using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.Configuration; using Robust.Shared.Interfaces.Network; using Robust.Shared.Interfaces.Resources; using Robust.Shared.IoC; namespace Content.Server.Preferences { /// /// Sends before the client joins the lobby. /// Receives and at any time. /// public class ServerPreferencesManager : SharedPreferencesManager, IServerPreferencesManager { #pragma warning disable 649 [Dependency] private readonly IServerNetManager _netManager; [Dependency] private readonly IConfigurationManager _configuration; [Dependency] private readonly IResourceManager _resourceManager; #pragma warning restore 649 private PreferencesDatabase _preferencesDb; public void Initialize() { _netManager.RegisterNetMessage(nameof(MsgPreferencesAndSettings)); _netManager.RegisterNetMessage(nameof(MsgSelectCharacter), HandleSelectCharacterMessage); _netManager.RegisterNetMessage(nameof(MsgUpdateCharacter), HandleUpdateCharacterMessage); _configuration.RegisterCVar("game.maxcharacterslots", 10); _configuration.RegisterCVar("database.prefs_engine", "sqlite"); _configuration.RegisterCVar("database.prefs_sqlite_dbpath", "preferences.db"); _configuration.RegisterCVar("database.prefs_pg_host", "localhost"); _configuration.RegisterCVar("database.prefs_pg_port", 5432); _configuration.RegisterCVar("database.prefs_pg_database", "ss14_prefs"); _configuration.RegisterCVar("database.prefs_pg_username", string.Empty); _configuration.RegisterCVar("database.prefs_pg_password", string.Empty); var engine = _configuration.GetCVar("database.prefs_engine").ToLower(); IDatabaseConfiguration dbConfig; switch (engine) { case "sqlite": var configPreferencesDbPath = _configuration.GetCVar("database.prefs_sqlite_dbpath"); var finalPreferencesDbPath = Path.Combine(_resourceManager.UserData.RootDir, configPreferencesDbPath); dbConfig = new SqliteConfiguration( finalPreferencesDbPath ); break; case "postgres": dbConfig = new PostgresConfiguration( _configuration.GetCVar("database.prefs_pg_host"), _configuration.GetCVar("database.prefs_pg_port"), _configuration.GetCVar("database.prefs_pg_database"), _configuration.GetCVar("database.prefs_pg_username"), _configuration.GetCVar("database.prefs_pg_password") ); break; default: throw new NotImplementedException("Unknown database engine {engine}."); } var maxCharacterSlots = _configuration.GetCVar("game.maxcharacterslots"); _preferencesDb = new PreferencesDatabase(dbConfig, maxCharacterSlots); } private void HandleSelectCharacterMessage(MsgSelectCharacter message) { _preferencesDb.SaveSelectedCharacterIndex(message.MsgChannel.SessionId.Username, message.SelectedCharacterIndex); } private void HandleUpdateCharacterMessage(MsgUpdateCharacter message) { _preferencesDb.SaveCharacterSlot(message.MsgChannel.SessionId.Username, message.Profile, message.Slot); } public void OnClientConnected(IPlayerSession session) { var msg = _netManager.CreateNetMessage(); msg.Preferences = GetPreferences(session.SessionId.Username); msg.Settings = new GameSettings { MaxCharacterSlots = _configuration.GetCVar("game.maxcharacterslots") }; _netManager.ServerSendMessage(msg, session.ConnectedClient); } /// /// Returns the requested or null if not found. /// private PlayerPreferences GetFromSql(string username) { return _preferencesDb.GetPlayerPreferences(username); } /// /// Retrieves preferences for the given username from storage. /// Creates and saves default preferences if they are not found, then returns them. /// public PlayerPreferences GetPreferences(string username) { var prefs = GetFromSql(username); if (prefs is null) { _preferencesDb.SaveSelectedCharacterIndex(username, 0); _preferencesDb.SaveCharacterSlot(username, HumanoidCharacterProfile.Default(), 0); prefs = GetFromSql(username); } return prefs; } } }