Skip to content

Commit

Permalink
Implemented hot reload of configuration
Browse files Browse the repository at this point in the history
When a config is changed and saved by an entity framework context:
* it will forward these changes to a IConfigurationChangeListener which is specific to the Persistence.EntityFramework.
* The implementation of that will
  * update the cached configuration objects and their parent objects, in case it's an collection
  * notify an instance of a ConfigurationChangeHandler which also existed before
  * The change handler will notify the change mediator (game logic), on which several logic objects will subscribe for changes

To make this work, especially updating the cached objects, I had to implement something like ICloneable<T> and Assignable<T>. I did this by implementing a code generator and a CloneableAttribute. The referencing of it might need some adaptions as it's probably only working in debug build right now.
  • Loading branch information
sven-n committed Oct 27, 2023
1 parent f279efd commit 2211ee6
Show file tree
Hide file tree
Showing 248 changed files with 3,547 additions and 298 deletions.
14 changes: 14 additions & 0 deletions src/Annotations/CloneableAttribute.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// <copyright file="CloneableAttribute.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.Annotations;

/// <summary>
/// Classes marked with this attribute will get a generic Clonable-Interface
/// implemented by a code generator.
/// </summary>
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public sealed class CloneableAttribute : Attribute
{
}
12 changes: 12 additions & 0 deletions src/Annotations/MUnique.OpenMU.Annotations.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<LangVersion>latest</LangVersion>
<Nullable>enable</Nullable>
<WarningsAsErrors>nullable;CS4014;VSTHRD110;VSTHRD100</WarningsAsErrors>
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</PropertyGroup>

</Project>
51 changes: 51 additions & 0 deletions src/DataModel/AssignableExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// <copyright file="AssignableExtensions.cs" company="MUnique">
// Licensed under the MIT License. See LICENSE file in the project root for full license information.
// </copyright>

namespace MUnique.OpenMU.DataModel;

using MUnique.OpenMU.DataModel.Configuration;

/// <summary>
/// Extensions for <see cref="IAssignable{T}"/>.
/// </summary>
public static class AssignableExtensions
{
/// <summary>
/// Assigns a collection to another one, resolving the objects to the ones
/// which are contained in the given <see cref="GameConfiguration"/>.
/// </summary>
/// <typeparam name="T">The type of the collection elements.</typeparam>
/// <param name="collection">The target collection.</param>
/// <param name="other">The other collection.</param>
/// <param name="gameConfiguration">The game configuration.</param>
public static void AssignCollection<T>(this ICollection<T> collection, ICollection<T> other, GameConfiguration gameConfiguration)
where T : class
{
var newItems = collection.Except(other).ToList();
var oldItems = other.Except(collection).ToList();

oldItems.ForEach(i => collection.Remove(i));
newItems.ForEach(i => collection.Add(
gameConfiguration.GetObjectOfConfig(i)
?? (i as ICloneable<T>)?.Clone(gameConfiguration)
?? (i as ICloneable)?.Clone() as T
?? i));
}

/// <summary>
/// Assigns a collection to another one.
/// </summary>
/// <typeparam name="T">The type of the collection values.</typeparam>
/// <param name="collection">The target collection.</param>
/// <param name="other">The other collection.</param>
public static void AssignCollection<T>(this ICollection<T> collection, ICollection<T> other)
where T : struct
{
var newItems = collection.Except(other).ToList();
var oldItems = other.Except(collection).ToList();

oldItems.ForEach(i => collection.Remove(i));
newItems.ForEach(collection.Add);
}
}
4 changes: 3 additions & 1 deletion src/DataModel/Attributes/PowerUpDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
namespace MUnique.OpenMU.DataModel.Attributes;

using System.Globalization;
using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;

