baseline: OpenMU upstream b5a0961 (fresh source)

This commit is contained in:
Acentech Dev
2026-07-14 19:00:35 +03:00
parent 450402e47d
commit 36fc125d5c
11968 changed files with 748705 additions and 0 deletions

View File

@@ -0,0 +1,108 @@
// <copyright file="JsonQueryBuilderTests.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.Initialization.Tests;
using System.Diagnostics;
using System.IO;
using Microsoft.EntityFrameworkCore;
using MUnique.OpenMU.Persistence.EntityFramework;
using MUnique.OpenMU.Persistence.EntityFramework.Json;
using Account = MUnique.OpenMU.Persistence.EntityFramework.Model.Account;
using GameConfiguration = MUnique.OpenMU.Persistence.EntityFramework.Model.GameConfiguration;
/// <summary>
/// Tests for the <see cref="JsonQueryBuilder"/>.
/// </summary>
[TestFixture]
internal class JsonQueryBuilderTests
{
/// <summary>
/// Sets up this instance.
/// </summary>
[OneTimeSetUp]
public void Setup()
{
ConnectionConfigurator.Initialize(new ConfigFileDatabaseConnectionStringProvider());
}
/// <summary>
/// Tests the json query builder for the <see cref="GameConfiguration"/> type.
/// </summary>
[Test]
public void JsonQueryBuilderGameConfiguration()
{
using var installationContext = new ConfigurationContext();
var type = installationContext.Model.GetEntityTypes().FirstOrDefault(t => t.ClrType == typeof(GameConfiguration));
string result;
Stopwatch stopwatch = new();
stopwatch.Start();
try
{
var builder = new GameConfigurationJsonQueryBuilder();
result = builder.BuildJsonQueryForEntity(type!);
}
finally
{
stopwatch.Stop();
}
result = $"-- Json query created in {stopwatch.ElapsedMilliseconds} ms:{Environment.NewLine}" + result;
//// File.WriteAllText(@"C:\temp\json_GameConfiguration.txt", result);
}
/// <summary>
/// Tests the json query builder for the <see cref="Account"/> type.
/// </summary>
[Test]
public void JsonQueryBuilderAccount()
{
using var installationContext = new ConfigurationContext();
var type = installationContext.Model.GetEntityTypes().FirstOrDefault(t => t.ClrType == typeof(Account));
string result;
Stopwatch stopwatch = new();
stopwatch.Start();
try
{
var builder = new JsonQueryBuilder();
result = builder.BuildJsonQueryForEntity(type!);
}
finally
{
stopwatch.Stop();
}
result = $"-- Json query created in {stopwatch.ElapsedMilliseconds} ms:{Environment.NewLine}" + result;
//// File.WriteAllText(@"C:\temp\json_Account.txt", result);
}
/// <summary>
/// Loads the <see cref="GameConfiguration"/> using the <see cref="JsonQueryBuilder"/> and the <see cref="JsonObjectLoader"/>.
/// It always fails, because it reports the taken time.
/// </summary>
[Test]
[Ignore("It hits the database.")]
public async Task LoadConfigByJsonAsync()
{
await using var installationContext = new ConfigurationContext();
installationContext.Database.OpenConnection();
var builder = new GameConfigurationJsonObjectLoader();
IEnumerable<GameConfiguration> result;
Stopwatch stopwatch = new();
stopwatch.Start();
try
{
result = await builder.LoadAllObjectsAsync<EntityFramework.Model.GameConfiguration>(installationContext).ConfigureAwait(false);
result = result.ToList();
}
finally
{
stopwatch.Stop();
}
Assert.That(result, Is.Not.Null);
Assert.That(result.Count, Is.Not.EqualTo(0));
Assert.That(stopwatch.ElapsedMilliseconds, Is.EqualTo(0));
}
}

View File

