diff --git a/src/DataModel/Configuration/DuelArea.cs b/src/DataModel/Configuration/DuelArea.cs
new file mode 100644
index 000000000..00013b059
--- /dev/null
+++ b/src/DataModel/Configuration/DuelArea.cs
@@ -0,0 +1,40 @@
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+//
+
+namespace MUnique.OpenMU.DataModel.Configuration;
+
+using MUnique.OpenMU.Annotations;
+
+///
+/// Defines an area where a duel can take place.
+///
+[Cloneable]
+public partial class DuelArea
+{
+ ///
+ /// Gets or sets the index of the area.
+ ///
+ public short Index { get; set; }
+
+ ///
+ /// Gets or sets the first player gate to which the player is teleported when he enters the duel.
+ ///
+ public virtual ExitGate? FirstPlayerGate { get; set; }
+
+ ///
+ /// Gets or sets the second player gate to which the player is teleported when he enters the duel.
+ ///
+ public virtual ExitGate? SecondPlayerGate { get; set; }
+
+ ///
+ /// Gets or sets the gate to which a spectator is teleported when he enters the duel.
+ ///
+ public virtual ExitGate? SpectatorsGate { get; set; }
+
+ ///
+ public override string ToString()
+ {
+ return $"{this.Index} - {this.FirstPlayerGate} - {this.SecondPlayerGate}";
+ }
+}
\ No newline at end of file
diff --git a/src/DataModel/Configuration/DuelConfiguration.cs b/src/DataModel/Configuration/DuelConfiguration.cs
new file mode 100644
index 000000000..9ca531af9
--- /dev/null
+++ b/src/DataModel/Configuration/DuelConfiguration.cs
@@ -0,0 +1,52 @@
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+//
+
+namespace MUnique.OpenMU.DataModel.Configuration;
+
+using MUnique.OpenMU.Annotations;
+
+///
+/// Configuration for the duel feature.
+///
+[Cloneable]
+public partial class DuelConfiguration
+{
+ ///
+ /// Gets or sets the maximum score at which the duel will end with a winner.
+ ///
+ public int MaximumScore {get; set; }
+
+ ///
+ /// Gets or sets the entrance fee for a duel.
+ ///
+ public int EntranceFee { get; set; }
+
+ ///
+ /// Gets or sets the minimum character level to start a duel.
+ ///
+ public int MinimumCharacterLevel { get; set; }
+
+ ///
+ /// Gets or sets the maximum spectators per duel room.
+ ///
+ public int MaximumSpectatorsPerDuelRoom { get; set; }
+
+ ///
+ /// Gets or sets the exit gate to which all players are ported after the duel has ended.
+ /// If not set, players will be ported to the safezone.
+ ///
+ public virtual ExitGate? Exit { get; set; }
+
+ ///
+ /// Gets or sets the available duel areas.
+ ///
+ [MemberOfAggregate]
+ public virtual ICollection DuelAreas { get; protected set; } = null!;
+
+ ///
+ public override string ToString()
+ {
+ return $"Duel Configuration {this.DuelAreas.Count} Arenas, Exit: {this.Exit}";
+ }
+}
\ No newline at end of file
diff --git a/src/DataModel/Configuration/GameConfiguration.cs b/src/DataModel/Configuration/GameConfiguration.cs
index 13dff95a4..6433f6347 100644
--- a/src/DataModel/Configuration/GameConfiguration.cs
+++ b/src/DataModel/Configuration/GameConfiguration.cs
@@ -137,6 +137,12 @@ public partial class GameConfiguration
///
public double HitsPerOneItemDurability { get; set; }
+ ///
+ /// Gets or sets the duel configuration.
+ ///
+ [MemberOfAggregate]
+ public virtual DuelConfiguration? DuelConfiguration { get; set; }
+
///
/// Gets or sets the possible jewel mixes.
///
diff --git a/src/Persistence/BasicModel/DuelArea.Generated.cs b/src/Persistence/BasicModel/DuelArea.Generated.cs
new file mode 100644
index 000000000..54664766d
--- /dev/null
+++ b/src/Persistence/BasicModel/DuelArea.Generated.cs
@@ -0,0 +1,117 @@
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+//
+
+//------------------------------------------------------------------------------
+//
+// This source code was auto-generated by a roslyn code generator.
+//
+//------------------------------------------------------------------------------
+
+// ReSharper disable All
+
+namespace MUnique.OpenMU.Persistence.BasicModel;
+
+using MUnique.OpenMU.Persistence.Json;
+
+///
+/// A plain implementation of .
+///
+public partial class DuelArea : MUnique.OpenMU.DataModel.Configuration.DuelArea, IIdentifiable, IConvertibleTo
+{
+
+ ///
+ /// Gets or sets the identifier of this instance.
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Gets the raw object of .
+ ///
+ [System.Text.Json.Serialization.JsonPropertyName("firstPlayerGate")]
+ public ExitGate RawFirstPlayerGate
+ {
+ get => base.FirstPlayerGate as ExitGate;
+ set => base.FirstPlayerGate = value;
+ }
+
+ ///
+ [System.Text.Json.Serialization.JsonIgnore]
+ public override MUnique.OpenMU.DataModel.Configuration.ExitGate FirstPlayerGate
+ {
+ get => base.FirstPlayerGate;
+ set => base.FirstPlayerGate = value;
+ }
+
+ ///
+ /// Gets the raw object of .
+ ///
+ [System.Text.Json.Serialization.JsonPropertyName("secondPlayerGate")]
+ public ExitGate RawSecondPlayerGate
+ {
+ get => base.SecondPlayerGate as ExitGate;
+ set => base.SecondPlayerGate = value;
+ }
+
+ ///
+ [System.Text.Json.Serialization.JsonIgnore]
+ public override MUnique.OpenMU.DataModel.Configuration.ExitGate SecondPlayerGate
+ {
+ get => base.SecondPlayerGate;
+ set => base.SecondPlayerGate = value;
+ }
+
+ ///
+ /// Gets the raw object of .
+ ///
+ [System.Text.Json.Serialization.JsonPropertyName("spectatorsGate")]
+ public ExitGate RawSpectatorsGate
+ {
+ get => base.SpectatorsGate as ExitGate;
+ set => base.SpectatorsGate = value;
+ }
+
+ ///
+ [System.Text.Json.Serialization.JsonIgnore]
+ public override MUnique.OpenMU.DataModel.Configuration.ExitGate SpectatorsGate
+ {
+ get => base.SpectatorsGate;
+ set => base.SpectatorsGate = value;
+ }
+
+ ///
+ public override MUnique.OpenMU.DataModel.Configuration.DuelArea Clone(MUnique.OpenMU.DataModel.Configuration.GameConfiguration gameConfiguration)
+ {
+ var clone = new DuelArea();
+ clone.AssignValuesOf(this, gameConfiguration);
+ return clone;
+ }
+
+ ///
+ public override void AssignValuesOf(MUnique.OpenMU.DataModel.Configuration.DuelArea other, MUnique.OpenMU.DataModel.Configuration.GameConfiguration gameConfiguration)
+ {
+ base.AssignValuesOf(other, gameConfiguration);
+ this.Id = other.GetId();
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ var baseObject = obj as IIdentifiable;
+ if (baseObject != null)
+ {
+ return baseObject.Id == this.Id;
+ }
+
+ return base.Equals(obj);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return this.Id.GetHashCode();
+ }
+
+ ///
+ public DuelArea Convert() => this;
+}
diff --git a/src/Persistence/BasicModel/DuelConfiguration.Generated.cs b/src/Persistence/BasicModel/DuelConfiguration.Generated.cs
new file mode 100644
index 000000000..2eb63d111
--- /dev/null
+++ b/src/Persistence/BasicModel/DuelConfiguration.Generated.cs
@@ -0,0 +1,102 @@
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+//
+
+//------------------------------------------------------------------------------
+//
+// This source code was auto-generated by a roslyn code generator.
+//
+//------------------------------------------------------------------------------
+
+// ReSharper disable All
+
+namespace MUnique.OpenMU.Persistence.BasicModel;
+
+using MUnique.OpenMU.Persistence.Json;
+
+///
+/// A plain implementation of .
+///
+public partial class DuelConfiguration : MUnique.OpenMU.DataModel.Configuration.DuelConfiguration, IIdentifiable, IConvertibleTo
+{
+
+ ///
+ /// Gets or sets the identifier of this instance.
+ ///
+ public Guid Id { get; set; }
+
+ ///
+ /// Gets the raw collection of .
+ ///
+ [System.Text.Json.Serialization.JsonPropertyName("duelAreas")]
+ public ICollection RawDuelAreas { get; } = new List();
+
+ ///
+ [System.Text.Json.Serialization.JsonIgnore]
+ public override ICollection DuelAreas
+ {
+ get => base.DuelAreas ??= new CollectionAdapter(this.RawDuelAreas);
+ protected set
+ {
+ this.DuelAreas.Clear();
+ foreach (var item in value)
+ {
+ this.DuelAreas.Add(item);
+ }
+ }
+ }
+
+ ///
+ /// Gets the raw object of .
+ ///
+ [System.Text.Json.Serialization.JsonPropertyName("exit")]
+ public ExitGate RawExit
+ {
+ get => base.Exit as ExitGate;
+ set => base.Exit = value;
+ }
+
+ ///
+ [System.Text.Json.Serialization.JsonIgnore]
+ public override MUnique.OpenMU.DataModel.Configuration.ExitGate Exit
+ {
+ get => base.Exit;
+ set => base.Exit = value;
+ }
+
+ ///
+ public override MUnique.OpenMU.DataModel.Configuration.DuelConfiguration Clone(MUnique.OpenMU.DataModel.Configuration.GameConfiguration gameConfiguration)
+ {
+ var clone = new DuelConfiguration();
+ clone.AssignValuesOf(this, gameConfiguration);
+ return clone;
+ }
+
+ ///
+ public override void AssignValuesOf(MUnique.OpenMU.DataModel.Configuration.DuelConfiguration other, MUnique.OpenMU.DataModel.Configuration.GameConfiguration gameConfiguration)
+ {
+ base.AssignValuesOf(other, gameConfiguration);
+ this.Id = other.GetId();
+ }
+
+ ///
+ public override bool Equals(object obj)
+ {
+ var baseObject = obj as IIdentifiable;
+ if (baseObject != null)
+ {
+ return baseObject.Id == this.Id;
+ }
+
+ return base.Equals(obj);
+ }
+
+ ///
+ public override int GetHashCode()
+ {
+ return this.Id.GetHashCode();
+ }
+
+ ///
+ public DuelConfiguration Convert() => this;
+}
diff --git a/src/Persistence/BasicModel/GameConfiguration.Generated.cs b/src/Persistence/BasicModel/GameConfiguration.Generated.cs
index c65692702..b0ee96b81 100644
--- a/src/Persistence/BasicModel/GameConfiguration.Generated.cs
+++ b/src/Persistence/BasicModel/GameConfiguration.Generated.cs
@@ -424,6 +424,24 @@ protected set
}
}
+ ///
+ /// Gets the raw object of .
+ ///
+ [System.Text.Json.Serialization.JsonPropertyName("duelConfiguration")]
+ public DuelConfiguration RawDuelConfiguration
+ {
+ get => base.DuelConfiguration as DuelConfiguration;
+ set => base.DuelConfiguration = value;
+ }
+
+ ///
+ [System.Text.Json.Serialization.JsonIgnore]
+ public override MUnique.OpenMU.DataModel.Configuration.DuelConfiguration DuelConfiguration
+ {
+ get => base.DuelConfiguration;
+ set => base.DuelConfiguration = value;
+ }
+
///
public override MUnique.OpenMU.DataModel.Configuration.GameConfiguration Clone(MUnique.OpenMU.DataModel.Configuration.GameConfiguration gameConfiguration)
{
diff --git a/src/Persistence/EntityFramework/Migrations/20240707081614_DuelConfiguration.Designer.cs b/src/Persistence/EntityFramework/Migrations/20240707081614_DuelConfiguration.Designer.cs
new file mode 100644
index 000000000..97a283b2c
--- /dev/null
+++ b/src/Persistence/EntityFramework/Migrations/20240707081614_DuelConfiguration.Designer.cs
@@ -0,0 +1,4996 @@
+//
+using System;
+using MUnique.OpenMU.Persistence.EntityFramework;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace MUnique.OpenMU.Persistence.EntityFramework.Migrations
+{
+ [DbContext(typeof(EntityDataContext))]
+ [Migration("20240707081614_DuelConfiguration")]
+ partial class DuelConfiguration
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "8.0.6")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Account", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ChatBanUntil")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("EMail")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("IsVaultExtended")
+ .HasColumnType("boolean");
+
+ b.Property("LoginName")
+ .IsRequired()
+ .HasMaxLength(10)
+ .HasColumnType("character varying(10)");
+
+ b.Property("PasswordHash")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("RegistrationDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("SecurityCode")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("State")
+ .HasColumnType("integer");
+
+ b.Property("TimeZone")
+ .HasColumnType("smallint");
+
+ b.Property("VaultId")
+ .HasColumnType("uuid");
+
+ b.Property("VaultPassword")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.HasIndex("LoginName")
+ .IsUnique();
+
+ b.HasIndex("VaultId")
+ .IsUnique();
+
+ b.ToTable("Account", "data");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AccountCharacterClass", b =>
+ {
+ b.Property("AccountId")
+ .HasColumnType("uuid");
+
+ b.Property("CharacterClassId")
+ .HasColumnType("uuid");
+
+ b.HasKey("AccountId", "CharacterClassId");
+
+ b.HasIndex("CharacterClassId");
+
+ b.ToTable("AccountCharacterClass", "data");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AppearanceData", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CharacterClassId")
+ .HasColumnType("uuid");
+
+ b.Property("FullAncientSetEquipped")
+ .HasColumnType("boolean");
+
+ b.Property("Pose")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CharacterClassId");
+
+ b.ToTable("AppearanceData", "data");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("Designation")
+ .HasColumnType("text");
+
+ b.Property("GameConfigurationId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GameConfigurationId");
+
+ b.ToTable("AttributeDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeRelationship", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CharacterClassId")
+ .HasColumnType("uuid");
+
+ b.Property("InputAttributeId")
+ .HasColumnType("uuid");
+
+ b.Property("InputOperand")
+ .HasColumnType("real");
+
+ b.Property("InputOperator")
+ .HasColumnType("integer");
+
+ b.Property("OperandAttributeId")
+ .HasColumnType("uuid");
+
+ b.Property("PowerUpDefinitionValueId")
+ .HasColumnType("uuid");
+
+ b.Property("TargetAttributeId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CharacterClassId");
+
+ b.HasIndex("InputAttributeId");
+
+ b.HasIndex("OperandAttributeId");
+
+ b.HasIndex("PowerUpDefinitionValueId");
+
+ b.HasIndex("TargetAttributeId");
+
+ b.ToTable("AttributeRelationship", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.AttributeRequirement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("AttributeId")
+ .HasColumnType("uuid");
+
+ b.Property("GameMapDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("ItemDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("MinimumValue")
+ .HasColumnType("integer");
+
+ b.Property("SkillId")
+ .HasColumnType("uuid");
+
+ b.Property("SkillId1")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AttributeId");
+
+ b.HasIndex("GameMapDefinitionId");
+
+ b.HasIndex("ItemDefinitionId");
+
+ b.HasIndex("SkillId");
+
+ b.HasIndex("SkillId1");
+
+ b.ToTable("AttributeRequirement", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.BattleZoneDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("GroundId")
+ .HasColumnType("uuid");
+
+ b.Property("LeftGoalId")
+ .HasColumnType("uuid");
+
+ b.Property("LeftTeamSpawnPointX")
+ .HasColumnType("smallint");
+
+ b.Property("LeftTeamSpawnPointY")
+ .HasColumnType("smallint");
+
+ b.Property("RightGoalId")
+ .HasColumnType("uuid");
+
+ b.Property("RightTeamSpawnPointX")
+ .HasColumnType("smallint");
+
+ b.Property("RightTeamSpawnPointY")
+ .HasColumnType("smallint");
+
+ b.Property("Type")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GroundId")
+ .IsUnique();
+
+ b.HasIndex("LeftGoalId")
+ .IsUnique();
+
+ b.HasIndex("RightGoalId")
+ .IsUnique();
+
+ b.ToTable("BattleZoneDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Character", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("AccountId")
+ .HasColumnType("uuid");
+
+ b.Property("CharacterClassId")
+ .IsRequired()
+ .HasColumnType("uuid");
+
+ b.Property("CharacterSlot")
+ .HasColumnType("smallint");
+
+ b.Property("CharacterStatus")
+ .HasColumnType("integer");
+
+ b.Property("CreateDate")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("CurrentMapId")
+ .HasColumnType("uuid");
+
+ b.Property("Experience")
+ .HasColumnType("bigint");
+
+ b.Property("InventoryExtensions")
+ .HasColumnType("integer");
+
+ b.Property("InventoryId")
+ .HasColumnType("uuid");
+
+ b.Property("KeyConfiguration")
+ .HasColumnType("bytea");
+
+ b.Property("LevelUpPoints")
+ .HasColumnType("integer");
+
+ b.Property("MasterExperience")
+ .HasColumnType("bigint");
+
+ b.Property("MasterLevelUpPoints")
+ .HasColumnType("integer");
+
+ b.Property("MuHelperConfiguration")
+ .HasColumnType("bytea");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(10)
+ .HasColumnType("character varying(10)");
+
+ b.Property("PlayerKillCount")
+ .HasColumnType("integer");
+
+ b.Property("Pose")
+ .HasColumnType("smallint");
+
+ b.Property("PositionX")
+ .HasColumnType("smallint");
+
+ b.Property("PositionY")
+ .HasColumnType("smallint");
+
+ b.Property("State")
+ .HasColumnType("integer");
+
+ b.Property("StateRemainingSeconds")
+ .HasColumnType("integer");
+
+ b.Property("UsedFruitPoints")
+ .HasColumnType("integer");
+
+ b.Property("UsedNegFruitPoints")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AccountId");
+
+ b.HasIndex("CharacterClassId");
+
+ b.HasIndex("CurrentMapId");
+
+ b.HasIndex("InventoryId")
+ .IsUnique();
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Character", "data");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterClass", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CanGetCreated")
+ .HasColumnType("boolean");
+
+ b.Property("ComboDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("CreationAllowedFlag")
+ .HasColumnType("smallint");
+
+ b.Property("FruitCalculation")
+ .HasColumnType("integer");
+
+ b.Property("GameConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("HomeMapId")
+ .HasColumnType("uuid");
+
+ b.Property("IsMasterClass")
+ .HasColumnType("boolean");
+
+ b.Property("LevelRequirementByCreation")
+ .HasColumnType("smallint");
+
+ b.Property("LevelWarpRequirementReductionPercent")
+ .HasColumnType("integer");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("NextGenerationClassId")
+ .HasColumnType("uuid");
+
+ b.Property("Number")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ComboDefinitionId")
+ .IsUnique();
+
+ b.HasIndex("GameConfigurationId");
+
+ b.HasIndex("HomeMapId");
+
+ b.HasIndex("NextGenerationClassId");
+
+ b.ToTable("CharacterClass", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterDropItemGroup", b =>
+ {
+ b.Property("CharacterId")
+ .HasColumnType("uuid");
+
+ b.Property("DropItemGroupId")
+ .HasColumnType("uuid");
+
+ b.HasKey("CharacterId", "DropItemGroupId");
+
+ b.HasIndex("DropItemGroupId");
+
+ b.ToTable("CharacterDropItemGroup", "data");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CharacterQuestState", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ActiveQuestId")
+ .HasColumnType("uuid");
+
+ b.Property("CharacterId")
+ .HasColumnType("uuid");
+
+ b.Property("ClientActionPerformed")
+ .HasColumnType("boolean");
+
+ b.Property("Group")
+ .HasColumnType("smallint");
+
+ b.Property("LastFinishedQuestId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ActiveQuestId");
+
+ b.HasIndex("CharacterId");
+
+ b.HasIndex("LastFinishedQuestId");
+
+ b.ToTable("CharacterQuestState", "data");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ClientCleanUpInterval")
+ .HasColumnType("interval");
+
+ b.Property("ClientTimeout")
+ .HasColumnType("interval");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("MaximumConnections")
+ .HasColumnType("integer");
+
+ b.Property("RoomCleanUpInterval")
+ .HasColumnType("interval");
+
+ b.Property("ServerId")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.ToTable("ChatServerDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ChatServerEndpoint", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ChatServerDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("ClientId")
+ .HasColumnType("uuid");
+
+ b.Property("NetworkPort")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ChatServerDefinitionId");
+
+ b.HasIndex("ClientId");
+
+ b.ToTable("ChatServerEndpoint", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.CombinationBonusRequirement", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("ItemOptionCombinationBonusId")
+ .HasColumnType("uuid");
+
+ b.Property("MinimumCount")
+ .HasColumnType("integer");
+
+ b.Property("OptionTypeId")
+ .HasColumnType("uuid");
+
+ b.Property("SubOptionType")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ItemOptionCombinationBonusId");
+
+ b.HasIndex("OptionTypeId");
+
+ b.ToTable("CombinationBonusRequirement", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConfigurationUpdate", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CreatedAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Description")
+ .HasColumnType("text");
+
+ b.Property("InstalledAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .HasColumnType("text");
+
+ b.Property("Version")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.ToTable("ConfigurationUpdate", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConfigurationUpdateState", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CurrentInstalledVersion")
+ .HasColumnType("integer");
+
+ b.Property("InitializationKey")
+ .HasColumnType("text");
+
+ b.HasKey("Id");
+
+ b.ToTable("ConfigurationUpdateState", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConnectServerDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CheckMaxConnectionsPerAddress")
+ .HasColumnType("boolean");
+
+ b.Property("ClientId")
+ .HasColumnType("uuid");
+
+ b.Property("ClientListenerPort")
+ .HasColumnType("integer");
+
+ b.Property("CurrentPatchVersion")
+ .HasColumnType("bytea");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("DisconnectOnUnknownPacket")
+ .HasColumnType("boolean");
+
+ b.Property("ListenerBacklog")
+ .HasColumnType("integer");
+
+ b.Property("MaxConnections")
+ .HasColumnType("integer");
+
+ b.Property("MaxConnectionsPerAddress")
+ .HasColumnType("integer");
+
+ b.Property("MaxFtpRequests")
+ .HasColumnType("integer");
+
+ b.Property("MaxIpRequests")
+ .HasColumnType("integer");
+
+ b.Property("MaxServerListRequests")
+ .HasColumnType("integer");
+
+ b.Property("MaximumReceiveSize")
+ .HasColumnType("smallint");
+
+ b.Property("PatchAddress")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ServerId")
+ .HasColumnType("smallint");
+
+ b.Property("Timeout")
+ .HasColumnType("interval");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ClientId");
+
+ b.ToTable("ConnectServerDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ConstValueAttribute", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("CharacterClassId")
+ .HasColumnType("uuid");
+
+ b.Property("DefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("Value")
+ .HasColumnType("real");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CharacterClassId");
+
+ b.HasIndex("DefinitionId");
+
+ b.ToTable("ConstValueAttribute", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Chance")
+ .HasColumnType("double precision");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("GameConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("ItemLevel")
+ .HasColumnType("smallint");
+
+ b.Property("ItemType")
+ .HasColumnType("integer");
+
+ b.Property("MaximumMonsterLevel")
+ .HasColumnType("smallint");
+
+ b.Property("MinimumMonsterLevel")
+ .HasColumnType("smallint");
+
+ b.Property("MonsterId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GameConfigurationId");
+
+ b.HasIndex("MonsterId");
+
+ b.ToTable("DropItemGroup", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DropItemGroupItemDefinition", b =>
+ {
+ b.Property("DropItemGroupId")
+ .HasColumnType("uuid");
+
+ b.Property("ItemDefinitionId")
+ .HasColumnType("uuid");
+
+ b.HasKey("DropItemGroupId", "ItemDefinitionId");
+
+ b.HasIndex("ItemDefinitionId");
+
+ b.ToTable("DropItemGroupItemDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelArea", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DuelConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("FirstPlayerGateId")
+ .HasColumnType("uuid");
+
+ b.Property("Index")
+ .HasColumnType("smallint");
+
+ b.Property("SecondPlayerGateId")
+ .HasColumnType("uuid");
+
+ b.Property("SpectatorsGateId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DuelConfigurationId");
+
+ b.HasIndex("FirstPlayerGateId");
+
+ b.HasIndex("SecondPlayerGateId");
+
+ b.HasIndex("SpectatorsGateId");
+
+ b.ToTable("DuelArea", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.DuelConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("EntranceFee")
+ .HasColumnType("integer");
+
+ b.Property("ExitId")
+ .HasColumnType("uuid");
+
+ b.Property("MaximumScore")
+ .HasColumnType("integer");
+
+ b.Property("MaximumSpectatorsPerDuelRoom")
+ .HasColumnType("integer");
+
+ b.Property("MinimumCharacterLevel")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ExitId");
+
+ b.ToTable("DuelConfiguration", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.EnterGate", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("GameMapDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("LevelRequirement")
+ .HasColumnType("smallint");
+
+ b.Property("Number")
+ .HasColumnType("smallint");
+
+ b.Property("TargetGateId")
+ .HasColumnType("uuid");
+
+ b.Property("X1")
+ .HasColumnType("smallint");
+
+ b.Property("X2")
+ .HasColumnType("smallint");
+
+ b.Property("Y1")
+ .HasColumnType("smallint");
+
+ b.Property("Y2")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GameMapDefinitionId");
+
+ b.HasIndex("TargetGateId");
+
+ b.ToTable("EnterGate", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.ExitGate", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Direction")
+ .HasColumnType("integer");
+
+ b.Property("IsSpawnGate")
+ .HasColumnType("boolean");
+
+ b.Property("MapId")
+ .HasColumnType("uuid");
+
+ b.Property("X1")
+ .HasColumnType("smallint");
+
+ b.Property("X2")
+ .HasColumnType("smallint");
+
+ b.Property("Y1")
+ .HasColumnType("smallint");
+
+ b.Property("Y2")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("MapId");
+
+ b.ToTable("ExitGate", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Friend", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Accepted")
+ .HasColumnType("boolean");
+
+ b.Property("CharacterId")
+ .HasColumnType("uuid");
+
+ b.Property("FriendId")
+ .HasColumnType("uuid");
+
+ b.Property("RequestOpen")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.HasAlternateKey("CharacterId", "FriendId");
+
+ b.ToTable("Friend", "friend");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameClientDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Episode")
+ .HasColumnType("smallint");
+
+ b.Property("Language")
+ .HasColumnType("integer");
+
+ b.Property("Season")
+ .HasColumnType("smallint");
+
+ b.Property("Serial")
+ .HasColumnType("bytea");
+
+ b.Property("Version")
+ .HasColumnType("bytea");
+
+ b.HasKey("Id");
+
+ b.ToTable("GameClientDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("AreaSkillHitsPlayer")
+ .HasColumnType("boolean");
+
+ b.Property("CharacterNameRegex")
+ .HasColumnType("text");
+
+ b.Property("DamagePerOneItemDurability")
+ .HasColumnType("double precision");
+
+ b.Property("DamagePerOnePetDurability")
+ .HasColumnType("double precision");
+
+ b.Property("DuelConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("ExperienceRate")
+ .HasColumnType("real");
+
+ b.Property("HitsPerOneItemDurability")
+ .HasColumnType("double precision");
+
+ b.Property("InfoRange")
+ .HasColumnType("smallint");
+
+ b.Property("ItemDropDuration")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("interval")
+ .HasDefaultValue(new TimeSpan(0, 0, 1, 0, 0));
+
+ b.Property("LetterSendPrice")
+ .HasColumnType("integer");
+
+ b.Property("MaximumCharactersPerAccount")
+ .HasColumnType("smallint");
+
+ b.Property("MaximumInventoryMoney")
+ .HasColumnType("integer");
+
+ b.Property("MaximumLetters")
+ .HasColumnType("integer");
+
+ b.Property("MaximumLevel")
+ .HasColumnType("smallint");
+
+ b.Property("MaximumMasterLevel")
+ .HasColumnType("smallint");
+
+ b.Property("MaximumPartySize")
+ .HasColumnType("smallint");
+
+ b.Property("MaximumPasswordLength")
+ .HasColumnType("integer");
+
+ b.Property("MaximumVaultMoney")
+ .HasColumnType("integer");
+
+ b.Property("MinimumMonsterLevelForMasterExperience")
+ .HasColumnType("smallint");
+
+ b.Property("RecoveryInterval")
+ .HasColumnType("integer");
+
+ b.Property("ShouldDropMoney")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.HasIndex("DuelConfigurationId")
+ .IsUnique();
+
+ b.ToTable("GameConfiguration", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("BattleZoneId")
+ .HasColumnType("uuid");
+
+ b.Property("Discriminator")
+ .HasColumnType("integer");
+
+ b.Property("ExpMultiplier")
+ .HasColumnType("double precision");
+
+ b.Property("GameConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("Number")
+ .HasColumnType("smallint");
+
+ b.Property("SafezoneMapId")
+ .HasColumnType("uuid");
+
+ b.Property("TerrainData")
+ .HasColumnType("bytea");
+
+ b.HasKey("Id");
+
+ b.HasIndex("BattleZoneId")
+ .IsUnique();
+
+ b.HasIndex("GameConfigurationId");
+
+ b.HasIndex("SafezoneMapId");
+
+ b.ToTable("GameMapDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameMapDefinitionDropItemGroup", b =>
+ {
+ b.Property("GameMapDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("DropItemGroupId")
+ .HasColumnType("uuid");
+
+ b.HasKey("GameMapDefinitionId", "DropItemGroupId");
+
+ b.HasIndex("DropItemGroupId");
+
+ b.ToTable("GameMapDefinitionDropItemGroup", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfiguration", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("MaximumPlayers")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.ToTable("GameServerConfiguration", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerConfigurationGameMapDefinition", b =>
+ {
+ b.Property("GameServerConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("GameMapDefinitionId")
+ .HasColumnType("uuid");
+
+ b.HasKey("GameServerConfigurationId", "GameMapDefinitionId");
+
+ b.HasIndex("GameMapDefinitionId");
+
+ b.ToTable("GameServerConfigurationGameMapDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerDefinition", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("Description")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("ExperienceRate")
+ .HasColumnType("real");
+
+ b.Property("GameConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("ServerConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("ServerID")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GameConfigurationId");
+
+ b.HasIndex("ServerConfigurationId");
+
+ b.ToTable("GameServerDefinition", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GameServerEndpoint", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("AlternativePublishedPort")
+ .HasColumnType("integer");
+
+ b.Property("ClientId")
+ .HasColumnType("uuid");
+
+ b.Property("GameServerDefinitionId")
+ .HasColumnType("uuid");
+
+ b.Property("NetworkPort")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("ClientId");
+
+ b.HasIndex("GameServerDefinitionId");
+
+ b.ToTable("GameServerEndpoint", "config");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.Guild", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("AllianceGuildId")
+ .HasColumnType("uuid");
+
+ b.Property("HostilityId")
+ .HasColumnType("uuid");
+
+ b.Property("Logo")
+ .HasColumnType("bytea");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasMaxLength(8)
+ .HasColumnType("character varying(8)");
+
+ b.Property("Notice")
+ .HasColumnType("text");
+
+ b.Property("Score")
+ .HasColumnType("integer");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AllianceGuildId");
+
+ b.HasIndex("HostilityId");
+
+ b.HasIndex("Name")
+ .IsUnique();
+
+ b.ToTable("Guild", "guild");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.GuildMember", b =>
+ {
+ b.Property("Id")
+ .HasColumnType("uuid");
+
+ b.Property("GuildId")
+ .HasColumnType("uuid");
+
+ b.Property("Status")
+ .HasColumnType("smallint");
+
+ b.HasKey("Id");
+
+ b.HasIndex("GuildId");
+
+ b.ToTable("GuildMember", "guild");
+ });
+
+ modelBuilder.Entity("MUnique.OpenMU.Persistence.EntityFramework.Model.IncreasableItemOption", b =>
+ {
+ b.Property