/// <summary>
/// The power up definition which describes the boost of an target attribute.
/// </summary>
public class PowerUpDefinition
[Cloneable]
public partial class PowerUpDefinition
{
/// <summary>
/// Gets or sets the target attribute.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Attributes/PowerUpDefinitionValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
namespace MUnique.OpenMU.DataModel.Attributes;

using System.ComponentModel;
using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;

/// <summary>
/// The power up definition value which can consist of a constant value and several related values which are all added together to get the result.
/// </summary>
public class PowerUpDefinitionValue
[Cloneable]
public partial class PowerUpDefinitionValue
{
/// <summary>
/// Gets or sets the constant value part of the value.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/BattleZoneDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines a battle zone.
/// </summary>
public class BattleZoneDefinition
[Cloneable]
public partial class BattleZoneDefinition
{
/// <summary>
/// Gets or sets the battle type.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/CharacterClass.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;
using MUnique.OpenMU.DataModel.Entities;

/// <summary>
/// Defines a character class.
/// </summary>
public class CharacterClass
[Cloneable]
public partial class CharacterClass
{
/// <summary>
/// Gets or sets the id of a character class.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/ChatServerDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Settings for the chat server.
/// </summary>
[AggregateRoot]
public class ChatServerDefinition
[Cloneable]
public partial class ChatServerDefinition
{
/// <summary>
/// Gets or sets the server identifier.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/ConnectServerDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,15 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.Interfaces;

/// <summary>
/// The definition of a connect server.
/// </summary>
[AggregateRoot]
public class ConnectServerDefinition : IConnectServerSettings
[Cloneable]
public partial class ConnectServerDefinition : IConnectServerSettings
{
/// <summary>
/// Gets or sets the id of this definition.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/DropItemGroup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.DataModel.Configuration.Items;

/// <summary>
Expand Down Expand Up @@ -47,7 +48,8 @@ public enum SpecialItemType
/// In the drop generator sort all DropItemGroups by its chance.
/// Classes which can have DropItemGroups: Maps, Monsters(for example the kundun drops), Players(for quest items).
/// </summary>
public class DropItemGroup
[Cloneable]
public partial class DropItemGroup
{
/// <summary>
/// Gets or sets the description.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/EnterGate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines a gate which a player can enter to move to another <see cref="ExitGate"/>.
/// </summary>
public class EnterGate : Gate
[Cloneable]
public partial class EnterGate : Gate
{
/// <summary>
/// Gets or sets the target gate.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/ExitGate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines a gate through which a player enters a map.
/// </summary>
public class ExitGate : Gate
[Cloneable]
public partial class ExitGate : Gate
{
/// <summary>
/// Gets or sets the direction to which the player looks when he enters the map.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/GameClientDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,16 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.Interfaces;
using MUnique.OpenMU.Network.PlugIns;

/// <summary>
/// Defines a game client.
/// </summary>
[AggregateRoot]
public class GameClientDefinition : IGameClientVersion
[Cloneable]
public partial class GameClientDefinition : IGameClientVersion
{
/// <summary>
/// Gets or sets the season.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/GameConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.AttributeSystem;
using MUnique.OpenMU.DataModel.Configuration.Items;
using MUnique.OpenMU.DataModel.Entities;
Expand All @@ -14,7 +15,8 @@ namespace MUnique.OpenMU.DataModel.Configuration;
/// A game configuration contains the whole configuration of a game, directly or indirectly.
/// </summary>
[AggregateRoot]
public class GameConfiguration
[Cloneable]
public partial class GameConfiguration
{
/// <summary>
/// Gets or sets the maximum reachable level.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/GameMapDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.DataModel.Attributes;
using MUnique.OpenMU.DataModel.Configuration.Items;

Expand All @@ -19,7 +20,8 @@ namespace MUnique.OpenMU.DataModel.Configuration;
/// To reflect this requirement on this data model, for each status there must be one game map definition.
/// The switch between this status and its corresponding game map definitions should be done in game logic.
/// </remarks>
public class GameMapDefinition
[Cloneable]
public partial class GameMapDefinition
{
/// <summary>
/// Gets or sets the number of the map.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/GameServerConfiguration.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,14 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines the game server configuration.
/// </summary>
[AggregateRoot]
public class GameServerConfiguration
[Cloneable]
public partial class GameServerConfiguration
{
/// <summary>
/// Gets or sets the maximum number of players which can connect.
Expand Down
4 changes: 3 additions & 1 deletion src/DataModel/Configuration/GameServerDefinition.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
namespace MUnique.OpenMU.DataModel.Configuration;

using System.Globalization;
using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines the configuration of a game server.
/// </summary>
[AggregateRoot]
public class GameServerDefinition
[Cloneable]
public partial class GameServerDefinition
{
/// <summary>
/// Gets or sets the server identifier.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/GameServerEndpoint.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines an endpoint of a game server.
/// </summary>
public class GameServerEndpoint : ServerEndpoint
[Cloneable]
public partial class GameServerEndpoint : ServerEndpoint
{
/// <summary>
/// Gets or sets the alternative published network port. It's reported to the connect server instead of the <see cref="ServerEndpoint.NetworkPort"/>, if not <c>0</c>.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/Gate.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Defines a gate through which a player can exit or enter to other maps.
/// </summary>
public class Gate
[Cloneable]
public partial class Gate
{
/// <summary>
/// Gets or sets the upper left corner, x-coordinate.
Expand Down
5 changes: 4 additions & 1 deletion src/DataModel/Configuration/ItemCrafting/ItemCrafting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@

namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;

using MUnique.OpenMU.Annotations;

/// <summary>
/// Description of IItemCrafting.
/// </summary>
public class ItemCrafting
[Cloneable]
public partial class ItemCrafting
{
/// <summary>
/// Gets or sets the number.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;

using System.Globalization;
using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.DataModel.Configuration.Items;

/// <summary>
/// Describes an required item for a crafting.
/// </summary>
public class ItemCraftingRequiredItem
[Cloneable]
public partial class ItemCraftingRequiredItem
{
/// <summary>
/// Gets or sets the collection of possible items which are valid for this requirement.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,14 @@

namespace MUnique.OpenMU.DataModel.Configuration.ItemCrafting;

using MUnique.OpenMU.Annotations;
using MUnique.OpenMU.DataModel.Configuration.Items;

/// <summary>
/// Defines the resulting item of a crafting.
/// </summary>
public class ItemCraftingResultItem
[Cloneable]
public partial class ItemCraftingResultItem
{
/// <summary>
/// Gets or sets the item definition.
Expand Down
Loading

0 comments on commit 2211ee6

Please sign in to comment.