@@ -0,0 +1,54 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
<OutputPath>bin\Debug\</OutputPath>
<DocumentationFile>bin\Debug\MUnique.OpenMU.Persistence.Initialization.Tests.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
<OutputPath>bin\Release\</OutputPath>
<DocumentationFile>bin\Release\MUnique.OpenMU.Persistence.Initialization.Tests.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\src\SharedAssemblyInfo.cs" Link="Properties\SharedAssemblyInfo.cs" />
<Compile Include="..\..\src\SharedGlobalUsings.cs" Link="SharedGlobalUsings.cs" />
<Compile Include="..\SharedTestUsings.cs" Link="SharedTestUsings.cs" />
</ItemGroup>
<ItemGroup>
<AdditionalFiles Include="..\..\src\stylecop.json" Link="stylecop.json" />
</ItemGroup>
<ItemGroup>
<None Include="..\..\src\.editorconfig" Link=".editorconfig" />
</ItemGroup>
<ItemGroup>
<Content Include="..\..\src\Persistence\EntityFramework\ConnectionSettings.xml" Link="ConnectionSettings.xml">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" />
<PackageReference Include="NUnit" />
<PackageReference Include="NUnit3TestAdapter" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\AttributeSystem\MUnique.OpenMU.AttributeSystem.csproj" />
<ProjectReference Include="..\..\src\DataModel\MUnique.OpenMU.DataModel.csproj" />
<ProjectReference Include="..\..\src\Persistence\Initialization\MUnique.OpenMU.Persistence.Initialization.csproj" />
<ProjectReference Include="..\..\src\Persistence\InMemory\MUnique.OpenMU.Persistence.InMemory.csproj" />
<ProjectReference Include="..\..\src\Persistence\MUnique.OpenMU.Persistence.csproj" />
<ProjectReference Include="..\..\src\Persistence\EntityFramework\MUnique.OpenMU.Persistence.EntityFramework.csproj" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,10 @@
// <copyright file="AssemblyInfo.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
using System.Reflection;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("MUnique.OpenMU.Persistence.Initialization.EntityFramework")]

View File

