mirror of
https://github.com/oliverbooth/VpSharp
synced 2024-11-23 01:28:48 +00:00
Add support for client extensions
This is currently preliminary, and the only event mapped so far is chat messaging
This commit is contained in:
parent
99fc7120c7
commit
e0666d54e4
@ -0,0 +1,33 @@
|
|||||||
|
using VpSharp.EventData;
|
||||||
|
|
||||||
|
namespace VpSharp.ClientExtensions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Represents the base class for extensions to the <see cref="VirtualParadiseClient" />.
|
||||||
|
/// </summary>
|
||||||
|
public abstract class VirtualParadiseClientExtension
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Initializes a new instance of the <see cref="VirtualParadiseClientExtension" /> class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="client">The owning client.</param>
|
||||||
|
protected VirtualParadiseClientExtension(VirtualParadiseClient client)
|
||||||
|
{
|
||||||
|
Client = client;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets the client to which this extension is registered.
|
||||||
|
/// </summary>
|
||||||
|
/// <value>The owning client.</value>
|
||||||
|
public VirtualParadiseClient Client { get; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called when a chat message is received.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="args">An object containing event data.</param>
|
||||||
|
protected internal virtual Task OnMessageReceived(MessageReceivedEventArgs args)
|
||||||
|
{
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
}
|
68
VpSharp/src/VirtualParadiseClient.Extensions.cs
Normal file
68
VpSharp/src/VirtualParadiseClient.Extensions.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
using System.Reflection;
|
||||||
|
using VpSharp.ClientExtensions;
|
||||||
|
|
||||||
|
namespace VpSharp;
|
||||||
|
|
||||||
|
public sealed partial class VirtualParadiseClient
|
||||||
|
{
|
||||||
|
private readonly List<VirtualParadiseClientExtension> _extensions = new();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an extension to this client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="arguments">The arguments to pass to the extension constructor.</param>
|
||||||
|
/// <typeparam name="T">The type of the extension to add.</typeparam>
|
||||||
|
/// <returns>A new instance of the specified extension.</returns>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// <para><typeparamref name="T" /> is <c>abstract</c>.</para>
|
||||||
|
/// </exception>
|
||||||
|
public T AddExtension<T>(params object?[]? arguments) where T : VirtualParadiseClientExtension
|
||||||
|
{
|
||||||
|
return (AddExtension(typeof(T), arguments) as T)!;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an extension to this client.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="type">The type of the extension to add.</param>
|
||||||
|
/// <param name="arguments">The arguments to pass to the extension constructor.</param>
|
||||||
|
/// <returns>A new instance of the specified extension.</returns>
|
||||||
|
/// <exception cref="ArgumentNullException"><paramref name="type" /> is <see langword="null" />.</exception>
|
||||||
|
/// <exception cref="ArgumentException">
|
||||||
|
/// <para><paramref name="type" /> does not inherit from <see cref="VirtualParadiseClientExtension" />.</para>
|
||||||
|
/// -or-
|
||||||
|
/// <para><paramref name="type" /> is <c>abstract</c>.</para>
|
||||||
|
/// </exception>
|
||||||
|
public VirtualParadiseClientExtension AddExtension(Type type, params object?[]? arguments)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(type);
|
||||||
|
|
||||||
|
if (!type.IsSubclassOf(typeof(VirtualParadiseClientExtension)))
|
||||||
|
{
|
||||||
|
throw new ArgumentException($"Type must inherit from {typeof(VirtualParadiseClientExtension)}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.IsAbstract)
|
||||||
|
{
|
||||||
|
throw new ArgumentException("Extension type cannot be abstract");
|
||||||
|
}
|
||||||
|
|
||||||
|
object?[] argumentsActual = {this};
|
||||||
|
if (arguments is not null)
|
||||||
|
{
|
||||||
|
argumentsActual = argumentsActual.Concat(arguments).ToArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;
|
||||||
|
object? instance = Activator.CreateInstance(type, bindingFlags, null, argumentsActual, CultureInfo.InvariantCulture);
|
||||||
|
if (instance is not VirtualParadiseClientExtension extension)
|
||||||
|
{
|
||||||
|
var innerException = new Exception($"Could not instantiate {type}");
|
||||||
|
throw new TypeInitializationException(type.FullName, innerException);
|
||||||
|
}
|
||||||
|
|
||||||
|
_extensions.Add(extension);
|
||||||
|
return extension;
|
||||||
|
}
|
||||||
|
}
|
@ -2,6 +2,7 @@ using System.Collections.Concurrent;
|
|||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
using System.Threading.Channels;
|
using System.Threading.Channels;
|
||||||
|
using VpSharp.ClientExtensions;
|
||||||
using VpSharp.Entities;
|
using VpSharp.Entities;
|
||||||
using VpSharp.EventData;
|
using VpSharp.EventData;
|
||||||
using VpSharp.Internal;
|
using VpSharp.Internal;
|
||||||
@ -79,6 +80,11 @@ public sealed partial class VirtualParadiseClient
|
|||||||
|
|
||||||
var args = new MessageReceivedEventArgs(message);
|
var args = new MessageReceivedEventArgs(message);
|
||||||
RaiseEvent(MessageReceived, args);
|
RaiseEvent(MessageReceived, args);
|
||||||
|
|
||||||
|
foreach (VirtualParadiseClientExtension extension in _extensions)
|
||||||
|
{
|
||||||
|
extension.OnMessageReceived(args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void OnAvatarAddNativeEvent(IntPtr sender)
|
private async void OnAvatarAddNativeEvent(IntPtr sender)
|
||||||
|
Loading…
Reference in New Issue
Block a user