diff --git a/src/DataModel/Configuration/ConfigurationUpdate.cs b/src/DataModel/Configuration/ConfigurationUpdate.cs
index b4bd3beab..6025a2a5c 100644
--- a/src/DataModel/Configuration/ConfigurationUpdate.cs
+++ b/src/DataModel/Configuration/ConfigurationUpdate.cs
@@ -23,12 +23,12 @@ public class ConfigurationUpdate
///
/// Gets or sets the name of the update.
///
- public LocalizedString? Name { get; set; }
+ public LocalizedString Name { get; set; }
///
/// Gets or sets the description of the update with further information.
///
- public LocalizedString? Description { get; set; }
+ public LocalizedString Description { get; set; }
///
/// Gets or sets the release date.
diff --git a/src/DataModel/Configuration/MiniGameChangeEvent.cs b/src/DataModel/Configuration/MiniGameChangeEvent.cs
index fb5f0e924..1e97aaa52 100644
--- a/src/DataModel/Configuration/MiniGameChangeEvent.cs
+++ b/src/DataModel/Configuration/MiniGameChangeEvent.cs
@@ -45,13 +45,13 @@ public partial class MiniGameChangeEvent
///
/// Gets or sets the description about the event.
///
- public LocalizedString? Description { get; set; }
+ public LocalizedString Description { get; set; }
///
/// Gets or sets the (golden) message which should be shown to the player.
/// One placeholder can be used to show the triggering player name.
///
- public LocalizedString? Message { get; set; }
+ public LocalizedString Message { get; set; }
///
/// Gets or sets the targets which need to be killed to reach the required .
diff --git a/src/DataModel/Configuration/MiniGameSpawnWave.cs b/src/DataModel/Configuration/MiniGameSpawnWave.cs
index 052081b24..e9a41bd33 100644
--- a/src/DataModel/Configuration/MiniGameSpawnWave.cs
+++ b/src/DataModel/Configuration/MiniGameSpawnWave.cs
@@ -21,12 +21,12 @@ public partial class MiniGameSpawnWave
///
/// Gets or sets the description about this wave.
///
- public LocalizedString? Description { get; set; }
+ public LocalizedString Description { get; set; }
///
/// Gets or sets a message which is shown to the player when the wave starts.
///
- public LocalizedString? Message { get; set; }
+ public LocalizedString Message { get; set; }
///
/// Gets or sets the starting time of the wave.
diff --git a/src/Directory.Packages.props b/src/Directory.Packages.props
index fcc43b89d..36db961fa 100644
--- a/src/Directory.Packages.props
+++ b/src/Directory.Packages.props
@@ -14,23 +14,24 @@
-
-
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -56,7 +57,7 @@
-
+
diff --git a/src/GameLogic/MUnique.OpenMU.GameLogic.csproj b/src/GameLogic/MUnique.OpenMU.GameLogic.csproj
index e14128457..0d05fb058 100644
--- a/src/GameLogic/MUnique.OpenMU.GameLogic.csproj
+++ b/src/GameLogic/MUnique.OpenMU.GameLogic.csproj
@@ -26,7 +26,6 @@
-
diff --git a/src/GameLogic/MiniGames/MiniGameContext.cs b/src/GameLogic/MiniGames/MiniGameContext.cs
index 643c6d49c..d312e5d02 100644
--- a/src/GameLogic/MiniGames/MiniGameContext.cs
+++ b/src/GameLogic/MiniGames/MiniGameContext.cs
@@ -530,7 +530,16 @@ protected async ValueTask SaveRankingAsync(IEnumerable<(int Rank, Character Char
///
protected async ValueTask ShowGoldenMessageAsync(LocalizedString message, params object?[] args)
{
- await this.ForEachPlayerAsync(player => player.InvokeViewPlugInAsync(p => p.ShowMessageAsync(string.Format(message.GetTranslation(player.Culture), args), MessageType.GoldenCenter)).AsTask()).ConfigureAwait(false);
+ if (string.IsNullOrEmpty(message.Value))
+ {
+ return;
+ }
+
+ await this.ForEachPlayerAsync(player => player.InvokeViewPlugInAsync(p =>
+ message.GetTranslation(player.Culture) is { Length: > 0 } translation
+ ? p.ShowMessageAsync(string.Format(translation, args), MessageType.GoldenCenter)
+ : ValueTask.CompletedTask)
+ .AsTask()).ConfigureAwait(false);
}
///
diff --git a/src/GameLogic/PlugIns/ChatCommands/ClearInventoryChatCommandPlugIn.cs b/src/GameLogic/PlugIns/ChatCommands/ClearInventoryChatCommandPlugIn.cs
index cfd5c50fc..7f66cf056 100644
--- a/src/GameLogic/PlugIns/ChatCommands/ClearInventoryChatCommandPlugIn.cs
+++ b/src/GameLogic/PlugIns/ChatCommands/ClearInventoryChatCommandPlugIn.cs
@@ -75,7 +75,11 @@ protected override async ValueTask DoHandleCommandAsync(Player player, Arguments
if (!this.pendingConfirmations.TryGetValue(playerId, out var confirmationTime) || (DateTime.UtcNow - confirmationTime).TotalSeconds > ConfirmationTimeoutSeconds)
{
this.pendingConfirmations[playerId] = DateTime.UtcNow;
- await player.ShowBlueMessageAsync(configuration.ConfirmationMessage.GetTranslation(player.Culture)).ConfigureAwait(false);
+ if (configuration.ConfirmationMessage.GetTranslation(player.Culture) is { Length: > 0 } message)
+ {
+ await player.ShowBlueMessageAsync(message).ConfigureAwait(false);
+ }
+
return;
}
@@ -94,7 +98,11 @@ protected override async ValueTask DoHandleCommandAsync(Player player, Arguments
if (removeMoney && !player.TryRemoveMoney(configuration.MoneyCost))
{
- await player.ShowBlueMessageAsync(configuration.NotEnoughMoneyMessage.GetTranslation(player.Culture)).ConfigureAwait(false);
+ if (configuration.NotEnoughMoneyMessage.GetTranslation(player.Culture) is { Length: > 0 } notEnoughMoneyMessage)
+ {
+ await player.ShowBlueMessageAsync(notEnoughMoneyMessage).ConfigureAwait(false);
+ }
+
return;
}
@@ -103,7 +111,10 @@ protected override async ValueTask DoHandleCommandAsync(Player player, Arguments
await targetPlayer.DestroyInventoryItemAsync(item).ConfigureAwait(false);
}
- await player.ShowBlueMessageAsync(configuration.InventoryClearedMessage.GetTranslation(player.Culture)).ConfigureAwait(false);
+ if (configuration.InventoryClearedMessage.GetTranslation(player.Culture) is { Length: > 0 } clearedMessage)
+ {
+ await player.ShowBlueMessageAsync(clearedMessage).ConfigureAwait(false);
+ }
}
///
diff --git a/src/GameLogic/PlugIns/ChatCommands/NpcChatCommandPlugIn.cs b/src/GameLogic/PlugIns/ChatCommands/NpcChatCommandPlugIn.cs
index 22933d3d5..4e09c608a 100644
--- a/src/GameLogic/PlugIns/ChatCommands/NpcChatCommandPlugIn.cs
+++ b/src/GameLogic/PlugIns/ChatCommands/NpcChatCommandPlugIn.cs
@@ -82,7 +82,11 @@ protected override async ValueTask DoHandleCommandAsync(Player player, Arguments
if (configuration.MinimumVipLevel > 0 && (player.Attributes?[Stats.IsVip] ?? 0) < configuration.MinimumVipLevel)
{
- await player.ShowBlueMessageAsync(configuration.InsufficientVipLevelMessage.GetTranslation(player.Culture)).ConfigureAwait(false);
+ if (configuration.InsufficientVipLevelMessage.GetTranslation(player.Culture) is { Length: > 0 } message)
+ {
+ await player.ShowBlueMessageAsync(message).ConfigureAwait(false);
+ }
+
return;
}
diff --git a/src/GameLogic/PlugIns/ChatCommands/OpenWarehouseChatCommandPlugIn.cs b/src/GameLogic/PlugIns/ChatCommands/OpenWarehouseChatCommandPlugIn.cs
index 6e73f42eb..e8438bfef 100644
--- a/src/GameLogic/PlugIns/ChatCommands/OpenWarehouseChatCommandPlugIn.cs
+++ b/src/GameLogic/PlugIns/ChatCommands/OpenWarehouseChatCommandPlugIn.cs
@@ -53,7 +53,11 @@ protected override async ValueTask DoHandleCommandAsync(Player player, Arguments
if (configuration.MinimumVipLevel > 0 && (player.Attributes?[Stats.IsVip] ?? 0) < configuration.MinimumVipLevel)
{
- await player.ShowBlueMessageAsync(configuration.InsufficientVipLevelMessage.GetTranslation(player.Culture)).ConfigureAwait(false);
+ if (configuration.InsufficientVipLevelMessage.GetTranslation(player.Culture) is { Length: > 0 } message)
+ {
+ await player.ShowBlueMessageAsync(message).ConfigureAwait(false);
+ }
+
return;
}
diff --git a/src/GameLogic/PlugIns/InvasionEvents/BaseInvasionPlugIn.cs b/src/GameLogic/PlugIns/InvasionEvents/BaseInvasionPlugIn.cs
index 4bf38de65..99c2e03e9 100644
--- a/src/GameLogic/PlugIns/InvasionEvents/BaseInvasionPlugIn.cs
+++ b/src/GameLogic/PlugIns/InvasionEvents/BaseInvasionPlugIn.cs
@@ -217,7 +217,7 @@ protected async Task TrySendStartMessageAsync(Player player, LocalizedString map
return;
}
- var message = (configuration.Message?.ToString() ?? PlugInResources.BaseInvasionPlugIn_DefaultStartMessage).Replace("{mapName}", mapName.GetTranslation(player.Culture), StringComparison.InvariantCulture);
+ var message = (configuration.Message.GetTranslation(player.Culture) ?? PlugInResources.BaseInvasionPlugIn_DefaultStartMessage).Replace("{mapName}", mapName.GetTranslation(player.Culture), StringComparison.InvariantCulture);
if (this.IsPlayerOnMap(player))
{
diff --git a/src/GameLogic/PlugIns/PeriodicTasks/HappyHourPlugIn.cs b/src/GameLogic/PlugIns/PeriodicTasks/HappyHourPlugIn.cs
index bd9c6f799..18197f2e3 100644
--- a/src/GameLogic/PlugIns/PeriodicTasks/HappyHourPlugIn.cs
+++ b/src/GameLogic/PlugIns/PeriodicTasks/HappyHourPlugIn.cs
@@ -124,7 +124,7 @@ protected async Task TrySendStartMessageAsync(Player player)
try
{
- var message = configuration.Message?.GetTranslation(player.Culture) ?? player.GetLocalizedMessage(nameof(PlayerMessage.HappyHourEventHasBeenStarted));
+ var message = configuration.Message.GetTranslation(player.Culture) is { Length: > 0 } translation ? translation : player.GetLocalizedMessage(nameof(PlayerMessage.HappyHourEventHasBeenStarted));
await player.InvokeViewPlugInAsync(p => p.ShowMessageAsync(message, Interfaces.MessageType.GoldenCenter)).ConfigureAwait(false);
}
catch (Exception ex)
diff --git a/src/GameLogic/PlugIns/PeriodicTasks/PeriodicTaskConfiguration.cs b/src/GameLogic/PlugIns/PeriodicTasks/PeriodicTaskConfiguration.cs
index 64ff9f68d..39454581d 100644
--- a/src/GameLogic/PlugIns/PeriodicTasks/PeriodicTaskConfiguration.cs
+++ b/src/GameLogic/PlugIns/PeriodicTasks/PeriodicTaskConfiguration.cs
@@ -33,7 +33,7 @@ public class PeriodicTaskConfiguration
/// Gets or sets the text which prints as a golden message in the game.
///
[Display(ResourceType = typeof(PlugInResources), Name = nameof(PlugInResources.PeriodicTaskConfiguration_Message_Name))]
- public LocalizedString? Message { get; set; }
+ public LocalizedString Message { get; set; }
///
/// Generate a sequence of time points like [00:00, 00:01, ...].
diff --git a/src/GameLogic/PlugIns/QuestMonsterKillCountPlugIn.cs b/src/GameLogic/PlugIns/QuestMonsterKillCountPlugIn.cs
index dedc903cc..e94f8112d 100644
--- a/src/GameLogic/PlugIns/QuestMonsterKillCountPlugIn.cs
+++ b/src/GameLogic/PlugIns/QuestMonsterKillCountPlugIn.cs
@@ -54,10 +54,11 @@ public async ValueTask AttackableGotKilledAsync(IAttackable killed, IAttacker? k
requirementState!.KillCount++;
- if (killRequirement.MinimumNumber >= requirementState!.KillCount)
+ if (killRequirement.MinimumNumber >= requirementState!.KillCount
+ && configuration.Message.GetTranslation(player.Culture) is { Length: > 0 } translation)
{
var message = string.Format(
- configuration.Message.GetTranslation(player.Culture),
+ translation,
questState.ActiveQuest.Name.GetTranslation(player.Culture),
monster.Definition.Designation.GetTranslation(player.Culture),
requirementState.KillCount,
diff --git a/src/GameLogic/PlugIns/WanderingMerchants/WanderingMerchantsPlugIn.cs b/src/GameLogic/PlugIns/WanderingMerchants/WanderingMerchantsPlugIn.cs
index 0b3052dc7..ff9376cf6 100644
--- a/src/GameLogic/PlugIns/WanderingMerchants/WanderingMerchantsPlugIn.cs
+++ b/src/GameLogic/PlugIns/WanderingMerchants/WanderingMerchantsPlugIn.cs
@@ -22,7 +22,6 @@ public object CreateDefaultConfig()
{
return new WanderingMerchantsConfiguration
{
- Message = null,
PreStartMessageDelay = TimeSpan.Zero,
// we check every minute if we have to move a merchant.
diff --git a/src/GameServer/RemoteView/ShowMessagePlugIn.cs b/src/GameServer/RemoteView/ShowMessagePlugIn.cs
index f9930b379..dc9775d5c 100644
--- a/src/GameServer/RemoteView/ShowMessagePlugIn.cs
+++ b/src/GameServer/RemoteView/ShowMessagePlugIn.cs
@@ -28,6 +28,11 @@ public class ShowMessagePlugIn : IShowMessagePlugIn
///
public async ValueTask ShowMessageAsync(string message, OpenMU.Interfaces.MessageType messageType)
{
+ if (string.IsNullOrEmpty(message))
+ {
+ return;
+ }
+
const int maxMessageLength = 241;
if (Encoding.UTF8.GetByteCount(message) > maxMessageLength)
diff --git a/src/Interfaces/LocalizedString.cs b/src/Interfaces/LocalizedString.cs
index 44bc9d953..643c2c421 100644
--- a/src/Interfaces/LocalizedString.cs
+++ b/src/Interfaces/LocalizedString.cs
@@ -139,7 +139,7 @@ public static implicit operator LocalizedString(string localizedString)
///
public override string? ToString()
{
- return this.GetTranslation(CultureInfo.CurrentCulture);
+ return this.Value is null ? null : this.GetTranslation(CultureInfo.CurrentCulture);
}
///
@@ -155,10 +155,12 @@ public static implicit operator LocalizedString(string localizedString)
/// is and no specific translation exists,
/// or an empty string if neither is available.
///
- public string GetTranslation(CultureInfo cultureInfo, bool fallbackToNeutral = true)
+ public string? GetTranslation(CultureInfo cultureInfo, bool fallbackToNeutral = true)
{
var span = this.GetTranslationAsSpan(cultureInfo, fallbackToNeutral);
- return new(span);
+ return span.IsEmpty
+ ? null
+ : new(span);
}
///
diff --git a/src/Network/MUnique.OpenMU.Network.csproj b/src/Network/MUnique.OpenMU.Network.csproj
index 2ad6e62af..aa9c30afd 100644
--- a/src/Network/MUnique.OpenMU.Network.csproj
+++ b/src/Network/MUnique.OpenMU.Network.csproj
@@ -45,9 +45,6 @@
-
-
-
diff --git a/src/Persistence/EntityFramework/EntityDataContextFactory.cs b/src/Persistence/EntityFramework/EntityDataContextFactory.cs
new file mode 100644
index 000000000..eafb0c868
--- /dev/null
+++ b/src/Persistence/EntityFramework/EntityDataContextFactory.cs
@@ -0,0 +1,24 @@
+//
+// Licensed under the MIT License. See LICENSE file in the project root for full license information.
+//
+
+namespace MUnique.OpenMU.Persistence.EntityFramework;
+
+using Microsoft.EntityFrameworkCore.Design;
+
+///
+/// Design-time factory for .
+///
+public class EntityDataContextFactory : IDesignTimeDbContextFactory
+{
+ ///
+ public EntityDataContext CreateDbContext(string[] args)
+ {
+ if (!ConnectionConfigurator.IsInitialized)
+ {
+ ConnectionConfigurator.Initialize(new ConfigFileDatabaseConnectionStringProvider());
+ }
+
+ return new EntityDataContext();
+ }
+}
\ No newline at end of file
diff --git a/src/Persistence/EntityFramework/Migrations/20260202204523_NonNullableLocalizedString.Designer.cs b/src/Persistence/EntityFramework/Migrations/20260202204523_NonNullableLocalizedString.Designer.cs
new file mode 100644
index 000000000..1078742c8
--- /dev/null
+++ b/src/Persistence/EntityFramework/Migrations/20260202204523_NonNullableLocalizedString.Designer.cs
@@ -0,0 +1,5192 @@
+//
+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("20260202204523_NonNullableLocalizedString")]
+ partial class NonNullableLocalizedString
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "10.0.2")
+ .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("IsTemplate")
+ .HasColumnType("boolean");
+
+ b.Property("IsVaultExtended")
+ .HasColumnType("boolean");
+
+ b.Property("LanguageIsoCode")
+ .IsRequired()
+ .ValueGeneratedOnAdd()
+ .HasMaxLength(3)
+ .HasColumnType("character varying(3)")
+ .HasDefaultValue("en");
+
+ 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.AreaSkillSettings", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("uuid");
+
+ b.Property("DelayBetweenHits")
+ .HasColumnType("interval");
+
+ b.Property("DelayPerOneDistance")
+ .HasColumnType("interval");
+
+ b.Property("FrustumDistance")
+ .HasColumnType("real");
+
+ b.Property("FrustumEndWidth")
+ .HasColumnType("real");
+
+ b.Property("FrustumStartWidth")
+ .HasColumnType("real");
+
+ b.Property("HitChancePerDistanceMultiplier")
+ .HasColumnType("real");
+
+ b.Property("MaximumNumberOfHitsPerAttack")
+ .HasColumnType("integer");
+
+ b.Property("MaximumNumberOfHitsPerTarget")
+ .HasColumnType("integer");
+
+ b.Property("MinimumNumberOfHitsPerTarget")
+ .HasColumnType("integer");
+
+ b.Property("ProjectileCount")
+ .HasColumnType("integer");
+
+ b.Property("TargetAreaDiameter")
+ .HasColumnType("real");
+
+ b.Property("UseDeferredHits")
+ .HasColumnType("boolean");
+
+ b.Property("UseFrustumFilter")
+ .HasColumnType("boolean");
+
+ b.Property("UseTargetAreaFilter")
+ .HasColumnType("boolean");
+
+ b.HasKey("Id");
+
+ b.ToTable("AreaSkillSettings", "config");
+ });
+
+ 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.Property("MaximumValue")
+ .HasColumnType("real");
+
+ 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("AggregateType")
+ .HasColumnType("integer");
+
+ 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("SkillId")
+ .HasColumnType("uuid");
+
+ b.Property("TargetAttributeId")
+ .HasColumnType("uuid");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CharacterClassId");
+
+ b.HasIndex("InputAttributeId");
+
+ b.HasIndex("OperandAttributeId");
+
+ b.HasIndex("PowerUpDefinitionValueId");
+
+ b.HasIndex("SkillId");
+
+ 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")
+ .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("IsStoreOpened")
+ .HasColumnType("boolean");
+
+ 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("StoreName")
+ .HasColumnType("text");
+
+ 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")
+ .IsRequired()
+ .HasColumnType("text");
+
+ b.Property("InstalledAt")
+ .HasColumnType("timestamp with time zone");
+
+ b.Property("Name")
+ .IsRequired()
+ .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("ClampMoneyOnPickup")
+ .HasColumnType("boolean");
+
+ b.Property("DamagePerOneItemDurability")
+ .HasColumnType("double precision");
+
+ b.Property("DamagePerOnePetDurability")
+ .HasColumnType("double precision");
+
+ b.Property("DuelConfigurationId")
+ .HasColumnType("uuid");
+
+ b.Property("ExperienceFormula")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text")
+ .HasDefaultValue("if(level == 0, 0, if(level < 256, 10 * (level + 8) * (level - 1) * (level - 1), (10 * (level + 8) * (level - 1) * (level - 1)) + (1000 * (level - 247) * (level - 256) * (level - 256))))");
+
+ 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("MasterExperienceFormula")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("text")
+ .HasDefaultValue("(505 * level * level * level) + (35278500 * level) + (228045 * level * level)");
+
+ b.Property("MaximumCharactersPerAccount")
+ .HasColumnType("smallint");
+
+ b.Property("MaximumInventoryMoney")
+ .HasColumnType("integer");
+
+ b.Property("MaximumItemOptionLevelDrop")
+ .HasColumnType("smallint");
+
+ 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("PreventExperienceOverflow")
+ .HasColumnType("boolean");
+
+ 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