diff --git a/Content.Server.Database/Configuration.cs b/Content.Server.Database/Configuration.cs new file mode 100644 index 0000000000..1541b42ed8 --- /dev/null +++ b/Content.Server.Database/Configuration.cs @@ -0,0 +1,70 @@ +using Microsoft.EntityFrameworkCore; +using Npgsql; + +namespace Content.Server.Database +{ + public interface IDatabaseConfiguration + { + DbContextOptions Options { get; } + } + + public class PostgresConfiguration : IDatabaseConfiguration + { + private readonly string _database; + private readonly string _host; + private readonly string _password; + private readonly int _port; + private readonly string _username; + + public PostgresConfiguration(string host, + int port, + string database, + string username, + string password) + { + _host = host; + _port = port; + _database = database; + _username = username; + _password = password; + } + + public DbContextOptions Options + { + get + { + var optionsBuilder = new DbContextOptionsBuilder(); + var connectionString = new NpgsqlConnectionStringBuilder + { + Host = _host, + Port = _port, + Database = _database, + Username = _username, + Password = _password + }.ConnectionString; + optionsBuilder.UseNpgsql(connectionString); + return optionsBuilder.Options; + } + } + } + + public class SqliteConfiguration : IDatabaseConfiguration + { + private readonly string _databaseFilePath; + + public SqliteConfiguration(string databaseFilePath) + { + _databaseFilePath = databaseFilePath; + } + + public DbContextOptions Options + { + get + { + var optionsBuilder = new DbContextOptionsBuilder(); + optionsBuilder.UseSqlite($"Data Source={_databaseFilePath}"); + return optionsBuilder.Options; + } + } + } +} diff --git a/Content.Server.Database/Content.Server.Database.csproj b/Content.Server.Database/Content.Server.Database.csproj index 8123f496ed..9d699ad591 100644 --- a/Content.Server.Database/Content.Server.Database.csproj +++ b/Content.Server.Database/Content.Server.Database.csproj @@ -19,6 +19,7 @@ all + diff --git a/Content.Server.Database/Migrations/Postgres/20200124133512_InitialPg.Designer.cs b/Content.Server.Database/Migrations/Postgres/20200124133512_InitialPg.Designer.cs new file mode 100644 index 0000000000..ada793d022 --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20200124133512_InitialPg.Designer.cs @@ -0,0 +1,151 @@ +// +using Content.Server.Database; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + [DbContext(typeof(PostgresPreferencesDbContext))] + [Migration("20200124133512_InitialPg")] + partial class InitialPg + { + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.Property("HumanoidProfileId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Age") + .HasColumnType("integer"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("text"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreferenceUnavailable") + .HasColumnType("integer"); + + b.Property("PrefsId") + .HasColumnType("integer"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("text"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("Slot") + .HasColumnType("integer"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("HumanoidProfileId"); + + b.HasIndex("PrefsId"); + + b.ToTable("HumanoidProfile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("JobId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("ProfileHumanoidProfileId") + .HasColumnType("integer"); + + b.HasKey("JobId"); + + b.HasIndex("ProfileHumanoidProfileId"); + + b.ToTable("Job"); + }); + + modelBuilder.Entity("Content.Server.Database.Prefs", b => + { + b.Property("PrefsId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("SelectedCharacterSlot") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("PrefsId"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Preferences"); + }); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.HasOne("Content.Server.Database.Prefs", "Prefs") + .WithMany("HumanoidProfiles") + .HasForeignKey("PrefsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileHumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/20200124133512_InitialPg.cs b/Content.Server.Database/Migrations/Postgres/20200124133512_InitialPg.cs new file mode 100644 index 0000000000..48dbf09481 --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/20200124133512_InitialPg.cs @@ -0,0 +1,105 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + public partial class InitialPg : Migration + { + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Preferences", + columns: table => new + { + PrefsId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Username = table.Column(nullable: false), + SelectedCharacterSlot = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Preferences", x => x.PrefsId); + }); + + migrationBuilder.CreateTable( + name: "HumanoidProfile", + columns: table => new + { + HumanoidProfileId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Slot = table.Column(nullable: false), + SlotName = table.Column(nullable: false), + CharacterName = table.Column(nullable: false), + Age = table.Column(nullable: false), + Sex = table.Column(nullable: false), + HairName = table.Column(nullable: false), + HairColor = table.Column(nullable: false), + FacialHairName = table.Column(nullable: false), + FacialHairColor = table.Column(nullable: false), + EyeColor = table.Column(nullable: false), + SkinColor = table.Column(nullable: false), + PreferenceUnavailable = table.Column(nullable: false), + PrefsId = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_HumanoidProfile", x => x.HumanoidProfileId); + table.ForeignKey( + name: "FK_HumanoidProfile_Preferences_PrefsId", + column: x => x.PrefsId, + principalTable: "Preferences", + principalColumn: "PrefsId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateTable( + name: "Job", + columns: table => new + { + JobId = table.Column(nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + ProfileHumanoidProfileId = table.Column(nullable: false), + JobName = table.Column(nullable: false), + Priority = table.Column(nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Job", x => x.JobId); + table.ForeignKey( + name: "FK_Job_HumanoidProfile_ProfileHumanoidProfileId", + column: x => x.ProfileHumanoidProfileId, + principalTable: "HumanoidProfile", + principalColumn: "HumanoidProfileId", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_HumanoidProfile_PrefsId", + table: "HumanoidProfile", + column: "PrefsId"); + + migrationBuilder.CreateIndex( + name: "IX_Job_ProfileHumanoidProfileId", + table: "Job", + column: "ProfileHumanoidProfileId"); + + migrationBuilder.CreateIndex( + name: "IX_Preferences_Username", + table: "Preferences", + column: "Username", + unique: true); + } + + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Job"); + + migrationBuilder.DropTable( + name: "HumanoidProfile"); + + migrationBuilder.DropTable( + name: "Preferences"); + } + } +} diff --git a/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs new file mode 100644 index 0000000000..5baa572a5c --- /dev/null +++ b/Content.Server.Database/Migrations/Postgres/PostgresPreferencesDbContextModelSnapshot.cs @@ -0,0 +1,148 @@ +// + +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +namespace Content.Server.Database.Migrations.Postgres +{ + [DbContext(typeof(PostgresPreferencesDbContext))] + partial class PostgresPreferencesDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn) + .HasAnnotation("ProductVersion", "3.1.0") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.Property("HumanoidProfileId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("Age") + .HasColumnType("integer"); + + b.Property("CharacterName") + .IsRequired() + .HasColumnType("text"); + + b.Property("EyeColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("FacialHairColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("FacialHairName") + .IsRequired() + .HasColumnType("text"); + + b.Property("HairColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("HairName") + .IsRequired() + .HasColumnType("text"); + + b.Property("PreferenceUnavailable") + .HasColumnType("integer"); + + b.Property("PrefsId") + .HasColumnType("integer"); + + b.Property("Sex") + .IsRequired() + .HasColumnType("text"); + + b.Property("SkinColor") + .IsRequired() + .HasColumnType("text"); + + b.Property("Slot") + .HasColumnType("integer"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("HumanoidProfileId"); + + b.HasIndex("PrefsId"); + + b.ToTable("HumanoidProfile"); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.Property("JobId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("JobName") + .IsRequired() + .HasColumnType("text"); + + b.Property("Priority") + .HasColumnType("integer"); + + b.Property("ProfileHumanoidProfileId") + .HasColumnType("integer"); + + b.HasKey("JobId"); + + b.HasIndex("ProfileHumanoidProfileId"); + + b.ToTable("Job"); + }); + + modelBuilder.Entity("Content.Server.Database.Prefs", b => + { + b.Property("PrefsId") + .ValueGeneratedOnAdd() + .HasColumnType("integer") + .HasAnnotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn); + + b.Property("SelectedCharacterSlot") + .HasColumnType("integer"); + + b.Property("Username") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("PrefsId"); + + b.HasIndex("Username") + .IsUnique(); + + b.ToTable("Preferences"); + }); + + modelBuilder.Entity("Content.Server.Database.HumanoidProfile", b => + { + b.HasOne("Content.Server.Database.Prefs", "Prefs") + .WithMany("HumanoidProfiles") + .HasForeignKey("PrefsId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); + + modelBuilder.Entity("Content.Server.Database.Job", b => + { + b.HasOne("Content.Server.Database.HumanoidProfile", "Profile") + .WithMany("Jobs") + .HasForeignKey("ProfileHumanoidProfileId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Content.Server.Database/Migrations/20200118020532_initial.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20200118020532_initial.Designer.cs similarity index 100% rename from Content.Server.Database/Migrations/20200118020532_initial.Designer.cs rename to Content.Server.Database/Migrations/Sqlite/20200118020532_initial.Designer.cs diff --git a/Content.Server.Database/Migrations/20200118020532_initial.cs b/Content.Server.Database/Migrations/Sqlite/20200118020532_initial.cs similarity index 100% rename from Content.Server.Database/Migrations/20200118020532_initial.cs rename to Content.Server.Database/Migrations/Sqlite/20200118020532_initial.cs diff --git a/Content.Server.Database/Migrations/20200118195640_jobs.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20200118195640_jobs.Designer.cs similarity index 100% rename from Content.Server.Database/Migrations/20200118195640_jobs.Designer.cs rename to Content.Server.Database/Migrations/Sqlite/20200118195640_jobs.Designer.cs diff --git a/Content.Server.Database/Migrations/20200118195640_jobs.cs b/Content.Server.Database/Migrations/Sqlite/20200118195640_jobs.cs similarity index 100% rename from Content.Server.Database/Migrations/20200118195640_jobs.cs rename to Content.Server.Database/Migrations/Sqlite/20200118195640_jobs.cs diff --git a/Content.Server.Database/Migrations/20200119103426_preferenceUnavailable.Designer.cs b/Content.Server.Database/Migrations/Sqlite/20200119103426_preferenceUnavailable.Designer.cs similarity index 100% rename from Content.Server.Database/Migrations/20200119103426_preferenceUnavailable.Designer.cs rename to Content.Server.Database/Migrations/Sqlite/20200119103426_preferenceUnavailable.Designer.cs diff --git a/Content.Server.Database/Migrations/20200119103426_preferenceUnavailable.cs b/Content.Server.Database/Migrations/Sqlite/20200119103426_preferenceUnavailable.cs similarity index 100% rename from Content.Server.Database/Migrations/20200119103426_preferenceUnavailable.cs rename to Content.Server.Database/Migrations/Sqlite/20200119103426_preferenceUnavailable.cs diff --git a/Content.Server.Database/Migrations/PreferencesDbContextModelSnapshot.cs b/Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs similarity index 98% rename from Content.Server.Database/Migrations/PreferencesDbContextModelSnapshot.cs rename to Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs index 271ec78c0b..2375a45c8a 100644 --- a/Content.Server.Database/Migrations/PreferencesDbContextModelSnapshot.cs +++ b/Content.Server.Database/Migrations/Sqlite/SqlitePreferencesDbContextModelSnapshot.cs @@ -1,8 +1,7 @@ // -using Content.Server.Database; + using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage.ValueConversion; namespace Content.Server.Database.Migrations { diff --git a/Content.Server.Database/Model.cs b/Content.Server.Database/Model.cs index 2ea94a49b9..d971002adc 100644 --- a/Content.Server.Database/Model.cs +++ b/Content.Server.Database/Model.cs @@ -3,16 +3,53 @@ using Microsoft.EntityFrameworkCore; namespace Content.Server.Database { - public class PreferencesDbContext : DbContext + public class PostgresPreferencesDbContext : PreferencesDbContext { // This is used by the "dotnet ef" CLI tool. - public PreferencesDbContext() : - base(new DbContextOptionsBuilder().UseSqlite("Data Source=:memory:").Options) + public PostgresPreferencesDbContext() { } + protected override void OnConfiguring(DbContextOptionsBuilder options) + { + if(!InitializedWithOptions) + options.UseNpgsql("dummy connection string"); + } + public PostgresPreferencesDbContext(DbContextOptions options) : base(options) + { + } + } + + public class SqlitePreferencesDbContext : PreferencesDbContext + { + public SqlitePreferencesDbContext() + { + } + protected override void OnConfiguring(DbContextOptionsBuilder options) + { + if (!InitializedWithOptions) + options.UseSqlite("dummy connection string"); + } + + public SqlitePreferencesDbContext(DbContextOptions options) : base(options) + { + } + } + + public abstract class PreferencesDbContext : DbContext + { + /// + /// The "dotnet ef" CLI tool uses the parameter-less constructor. + /// When that happens we want to supply the via . + /// To use the context within the application, the options need to be passed the constructor instead. + /// + protected readonly bool InitializedWithOptions; + public PreferencesDbContext() + { + } public PreferencesDbContext(DbContextOptions options) : base(options) { + InitializedWithOptions = true; } public DbSet Preferences { get; set; } = null!; diff --git a/Content.Server.Database/PrefsDb.cs b/Content.Server.Database/PrefsDb.cs index c4d6d112ba..ea47678d93 100644 --- a/Content.Server.Database/PrefsDb.cs +++ b/Content.Server.Database/PrefsDb.cs @@ -1,3 +1,4 @@ +using System; using System.Linq; using Microsoft.EntityFrameworkCore; @@ -7,12 +8,15 @@ namespace Content.Server.Database { private readonly PreferencesDbContext _prefsCtx; - public PrefsDb(string dbPath) + public PrefsDb(IDatabaseConfiguration dbConfig) { - var optionsBuilder = new DbContextOptionsBuilder(); - optionsBuilder.UseSqlite($"Data Source={dbPath}"); - - _prefsCtx = new PreferencesDbContext(optionsBuilder.Options); + _prefsCtx = dbConfig switch + { + SqliteConfiguration sqlite => (PreferencesDbContext) new SqlitePreferencesDbContext( + sqlite.Options), + PostgresConfiguration postgres => new PostgresPreferencesDbContext(postgres.Options), + _ => throw new NotImplementedException() + }; _prefsCtx.Database.Migrate(); } diff --git a/Content.Server/Interfaces/IServerPreferencesManager.cs b/Content.Server/Interfaces/IServerPreferencesManager.cs index 0cf13fda53..71b91af8f9 100644 --- a/Content.Server/Interfaces/IServerPreferencesManager.cs +++ b/Content.Server/Interfaces/IServerPreferencesManager.cs @@ -8,6 +8,5 @@ namespace Content.Server.Interfaces void Initialize(); void OnClientConnected(IPlayerSession session); PlayerPreferences GetPreferences(string username); - void SavePreferences(PlayerPreferences prefs, string username); } } diff --git a/Content.Server/Preferences/PreferencesDatabase.cs b/Content.Server/Preferences/PreferencesDatabase.cs index ebf1baf54e..2e5e586e02 100644 --- a/Content.Server/Preferences/PreferencesDatabase.cs +++ b/Content.Server/Preferences/PreferencesDatabase.cs @@ -16,10 +16,10 @@ namespace Content.Server.Preferences private readonly int _maxCharacterSlots; private readonly PrefsDb _prefsDb; - public PreferencesDatabase(string databaseFilePath, int maxCharacterSlots) + public PreferencesDatabase(IDatabaseConfiguration dbConfig, int maxCharacterSlots) { _maxCharacterSlots = maxCharacterSlots; - _prefsDb = new PrefsDb(databaseFilePath); + _prefsDb = new PrefsDb(dbConfig); } public PlayerPreferences GetPlayerPreferences(string username) diff --git a/Content.Server/Preferences/ServerPreferencesManager.cs b/Content.Server/Preferences/ServerPreferencesManager.cs index 37d71a8646..064f3ce12d 100644 --- a/Content.Server/Preferences/ServerPreferencesManager.cs +++ b/Content.Server/Preferences/ServerPreferencesManager.cs @@ -1,4 +1,6 @@ +using System; using System.IO; +using Content.Server.Database; using Content.Server.Interfaces; using Content.Shared.Preferences; using Robust.Server.Interfaces.Player; @@ -31,14 +33,42 @@ namespace Content.Server.Preferences HandleUpdateCharacterMessage); _configuration.RegisterCVar("game.maxcharacterslots", 10); - _configuration.RegisterCVar("game.preferencesdbpath", "preferences.db"); + _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 configPreferencesDbPath = _configuration.GetCVar("game.preferencesdbpath"); - var finalPreferencesDbPath = Path.Combine(_resourceManager.UserData.RootDir, configPreferencesDbPath); + 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(finalPreferencesDbPath, maxCharacterSlots); + _preferencesDb = new PreferencesDatabase(dbConfig, maxCharacterSlots); } private void HandleSelectCharacterMessage(MsgSelectCharacter message) @@ -79,25 +109,12 @@ namespace Content.Server.Preferences var prefs = GetFromSql(username); if (prefs is null) { - prefs = PlayerPreferences.Default(); // TODO: Create random character instead - SavePreferences(prefs, username); + _preferencesDb.SaveSelectedCharacterIndex(username, 0); + _preferencesDb.SaveCharacterSlot(username, HumanoidCharacterProfile.Default(), 0); + prefs = GetFromSql(username); } return prefs; } - - /// - /// Saves the given preferences to storage. - /// - public void SavePreferences(PlayerPreferences prefs, string username) - { - _preferencesDb.SaveSelectedCharacterIndex(username, prefs.SelectedCharacterIndex); - var index = 0; - foreach (var character in prefs.Characters) - { - _preferencesDb.SaveCharacterSlot(username, character, index); - index++; - } - } } } diff --git a/Content.Shared/Preferences/PlayerPreferences.cs b/Content.Shared/Preferences/PlayerPreferences.cs index 25a0adb811..5655e72c61 100644 --- a/Content.Shared/Preferences/PlayerPreferences.cs +++ b/Content.Shared/Preferences/PlayerPreferences.cs @@ -38,15 +38,6 @@ namespace Content.Shared.Preferences public int FirstEmptySlot => IndexOfCharacter(null); - public static PlayerPreferences Default() - { - return new PlayerPreferences(new List - { - HumanoidCharacterProfile.Default() - }, - 0); - } - public int IndexOfCharacter(ICharacterProfile profile) { return _characters.FindIndex(x => x == profile); diff --git a/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs b/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs index 031654b3d8..c047a1af07 100644 --- a/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs +++ b/Content.Tests/Server/Preferences/PreferencesDatabaseTests.cs @@ -1,6 +1,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using Content.Server.Database; using Content.Server.Preferences; using Content.Shared; using Content.Shared.Preferences; @@ -39,7 +40,7 @@ namespace Content.Tests.Server.Preferences private static PreferencesDatabase GetDb() { - return new PreferencesDatabase(Path.GetTempFileName(), MaxCharacterSlots); + return new PreferencesDatabase(new SqliteConfiguration(Path.GetTempFileName()), MaxCharacterSlots); } [Test]