From ffed3a8b4a821da18a71bdd67167067c6613df2f Mon Sep 17 00:00:00 2001 From: CyberL1 Date: Tue, 21 May 2024 10:28:49 +0200 Subject: [PATCH] feat: slot settings --- .../Controllers/WorldsController.cs | 101 ++++- Minecraft-Realms-Emulator/Data/DataContext.cs | 1 + Minecraft-Realms-Emulator/Entities/Slot.cs | 9 +- Minecraft-Realms-Emulator/Entities/World.cs | 7 +- .../20240521071345_Slots_Table.Designer.cs | 382 ++++++++++++++++++ .../Migrations/20240521071345_Slots_Table.cs | 70 ++++ ..._World_ActiveVersion_From_Slot.Designer.cs | 378 +++++++++++++++++ ...521080804_World_ActiveVersion_From_Slot.cs | 29 ++ .../Migrations/DataContextModelSnapshot.cs | 77 +++- .../Requests/SlotOptionsRequest.cs | 17 + .../Responses/SlotsResponse.cs | 8 + .../Responses/WorldResponse.cs | 6 +- 12 files changed, 1054 insertions(+), 31 deletions(-) create mode 100644 Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.Designer.cs create mode 100644 Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.cs create mode 100644 Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.Designer.cs create mode 100644 Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.cs create mode 100644 Minecraft-Realms-Emulator/Requests/SlotOptionsRequest.cs create mode 100644 Minecraft-Realms-Emulator/Responses/SlotsResponse.cs diff --git a/Minecraft-Realms-Emulator/Controllers/WorldsController.cs b/Minecraft-Realms-Emulator/Controllers/WorldsController.cs index 6b749b4..8493118 100644 --- a/Minecraft-Realms-Emulator/Controllers/WorldsController.cs +++ b/Minecraft-Realms-Emulator/Controllers/WorldsController.cs @@ -31,8 +31,8 @@ namespace Minecraft_Realms_Emulator.Controllers string playerName = cookie.Split(";")[1].Split("=")[1]; string gameVersion = cookie.Split(";")[2].Split("=")[1]; - var ownedWorlds = await _context.Worlds.Where(w => w.OwnerUUID == playerUUID).Include(w => w.Subscription).ToListAsync(); - var memberWorlds = await _context.Players.Where(p => p.Uuid == playerUUID && p.Accepted).Include(p => p.World.Subscription).Select(p => p.World).ToListAsync(); + var ownedWorlds = await _context.Worlds.Where(w => w.OwnerUUID == playerUUID).Include(w => w.Subscription).Include(w => w.Slots).ToListAsync(); + var memberWorlds = await _context.Players.Where(p => p.Uuid == playerUUID && p.Accepted).Include(p => p.World.Subscription).Include(p => p.World.Slots).Select(p => p.World).ToListAsync(); List allWorlds = []; @@ -51,8 +51,7 @@ namespace Minecraft_Realms_Emulator.Controllers MinigameName = null, MinigameImage = null, ActiveSlot = 1, - Member = false, - ActiveVersion = gameVersion + Member = false }; ownedWorlds.Add(world); @@ -63,7 +62,9 @@ namespace Minecraft_Realms_Emulator.Controllers foreach (var world in ownedWorlds) { - int versionsCompared = SemVersion.Parse(gameVersion, SemVersionStyles.Strict).ComparePrecedenceTo(SemVersion.Parse(world.ActiveVersion, SemVersionStyles.Strict)); + Slot activeSlot = world.Slots.Find(s => s.SlotId == world.ActiveSlot); + + int versionsCompared = SemVersion.Parse(gameVersion, SemVersionStyles.Strict).ComparePrecedenceTo(SemVersion.Parse(activeSlot?.Version ?? gameVersion, SemVersionStyles.Strict)); string isCompatible = versionsCompared == 0 ? "COMPATIBLE" : versionsCompared < 0 ? "NEEDS_DOWNGRADE" : "NEEDS_UPGRADE"; WorldResponse response = new() @@ -82,7 +83,7 @@ namespace Minecraft_Realms_Emulator.Controllers ActiveSlot = world.ActiveSlot, Member = world.Member, Players = world.Players, - ActiveVersion = world.ActiveVersion, + ActiveVersion = activeSlot?.Version ?? gameVersion, Compatibility = isCompatible }; @@ -98,7 +99,9 @@ namespace Minecraft_Realms_Emulator.Controllers foreach (var world in memberWorlds) { - int versionsCompared = SemVersion.Parse(gameVersion, SemVersionStyles.OptionalPatch).ComparePrecedenceTo(SemVersion.Parse(world.ActiveVersion, SemVersionStyles.OptionalPatch)); + Slot activeSlot = world.Slots.Find(s => s.SlotId == world.ActiveSlot); + + int versionsCompared = SemVersion.Parse(gameVersion, SemVersionStyles.OptionalPatch).ComparePrecedenceTo(SemVersion.Parse(activeSlot.Version, SemVersionStyles.OptionalPatch)); string isCompatible = versionsCompared == 0 ? "COMPATIBLE" : versionsCompared < 0 ? "NEEDS_DOWNGRADE" : "NEEDS_UPGRADE"; WorldResponse response = new() @@ -120,7 +123,7 @@ namespace Minecraft_Realms_Emulator.Controllers DaysLeft = 0, Expired = ((DateTimeOffset)world.Subscription.StartDate.AddDays(30) - DateTime.Today).Days < 0, ExpiredTrial = false, - ActiveVersion = world.ActiveVersion, + ActiveVersion = activeSlot.Version, Compatibility = isCompatible }; @@ -141,13 +144,40 @@ namespace Minecraft_Realms_Emulator.Controllers string cookie = Request.Headers.Cookie; string gameVersion = cookie.Split(";")[2].Split("=")[1]; - var world = await _context.Worlds.Include(w => w.Players).Include(w => w.Subscription).FirstOrDefaultAsync(w => w.Id == id); + var world = await _context.Worlds.Include(w => w.Players).Include(w => w.Subscription).Include(w => w.Slots).FirstOrDefaultAsync(w => w.Id == id); if (world?.Subscription == null) return NotFound("World not found"); - int versionsCompared = SemVersion.Parse(gameVersion, SemVersionStyles.OptionalPatch).ComparePrecedenceTo(SemVersion.Parse(world.ActiveVersion, SemVersionStyles.OptionalPatch)); + Slot activeSlot = world.Slots.Find(s => s.SlotId == world.ActiveSlot); + + int versionsCompared = SemVersion.Parse(gameVersion, SemVersionStyles.OptionalPatch).ComparePrecedenceTo(SemVersion.Parse(activeSlot.Version, SemVersionStyles.OptionalPatch)); string isCompatible = versionsCompared == 0 ? "COMPATIBLE" : versionsCompared < 0 ? "NEEDS_DOWNGRADE" : "NEEDS_UPGRADE"; + List slots = []; + + foreach (var slot in world.Slots) + { + slots.Add(new SlotsResponse() + { + SlotId = slot.SlotId, + Options = JsonConvert.SerializeObject(new + { + slotName = slot.SlotName, + gameMode = slot.GameMode, + difficulty = slot.Difficulty, + spawnProtection = slot.SpawnProtection, + forceGameMode = slot.ForceGameMode, + pvp = slot.Pvp, + spawnAnimals = slot.SpawnAnimals, + spawnMonsters = slot.SpawnMonsters, + spawnNPCs = slot.SpawnNPCs, + commandBlocks = slot.CommandBlocks, + version = slot.Version, + compatibility = isCompatible + }) + }); + } + WorldResponse response = new() { Id = world.Id, @@ -162,13 +192,13 @@ namespace Minecraft_Realms_Emulator.Controllers MinigameName = world.MinigameName, MinigameImage = world.MinigameImage, ActiveSlot = world.ActiveSlot, - Slots = world.Slots, + Slots = slots, Member = world.Member, Players = world.Players, DaysLeft = ((DateTimeOffset)world.Subscription.StartDate.AddDays(30) - DateTime.Today).Days, Expired = ((DateTimeOffset)world.Subscription.StartDate.AddDays(30) - DateTime.Today).Days < 0, ExpiredTrial = false, - ActiveVersion = world.ActiveVersion, + ActiveVersion = activeSlot.Version, Compatibility = isCompatible }; @@ -178,6 +208,9 @@ namespace Minecraft_Realms_Emulator.Controllers [HttpPost("{id}/initialize")] public async Task> Initialize(int id, WorldCreateRequest body) { + string cookie = Request.Headers.Cookie; + string gameVersion = cookie.Split(";")[2].Split("=")[1]; + var worlds = await _context.Worlds.ToListAsync(); var world = worlds.Find(w => w.Id == id); @@ -204,10 +237,28 @@ namespace Minecraft_Realms_Emulator.Controllers Address = JsonConvert.DeserializeObject(defaultServerAddress.Value) }; + Slot slot = new() + { + World = world, + SlotId = 1, + SlotName = "", + Version = gameVersion, + GameMode = 0, + Difficulty = 2, + SpawnProtection = 0, + ForceGameMode = false, + Pvp = true, + SpawnAnimals = true, + SpawnMonsters = true, + SpawnNPCs = true, + CommandBlocks = false + }; + _context.Worlds.Update(world); _context.Subscriptions.Add(subscription); _context.Connections.Add(connection); + _context.Slots.Add(slot); _context.SaveChanges(); @@ -271,9 +322,31 @@ namespace Minecraft_Realms_Emulator.Controllers } [HttpPost("{wId}/slot/{sId}")] - public bool U(int wId, int sId, object o) + public async Task> UpdateSlotAsync(int wId, int sId, SlotOptionsRequest body) { - Console.WriteLine(o); + var slots = await _context.Slots.Where(s => s.World.Id == wId).ToListAsync(); + var slot = slots.Find(s => s.SlotId == sId); + + slot.SlotName = body.SlotName; + slot.GameMode = body.GameMode; + slot.Difficulty = body.Difficulty; + slot.SpawnProtection = body.SpawnProtection; + slot.ForceGameMode = body.ForceGameMode; + slot.Pvp = body.Pvp; + slot.SpawnAnimals = body.SpawnAnimals; + slot.SpawnMonsters = body.SpawnMonsters; + slot.SpawnNPCs = body.SpawnNPCs; + slot.CommandBlocks = body.CommandBlocks; + + _context.SaveChanges(); + + return Ok(true); + } + + [HttpPut("{wId}/slot/{sId}")] + public bool SwitchSlot(int wId, int sId) + { + Console.WriteLine($"Switching world {wId} to slot {sId}"); return true; } diff --git a/Minecraft-Realms-Emulator/Data/DataContext.cs b/Minecraft-Realms-Emulator/Data/DataContext.cs index e2562b8..bd720e6 100644 --- a/Minecraft-Realms-Emulator/Data/DataContext.cs +++ b/Minecraft-Realms-Emulator/Data/DataContext.cs @@ -12,5 +12,6 @@ namespace Minecraft_Realms_Emulator.Data public DbSet Invites { get; set; } public DbSet Players { get; set; } public DbSet Configuration { get; set; } + public DbSet Slots { get; set; } } } diff --git a/Minecraft-Realms-Emulator/Entities/Slot.cs b/Minecraft-Realms-Emulator/Entities/Slot.cs index e08d892..1bc697f 100644 --- a/Minecraft-Realms-Emulator/Entities/Slot.cs +++ b/Minecraft-Realms-Emulator/Entities/Slot.cs @@ -1,8 +1,11 @@ -namespace Minecraft_Realms_Emulator.Entities +using Minecraft_Realms_Emulator.Requests; + +namespace Minecraft_Realms_Emulator.Entities { - public class Slot + public class Slot : SlotOptionsRequest { + public int Id { get; set; } + public World World { get; set; } = null!; public int SlotId { get; set; } - public string Options { get; set; } = "{}"; } } diff --git a/Minecraft-Realms-Emulator/Entities/World.cs b/Minecraft-Realms-Emulator/Entities/World.cs index c14b5b6..6bd6c51 100644 --- a/Minecraft-Realms-Emulator/Entities/World.cs +++ b/Minecraft-Realms-Emulator/Entities/World.cs @@ -1,6 +1,4 @@ -using System.Text.Json; - -namespace Minecraft_Realms_Emulator.Entities +namespace Minecraft_Realms_Emulator.Entities { public class World { @@ -18,8 +16,7 @@ namespace Minecraft_Realms_Emulator.Entities public int? MinigameId { get; set; } public string? MinigameImage { get; set; } public int ActiveSlot { get; set; } = 1; - public JsonDocument[] Slots { get; set; } = []; + public List Slots { get; set; } = []; public bool Member { get; set; } = false; - public string ActiveVersion { get; set; } = null!; } } \ No newline at end of file diff --git a/Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.Designer.cs b/Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.Designer.cs new file mode 100644 index 0000000..3e0679d --- /dev/null +++ b/Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.Designer.cs @@ -0,0 +1,382 @@ +// +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Minecraft_Realms_Emulator.Data; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Minecraft_Realms_Emulator.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240521071345_Slots_Table")] + partial class Slots_Table + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Backup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BackupId") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModifiedDate") + .HasColumnType("bigint"); + + b.Property("Metadata") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Size") + .HasColumnType("integer"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Backups"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Configuration", b => + { + b.Property("Key") + .HasColumnType("text"); + + b.Property("Value") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Key"); + + b.ToTable("Configuration"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Connection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("text"); + + b.Property("PendingUpdate") + .HasColumnType("boolean"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Connections"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Invite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("timestamp with time zone"); + + b.Property("InvitationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("RecipeintUUID") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Invites"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Accepted") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Online") + .HasColumnType("boolean"); + + b.Property("Operator") + .HasColumnType("boolean"); + + b.Property("Permission") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uuid") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Players"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Slot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CommandBlocks") + .HasColumnType("boolean"); + + b.Property("Difficulty") + .HasColumnType("integer"); + + b.Property("ForceGameMode") + .HasColumnType("boolean"); + + b.Property("GameMode") + .HasColumnType("integer"); + + b.Property("Pvp") + .HasColumnType("boolean"); + + b.Property("SlotId") + .HasColumnType("integer"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("text"); + + b.Property("SpawnAnimals") + .HasColumnType("boolean"); + + b.Property("SpawnMonsters") + .HasColumnType("boolean"); + + b.Property("SpawnNPCs") + .HasColumnType("boolean"); + + b.Property("SpawnProtection") + .HasColumnType("integer"); + + b.Property("Version") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Slots"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Subscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SubscriptionType") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId") + .IsUnique(); + + b.ToTable("Subscriptions"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.World", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActiveSlot") + .HasColumnType("integer"); + + b.Property("ActiveVersion") + .IsRequired() + .HasColumnType("text"); + + b.Property("MaxPlayers") + .HasColumnType("integer"); + + b.Property("Member") + .HasColumnType("boolean"); + + b.Property("MinigameId") + .HasColumnType("integer"); + + b.Property("MinigameImage") + .HasColumnType("text"); + + b.Property("MinigameName") + .HasColumnType("text"); + + b.Property("Motd") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Owner") + .HasColumnType("text"); + + b.Property("OwnerUUID") + .HasColumnType("text"); + + b.Property("State") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Worlds"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Backup", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany() + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Connection", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany() + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Invite", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany() + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Player", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany("Players") + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Slot", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany("Slots") + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Subscription", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithOne("Subscription") + .HasForeignKey("Minecraft_Realms_Emulator.Entities.Subscription", "WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.World", b => + { + b.Navigation("Players"); + + b.Navigation("Slots"); + + b.Navigation("Subscription"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.cs b/Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.cs new file mode 100644 index 0000000..4a77de7 --- /dev/null +++ b/Minecraft-Realms-Emulator/Migrations/20240521071345_Slots_Table.cs @@ -0,0 +1,70 @@ +using System.Text.Json; +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Minecraft_Realms_Emulator.Migrations +{ + /// + public partial class Slots_Table : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "Slots", + table: "Worlds"); + + migrationBuilder.CreateTable( + name: "Slots", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + WorldId = table.Column(type: "integer", nullable: false), + SlotId = table.Column(type: "integer", nullable: false), + SlotName = table.Column(type: "text", nullable: false), + Version = table.Column(type: "text", nullable: false), + GameMode = table.Column(type: "integer", nullable: false), + Difficulty = table.Column(type: "integer", nullable: false), + SpawnProtection = table.Column(type: "integer", nullable: false), + ForceGameMode = table.Column(type: "boolean", nullable: false), + Pvp = table.Column(type: "boolean", nullable: false), + SpawnAnimals = table.Column(type: "boolean", nullable: false), + SpawnMonsters = table.Column(type: "boolean", nullable: false), + SpawnNPCs = table.Column(type: "boolean", nullable: false), + CommandBlocks = table.Column(type: "boolean", nullable: false) + }, + constraints: table => + { + table.PrimaryKey("PK_Slots", x => x.Id); + table.ForeignKey( + name: "FK_Slots_Worlds_WorldId", + column: x => x.WorldId, + principalTable: "Worlds", + principalColumn: "Id", + onDelete: ReferentialAction.Cascade); + }); + + migrationBuilder.CreateIndex( + name: "IX_Slots_WorldId", + table: "Slots", + column: "WorldId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Slots"); + + migrationBuilder.AddColumn( + name: "Slots", + table: "Worlds", + type: "jsonb[]", + nullable: false, + defaultValue: new JsonDocument[0]); + } + } +} diff --git a/Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.Designer.cs b/Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.Designer.cs new file mode 100644 index 0000000..c3b0a85 --- /dev/null +++ b/Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.Designer.cs @@ -0,0 +1,378 @@ +// +using System; +using System.Text.Json; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Minecraft_Realms_Emulator.Data; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace Minecraft_Realms_Emulator.Migrations +{ + [DbContext(typeof(DataContext))] + [Migration("20240521080804_World_ActiveVersion_From_Slot")] + partial class World_ActiveVersion_From_Slot + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "8.0.4") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Backup", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("BackupId") + .IsRequired() + .HasColumnType("text"); + + b.Property("LastModifiedDate") + .HasColumnType("bigint"); + + b.Property("Metadata") + .IsRequired() + .HasColumnType("jsonb"); + + b.Property("Size") + .HasColumnType("integer"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Backups"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Configuration", b => + { + b.Property("Key") + .HasColumnType("text"); + + b.Property("Value") + .IsRequired() + .HasColumnType("jsonb"); + + b.HasKey("Key"); + + b.ToTable("Configuration"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Connection", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Address") + .IsRequired() + .HasColumnType("text"); + + b.Property("PendingUpdate") + .HasColumnType("boolean"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Connections"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Invite", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Date") + .HasColumnType("timestamp with time zone"); + + b.Property("InvitationId") + .IsRequired() + .HasColumnType("text"); + + b.Property("RecipeintUUID") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Invites"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Player", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Accepted") + .HasColumnType("boolean"); + + b.Property("Name") + .IsRequired() + .HasColumnType("text"); + + b.Property("Online") + .HasColumnType("boolean"); + + b.Property("Operator") + .HasColumnType("boolean"); + + b.Property("Permission") + .IsRequired() + .HasColumnType("text"); + + b.Property("Uuid") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Players"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Slot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CommandBlocks") + .HasColumnType("boolean"); + + b.Property("Difficulty") + .HasColumnType("integer"); + + b.Property("ForceGameMode") + .HasColumnType("boolean"); + + b.Property("GameMode") + .HasColumnType("integer"); + + b.Property("Pvp") + .HasColumnType("boolean"); + + b.Property("SlotId") + .HasColumnType("integer"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("text"); + + b.Property("SpawnAnimals") + .HasColumnType("boolean"); + + b.Property("SpawnMonsters") + .HasColumnType("boolean"); + + b.Property("SpawnNPCs") + .HasColumnType("boolean"); + + b.Property("SpawnProtection") + .HasColumnType("integer"); + + b.Property("Version") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Slots"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Subscription", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("StartDate") + .HasColumnType("timestamp with time zone"); + + b.Property("SubscriptionType") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId") + .IsUnique(); + + b.ToTable("Subscriptions"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.World", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("ActiveSlot") + .HasColumnType("integer"); + + b.Property("MaxPlayers") + .HasColumnType("integer"); + + b.Property("Member") + .HasColumnType("boolean"); + + b.Property("MinigameId") + .HasColumnType("integer"); + + b.Property("MinigameImage") + .HasColumnType("text"); + + b.Property("MinigameName") + .HasColumnType("text"); + + b.Property("Motd") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Owner") + .HasColumnType("text"); + + b.Property("OwnerUUID") + .HasColumnType("text"); + + b.Property("State") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldType") + .IsRequired() + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Worlds"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Backup", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany() + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Connection", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany() + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Invite", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany() + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Player", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany("Players") + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Slot", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany("Slots") + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Subscription", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithOne("Subscription") + .HasForeignKey("Minecraft_Realms_Emulator.Entities.Subscription", "WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.World", b => + { + b.Navigation("Players"); + + b.Navigation("Slots"); + + b.Navigation("Subscription"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.cs b/Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.cs new file mode 100644 index 0000000..f3f61ee --- /dev/null +++ b/Minecraft-Realms-Emulator/Migrations/20240521080804_World_ActiveVersion_From_Slot.cs @@ -0,0 +1,29 @@ +using Microsoft.EntityFrameworkCore.Migrations; + +#nullable disable + +namespace Minecraft_Realms_Emulator.Migrations +{ + /// + public partial class World_ActiveVersion_From_Slot : Migration + { + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropColumn( + name: "ActiveVersion", + table: "Worlds"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.AddColumn( + name: "ActiveVersion", + table: "Worlds", + type: "text", + nullable: false, + defaultValue: ""); + } + } +} diff --git a/Minecraft-Realms-Emulator/Migrations/DataContextModelSnapshot.cs b/Minecraft-Realms-Emulator/Migrations/DataContextModelSnapshot.cs index 4369893..0d53254 100644 --- a/Minecraft-Realms-Emulator/Migrations/DataContextModelSnapshot.cs +++ b/Minecraft-Realms-Emulator/Migrations/DataContextModelSnapshot.cs @@ -162,6 +162,62 @@ namespace Minecraft_Realms_Emulator.Migrations b.ToTable("Players"); }); + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Slot", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CommandBlocks") + .HasColumnType("boolean"); + + b.Property("Difficulty") + .HasColumnType("integer"); + + b.Property("ForceGameMode") + .HasColumnType("boolean"); + + b.Property("GameMode") + .HasColumnType("integer"); + + b.Property("Pvp") + .HasColumnType("boolean"); + + b.Property("SlotId") + .HasColumnType("integer"); + + b.Property("SlotName") + .IsRequired() + .HasColumnType("text"); + + b.Property("SpawnAnimals") + .HasColumnType("boolean"); + + b.Property("SpawnMonsters") + .HasColumnType("boolean"); + + b.Property("SpawnNPCs") + .HasColumnType("boolean"); + + b.Property("SpawnProtection") + .HasColumnType("integer"); + + b.Property("Version") + .IsRequired() + .HasColumnType("text"); + + b.Property("WorldId") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("WorldId"); + + b.ToTable("Slots"); + }); + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Subscription", b => { b.Property("Id") @@ -199,10 +255,6 @@ namespace Minecraft_Realms_Emulator.Migrations b.Property("ActiveSlot") .HasColumnType("integer"); - b.Property("ActiveVersion") - .IsRequired() - .HasColumnType("text"); - b.Property("MaxPlayers") .HasColumnType("integer"); @@ -230,10 +282,6 @@ namespace Minecraft_Realms_Emulator.Migrations b.Property("OwnerUUID") .HasColumnType("text"); - b.Property("Slots") - .IsRequired() - .HasColumnType("jsonb[]"); - b.Property("State") .IsRequired() .HasColumnType("text"); @@ -291,6 +339,17 @@ namespace Minecraft_Realms_Emulator.Migrations b.Navigation("World"); }); + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Slot", b => + { + b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") + .WithMany("Slots") + .HasForeignKey("WorldId") + .OnDelete(DeleteBehavior.Cascade) + .IsRequired(); + + b.Navigation("World"); + }); + modelBuilder.Entity("Minecraft_Realms_Emulator.Entities.Subscription", b => { b.HasOne("Minecraft_Realms_Emulator.Entities.World", "World") @@ -306,6 +365,8 @@ namespace Minecraft_Realms_Emulator.Migrations { b.Navigation("Players"); + b.Navigation("Slots"); + b.Navigation("Subscription"); }); #pragma warning restore 612, 618 diff --git a/Minecraft-Realms-Emulator/Requests/SlotOptionsRequest.cs b/Minecraft-Realms-Emulator/Requests/SlotOptionsRequest.cs new file mode 100644 index 0000000..9c29f60 --- /dev/null +++ b/Minecraft-Realms-Emulator/Requests/SlotOptionsRequest.cs @@ -0,0 +1,17 @@ +namespace Minecraft_Realms_Emulator.Requests +{ + public class SlotOptionsRequest + { + public string SlotName { get; set; } = null!; + public string Version { get; set; } = null!; + public int GameMode { get; set; } + public int Difficulty { get; set; } + public int SpawnProtection { get; set; } + public bool ForceGameMode { get; set; } + public bool Pvp { get; set; } + public bool SpawnAnimals { get; set; } + public bool SpawnMonsters { get; set; } + public bool SpawnNPCs { get; set; } + public bool CommandBlocks { get; set; } + } +} diff --git a/Minecraft-Realms-Emulator/Responses/SlotsResponse.cs b/Minecraft-Realms-Emulator/Responses/SlotsResponse.cs new file mode 100644 index 0000000..cf32daf --- /dev/null +++ b/Minecraft-Realms-Emulator/Responses/SlotsResponse.cs @@ -0,0 +1,8 @@ +namespace Minecraft_Realms_Emulator.Responses +{ + public class SlotsResponse + { + public int SlotId { get; set; } + public string Options { get; set; } = null!; + } +} diff --git a/Minecraft-Realms-Emulator/Responses/WorldResponse.cs b/Minecraft-Realms-Emulator/Responses/WorldResponse.cs index 964dbf3..acd68fb 100644 --- a/Minecraft-Realms-Emulator/Responses/WorldResponse.cs +++ b/Minecraft-Realms-Emulator/Responses/WorldResponse.cs @@ -1,4 +1,6 @@ -namespace Minecraft_Realms_Emulator.Entities +using Minecraft_Realms_Emulator.Responses; + +namespace Minecraft_Realms_Emulator.Entities { public class WorldResponse : World { @@ -7,5 +9,7 @@ public bool Expired { get; set; } = false; public bool ExpiredTrial { get; set; } = false; public string Compatibility { get; set; } = null!; + public List Slots { get; set; } = null!; + public string ActiveVersion { get; set; } = null!; } } \ No newline at end of file