@@ -0,0 +1,185 @@
// <copyright file="TestInitializationWithEfCore.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>
namespace MUnique.OpenMU.Persistence.Initialization.Tests;
using Microsoft.Extensions.Logging.Abstractions;
using MUnique.OpenMU.DataModel;
using MUnique.OpenMU.DataModel.Configuration;
using MUnique.OpenMU.GameLogic;
using MUnique.OpenMU.Persistence.EntityFramework;
using MUnique.OpenMU.Persistence.Initialization.Updates;
using MUnique.OpenMU.Persistence.InMemory;
/// <summary>
/// The main program class.
/// </summary>
[TestFixture]
internal class TestInitializationWithEfCore
{
private const byte IcarusMapNumber = 10;
private static readonly Guid FeatherDropGroupId = new(0x200, IcarusMapNumber, 1, 0, 0, 0, 0, 0, 0, 0, 0);
private static readonly Guid CrestDropGroupId = new(0x200, IcarusMapNumber, 2, 0, 0, 0, 0, 0, 0, 0, 0);
/// <summary>
/// Tests the data initialization using the entity framework core.
/// </summary>
[Test]
[Ignore("This is not a real test which should run automatically.")]
public async Task SetupDatabaseAndTestLoadingDataAsync()
{
var manager = new PersistenceContextProvider(new NullLoggerFactory(), null);
using var update = await manager.ReCreateDatabaseAsync().ConfigureAwait(false);
await this.TestDataInitializationAsync(new PersistenceContextProvider(new NullLoggerFactory(), null)).ConfigureAwait(false);
}
/// <summary>
/// Tests the data initialization using the in-memory persistence.
/// </summary>
[Test]
public async Task TestDataInitializationInMemoryAsync()
{
await this.TestDataInitializationAsync(new InMemoryPersistenceContextProvider()).ConfigureAwait(false);
}
/// <summary>
/// Tests the data initialization using the in-memory persistence.
/// </summary>
[Test]
public async Task TestSeason6DataAsync()
{
var contextProvider = new InMemoryPersistenceContextProvider();
var dataInitialization = new VersionSeasonSix.DataInitialization(contextProvider, new NullLoggerFactory());
await dataInitialization.CreateInitialDataAsync(1, true).ConfigureAwait(false);
await this.AssertIcarusFeatherAndCrestDropGroupsAsync(contextProvider).ConfigureAwait(false);
await this.TestIfItemsFitIntoInventoriesAsync(contextProvider).ConfigureAwait(false);
}
/// <summary>
/// Tests that applying the update for Crest of Monarch in Season 6 is idempotent.
/// </summary>
[Test]
public async Task TestSeason6CrestOfMonarchUpdatePlugInAsync()
{
var contextProvider = new InMemoryPersistenceContextProvider();
var dataInitialization = new VersionSeasonSix.DataInitialization(contextProvider, new NullLoggerFactory());
await dataInitialization.CreateInitialDataAsync(1, true).ConfigureAwait(false);
using var context = contextProvider.CreateNewContext();
var gameConfiguration = (await context.GetAsync<GameConfiguration>().ConfigureAwait(false)).First();
var map = gameConfiguration.Maps.First(m => m.Number == IcarusMapNumber && m.Discriminator == 0);
if (gameConfiguration.DropItemGroups.FirstOrDefault(group => group.GetId() == CrestDropGroupId) is { } existingCrestGroup)
{
map.DropItemGroups.Remove(existingCrestGroup);
gameConfiguration.DropItemGroups.Remove(existingCrestGroup);
}
var update = new AddCrestOfMonarchDropGroupUpdateSeason6();
await update.ApplyUpdateAsync(context, gameConfiguration).ConfigureAwait(false);
await update.ApplyUpdateAsync(context, gameConfiguration).ConfigureAwait(false);
var groups = gameConfiguration.DropItemGroups.Where(group => group.GetId() == CrestDropGroupId).ToList();
Assert.That(groups, Has.Count.EqualTo(1));
Assert.That(map.DropItemGroups.Count(group => group.GetId() == CrestDropGroupId), Is.EqualTo(1));
Assert.That(groups[0].Chance, Is.EqualTo(0.001));
Assert.That(groups[0].MinimumMonsterLevel, Is.EqualTo((byte)82));
Assert.That(groups[0].ItemLevel, Is.EqualTo((byte)1));
Assert.That(groups[0].PossibleItems, Has.Count.EqualTo(1));
Assert.That(groups[0].PossibleItems.Single().Group, Is.EqualTo((byte)13));
Assert.That(groups[0].PossibleItems.Single().Number, Is.EqualTo((short)14));
}
/// <summary>
/// Tests the data initialization using the in-memory persistence.
/// </summary>
[Test]
public async Task Test075DataAsync()
{
var contextProvider = new InMemoryPersistenceContextProvider();
var dataInitialization = new Version075.DataInitialization(contextProvider, new NullLoggerFactory());
await dataInitialization.CreateInitialDataAsync(1, true).ConfigureAwait(false);
await this.TestIfItemsFitIntoInventoriesAsync(contextProvider).ConfigureAwait(false);
}
/// <summary>
/// Tests the data initialization using the in-memory persistence.
/// </summary>
[Test]
public async Task Test095dDataAsync()
{
var contextProvider = new InMemoryPersistenceContextProvider();
var dataInitialization = new Version095d.DataInitialization(contextProvider, new NullLoggerFactory());
await dataInitialization.CreateInitialDataAsync(1, true).ConfigureAwait(false);
await this.TestIfItemsFitIntoInventoriesAsync(contextProvider).ConfigureAwait(false);
}
private async Task TestDataInitializationAsync(IPersistenceContextProvider contextProvider)
{
var initialization = new VersionSeasonSix.DataInitialization(contextProvider, new NullLoggerFactory());
await initialization.CreateInitialDataAsync(3, true).ConfigureAwait(false);
// Loading game configuration
using var context = contextProvider.CreateNewConfigurationContext();
var gameConfiguraton = (await context.GetAsync<DataModel.Configuration.GameConfiguration>().ConfigureAwait(false)).FirstOrDefault();
Assert.That(gameConfiguraton, Is.Not.Null);
// Testing loading of an account
using var accountContext = contextProvider.CreateNewPlayerContext(gameConfiguraton!);
var account1 = await accountContext.GetAccountByLoginNameAsync("test1", "test1").ConfigureAwait(false);
Assert.That(account1, Is.Not.Null);
Assert.That(account1!.LoginName, Is.EqualTo("test1"));
}
private async Task TestIfItemsFitIntoInventoriesAsync(IPersistenceContextProvider contextProvider)
{
using var configContext = contextProvider.CreateNewConfigurationContext();
var config = (await configContext.GetAsync<GameConfiguration>().ConfigureAwait(false)).First();
using var context = contextProvider.CreateNewPlayerContext(config);
var characters = (await context.GetAccountsOrderedByLoginNameAsync(0, 100).ConfigureAwait(false)).SelectMany(a => a.Characters).ToList();
Assert.That(characters, Is.Not.Empty);
byte inventorySize = (byte)(InventoryConstants.EquippableSlotsCount + 64);
foreach (var character in characters)
{
try
{
var storage = character.Inventory!;
var inventory = new Storage(inventorySize, InventoryConstants.EquippableSlotsCount, 0, storage);
Assert.That(inventory.Items.Count(), Is.EqualTo(storage.Items.Count));
}
catch (Exception ex)
{
Assert.Warn($"{ex.Message} Character: {character.Name}");
}
}
}
private async Task AssertIcarusFeatherAndCrestDropGroupsAsync(IPersistenceContextProvider contextProvider)
{
using var context = contextProvider.CreateNewConfigurationContext();
var gameConfiguration = (await context.GetAsync<GameConfiguration>().ConfigureAwait(false)).First();
var map = gameConfiguration.Maps.First(m => m.Number == IcarusMapNumber && m.Discriminator == 0);
var featherGroup = gameConfiguration.DropItemGroups.Single(group => group.GetId() == FeatherDropGroupId);
var crestGroup = gameConfiguration.DropItemGroups.Single(group => group.GetId() == CrestDropGroupId);
Assert.That(map.DropItemGroups.Count(group => group.GetId() == FeatherDropGroupId), Is.EqualTo(1));
Assert.That(map.DropItemGroups.Count(group => group.GetId() == CrestDropGroupId), Is.EqualTo(1));
Assert.That(featherGroup.Chance, Is.EqualTo(0.001));
Assert.That(featherGroup.MinimumMonsterLevel, Is.EqualTo((byte)82));
Assert.That(featherGroup.ItemLevel, Is.Null);
Assert.That(featherGroup.PossibleItems, Has.Count.EqualTo(1));
Assert.That(featherGroup.PossibleItems.Single().Group, Is.EqualTo((byte)13));
Assert.That(featherGroup.PossibleItems.Single().Number, Is.EqualTo((short)14));
Assert.That(crestGroup.Chance, Is.EqualTo(0.001));
Assert.That(crestGroup.MinimumMonsterLevel, Is.EqualTo((byte)82));
Assert.That(crestGroup.ItemLevel, Is.EqualTo((byte)1));
Assert.That(crestGroup.PossibleItems, Has.Count.EqualTo(1));
Assert.That(crestGroup.PossibleItems.Single().Group, Is.EqualTo((byte)13));
Assert.That(crestGroup.PossibleItems.Single().Number, Is.EqualTo((short)14));
}
}