From ff298a8af509e22274a16da0b2fba7efc40e0005 Mon Sep 17 00:00:00 2001 From: Oliver Booth Date: Sun, 17 Mar 2024 13:27:57 +0000 Subject: [PATCH] refactor!: extract interface for Message This commit also amends the previous commit, where files relevant for User were missed --- VpSharp.Commands/CommandContext.cs | 13 ++-- VpSharp.Commands/CommandsExtension.cs | 4 +- .../VirtualParadiseClientExtension.cs | 4 +- VpSharp/src/Entities/Avatar.cs | 19 +++-- VpSharp/src/Entities/ConsoleMessage.cs | 30 ++++++++ VpSharp/src/Entities/IAvatar.cs | 6 +- VpSharp/src/Entities/IConsoleMessage.cs | 21 ++++++ VpSharp/src/Entities/IMessage.cs | 25 +++++++ VpSharp/src/Entities/IUser.cs | 71 ++++++++++++++++++ VpSharp/src/Entities/IUserMessage.cs | 6 ++ VpSharp/src/Entities/Message.cs | 74 +++++-------------- VpSharp/src/Entities/ObjectBuilder.cs | 4 +- VpSharp/src/Entities/User.cs | 2 +- VpSharp/src/Entities/UserMessage.cs | 17 +++++ VpSharp/src/Entities/VirtualParadiseObject.cs | 2 +- VpSharp/src/InviteRequest.cs | 4 +- VpSharp/src/JoinRequest.cs | 4 +- VpSharp/src/MessageType.cs | 17 ----- VpSharp/src/VirtualParadiseClient.Events.cs | 4 +- .../src/VirtualParadiseClient.NativeEvents.cs | 17 +++-- VpSharp/src/VirtualParadiseClient.Users.cs | 2 +- VpSharp/src/VirtualParadiseClient.cs | 33 ++++----- 22 files changed, 246 insertions(+), 133 deletions(-) create mode 100644 VpSharp/src/Entities/ConsoleMessage.cs create mode 100644 VpSharp/src/Entities/IConsoleMessage.cs create mode 100644 VpSharp/src/Entities/IMessage.cs create mode 100644 VpSharp/src/Entities/IUser.cs create mode 100644 VpSharp/src/Entities/IUserMessage.cs create mode 100644 VpSharp/src/Entities/UserMessage.cs delete mode 100644 VpSharp/src/MessageType.cs diff --git a/VpSharp.Commands/CommandContext.cs b/VpSharp.Commands/CommandContext.cs index 9120e97..e6f4b84 100644 --- a/VpSharp.Commands/CommandContext.cs +++ b/VpSharp.Commands/CommandContext.cs @@ -9,7 +9,7 @@ namespace VpSharp.Commands; /// public sealed class CommandContext { - internal CommandContext(VirtualParadiseClient client, Avatar avatar, string commandName, string alias, + internal CommandContext(VirtualParadiseClient client, IAvatar avatar, string commandName, string alias, string rawArguments) { Client = client; @@ -36,8 +36,8 @@ public sealed class CommandContext /// Gets the avatar who executed the command. /// /// The executing avatar. - public Avatar Avatar { get; } - + public IAvatar Avatar { get; } + /// /// Gets the client which raised the event. /// @@ -65,10 +65,11 @@ public sealed class CommandContext /// regular chat message. /// /// The message which was sent. - public Task RespondAsync(string message, bool ephemeral = false) + public async Task RespondAsync(string message, bool ephemeral = false) { return ephemeral - ? Avatar.SendMessageAsync(Client.CurrentAvatar?.Name, message, FontStyle.Regular, Color.Black) - : Client.SendMessageAsync(message); + ? await Avatar.SendMessageAsync(Client.CurrentAvatar?.Name, message, FontStyle.Regular, Color.Black) + .ConfigureAwait(false) + : await Client.SendMessageAsync(message).ConfigureAwait(false); } } diff --git a/VpSharp.Commands/CommandsExtension.cs b/VpSharp.Commands/CommandsExtension.cs index c952c2e..66def85 100644 --- a/VpSharp.Commands/CommandsExtension.cs +++ b/VpSharp.Commands/CommandsExtension.cs @@ -176,14 +176,14 @@ public sealed class CommandsExtension : VirtualParadiseClientExtension } /// - protected internal override Task OnMessageReceived(Message message) + protected internal override Task OnMessageReceived(IMessage message) { if (message is null) { throw new ArgumentNullException(nameof(message)); } - if (message.Type != MessageType.ChatMessage) + if (message is IUserMessage) { return base.OnMessageReceived(message); } diff --git a/VpSharp/src/ClientExtensions/VirtualParadiseClientExtension.cs b/VpSharp/src/ClientExtensions/VirtualParadiseClientExtension.cs index 98b6702..874177f 100644 --- a/VpSharp/src/ClientExtensions/VirtualParadiseClientExtension.cs +++ b/VpSharp/src/ClientExtensions/VirtualParadiseClientExtension.cs @@ -26,8 +26,8 @@ public abstract class VirtualParadiseClientExtension /// /// Called when a chat message is received. /// - /// An object containing event data. - protected internal virtual Task OnMessageReceived(Message message) + /// The message which was received. + protected internal virtual Task OnMessageReceived(IMessage message) { return Task.CompletedTask; } diff --git a/VpSharp/src/Entities/Avatar.cs b/VpSharp/src/Entities/Avatar.cs index 8722bd7..2486e21 100644 --- a/VpSharp/src/Entities/Avatar.cs +++ b/VpSharp/src/Entities/Avatar.cs @@ -13,7 +13,7 @@ namespace VpSharp.Entities; public sealed class Avatar : IEquatable, IAvatar { private readonly VirtualParadiseClient _client; - private User? _user; + private IUser? _user; internal Avatar(VirtualParadiseClient client, int session) { @@ -172,7 +172,7 @@ public sealed class Avatar : IEquatable, IAvatar /// Gets the user associated with this avatar. /// /// The user. - public async Task GetUserAsync() + public async Task GetUserAsync() { _user ??= await _client.GetUserAsync(UserId).ConfigureAwait(false); return _user; @@ -196,7 +196,7 @@ public sealed class Avatar : IEquatable, IAvatar /// -or- /// is too long to send. /// - public Task SendMessageAsync(string message, FontStyle fontStyle, Color color) + public Task SendMessageAsync(string message, FontStyle fontStyle, Color color) { return SendMessageAsync(null, message, fontStyle, color); } @@ -221,7 +221,7 @@ public sealed class Avatar : IEquatable, IAvatar /// is too long to send. /// /// Passing to will hide the name from the recipient. - public Task SendMessageAsync(string? name, string message, FontStyle fontStyle, Color color) + public Task SendMessageAsync(string? name, string message, FontStyle fontStyle, Color color) { if (message is null) { @@ -267,13 +267,12 @@ public sealed class Avatar : IEquatable, IAvatar avatar = _client.CurrentAvatar!; } - return Task.FromResult(new Message( - MessageType.ConsoleMessage, - name, - message, + return Task.FromResult((IConsoleMessage)new ConsoleMessage( avatar, - fontStyle, - color + avatar.Name, + message, + color, + fontStyle )); } diff --git a/VpSharp/src/Entities/ConsoleMessage.cs b/VpSharp/src/Entities/ConsoleMessage.cs new file mode 100644 index 0000000..f27949c --- /dev/null +++ b/VpSharp/src/Entities/ConsoleMessage.cs @@ -0,0 +1,30 @@ +using System.Drawing; + +namespace VpSharp.Entities; + +/// +/// Represents a chat message that was sent by a user. +/// +public sealed class ConsoleMessage : Message, IConsoleMessage +{ + /// + /// Initializes a new instance of the class. + /// + /// The author of the message. + /// The apparent sender's name of the message. + /// The content of the message. + /// A value representing the color of the message. + /// A value representing the font style of the message. + public ConsoleMessage(IAvatar author, string name, string content, Color color, FontStyle fontStyle) + : base(author, name, content) + { + Color = color; + Style = fontStyle; + } + + /// + public Color Color { get; } + + /// + public FontStyle Style { get; } +} diff --git a/VpSharp/src/Entities/IAvatar.cs b/VpSharp/src/Entities/IAvatar.cs index d97e7d6..4238798 100644 --- a/VpSharp/src/Entities/IAvatar.cs +++ b/VpSharp/src/Entities/IAvatar.cs @@ -70,7 +70,7 @@ public interface IAvatar /// Gets the user associated with this avatar. /// /// The user. - Task GetUserAsync(); + Task GetUserAsync(); /// /// Sends a console message to the avatar with no name. @@ -90,7 +90,7 @@ public interface IAvatar /// -or- /// is too long to send. /// - Task SendMessageAsync(string message, FontStyle fontStyle, Color color); + Task SendMessageAsync(string message, FontStyle fontStyle, Color color); /// /// Sends a console message to the avatar. @@ -112,7 +112,7 @@ public interface IAvatar /// is too long to send. /// /// Passing to will hide the name from the recipient. - Task SendMessageAsync(string? name, string message, FontStyle fontStyle, Color color); + Task SendMessageAsync(string? name, string message, FontStyle fontStyle, Color color); /// /// Sends a URI to this avatar. diff --git a/VpSharp/src/Entities/IConsoleMessage.cs b/VpSharp/src/Entities/IConsoleMessage.cs new file mode 100644 index 0000000..b00b90f --- /dev/null +++ b/VpSharp/src/Entities/IConsoleMessage.cs @@ -0,0 +1,21 @@ +using System.Drawing; + +namespace VpSharp.Entities; + +/// +/// Represents a console message. +/// +public interface IConsoleMessage : IMessage +{ + /// + /// Gets the color of the message. + /// + /// A value representing the color. + Color Color { get; } + + /// + /// Gets the font style of the message. + /// + /// A value representing the font style. + FontStyle Style { get; } +} diff --git a/VpSharp/src/Entities/IMessage.cs b/VpSharp/src/Entities/IMessage.cs new file mode 100644 index 0000000..afd3f4a --- /dev/null +++ b/VpSharp/src/Entities/IMessage.cs @@ -0,0 +1,25 @@ +namespace VpSharp.Entities; + +/// +/// Represents a message. +/// +public interface IMessage +{ + /// + /// Gets the author of the message. + /// + /// The avatar which authored the message. + IAvatar Author { get; } + + /// + /// Gets the content of the message. + /// + /// The content. + string Content { get; } + + /// + /// Gets the apparent sender's name of the message. + /// + /// The sender's name. + string Name { get; } +} diff --git a/VpSharp/src/Entities/IUser.cs b/VpSharp/src/Entities/IUser.cs new file mode 100644 index 0000000..083f109 --- /dev/null +++ b/VpSharp/src/Entities/IUser.cs @@ -0,0 +1,71 @@ +using VpSharp.Exceptions; + +namespace VpSharp.Entities; + +public interface IUser +{ + /// + /// Gets the email address of this user. + /// + /// The email address of this user. + string EmailAddress { get; } + + /// + /// Gets the ID of this user. + /// + /// The user's ID. + int Id { get; } + + /// + /// Gets the date and time at which this user was last online. + /// + /// A representing the date and time this user was last online. + DateTimeOffset LastLogin { get; } + + /// + /// Gets the name of this user. + /// + /// The user's name. + string Name { get; } + + /// + /// Gets the duration for which this user has been online. + /// + /// A representing the duration for which this user has been online. + TimeSpan OnlineTime { get; } + + /// + /// Gets the date and time at which this user was registered. + /// + /// A representing the date and time this user was registered. + DateTimeOffset RegistrationTime { get; } + + /// + /// Determines if two instances are equal. + /// + /// The other instance. + /// + /// if this instance is equal to ; otherwise, . + /// + bool Equals(User? other); + + /// + /// Invites this user to a specified location. + /// + /// + /// The invitation location. If , the client's current location is used. + /// + Task InviteAsync(Location? location = null); + + /// + /// Sends a to join request to the user. + /// + /// + /// If , the client's avatar will not teleport to the requested location automatically. + /// Be careful, there is no way to retrieve + /// + /// The result of the request. + /// This user is invalid and cannot be joined. + /// An unexpected error occurred trying to join the user. + Task JoinAsync(bool suppressTeleport = false); +} diff --git a/VpSharp/src/Entities/IUserMessage.cs b/VpSharp/src/Entities/IUserMessage.cs new file mode 100644 index 0000000..2a94279 --- /dev/null +++ b/VpSharp/src/Entities/IUserMessage.cs @@ -0,0 +1,6 @@ +namespace VpSharp.Entities; + +/// +/// Represents a chat message that was sent by a user. +/// +public interface IUserMessage : IMessage; diff --git a/VpSharp/src/Entities/Message.cs b/VpSharp/src/Entities/Message.cs index 49024e6..c30c653 100644 --- a/VpSharp/src/Entities/Message.cs +++ b/VpSharp/src/Entities/Message.cs @@ -1,67 +1,29 @@ -using System.Drawing; - -namespace VpSharp.Entities; +namespace VpSharp.Entities; /// /// Represents a message. /// -public sealed class Message +public abstract class Message : IMessage { - internal Message( - MessageType type, - string? name, - string content, - IAvatar author, - FontStyle style, - Color color) + /// + /// Initializes a new instance of the class. + /// + /// The author of the message. + /// The apparent sender's name of the message. + /// The content of the message. + protected Message(IAvatar author, string name, string content) { - Type = type; - Name = string.IsNullOrWhiteSpace(name) ? null : name; - Content = content; Author = author; - Style = style; - Color = color; + Content = content; + Name = name; } - /// - /// Gets the message author. - /// - /// The message author. - public IAvatar Author { get; } - - /// - /// Gets the message content. - /// - /// The message content. - public string Content { get; } - - /// - /// Gets the message name. - /// - /// The message name. This will always be equal to the name of the for chat messages. - public string? Name { get; } - - /// - /// Gets the message color. - /// - /// The message color. This will always be for chat messages. - public Color Color { get; } - - /// - /// Gets the message font style. - /// - /// The message font style. This will always be for chat messages. - public FontStyle Style { get; } - - /// - /// Gets the type of this message. - /// - /// The type of this message. - public MessageType Type { get; } - /// - public override string ToString() - { - return $"Message {Author}; Type {Type}; Content {Content}"; - } + public IAvatar Author { get; } + + /// + public string Content { get; } + + /// + public string Name { get; } } diff --git a/VpSharp/src/Entities/ObjectBuilder.cs b/VpSharp/src/Entities/ObjectBuilder.cs index e907ee8..069c30d 100644 --- a/VpSharp/src/Entities/ObjectBuilder.cs +++ b/VpSharp/src/Entities/ObjectBuilder.cs @@ -43,7 +43,7 @@ public abstract class ObjectBuilder /// This property may only be set during an object load, and will throw at /// any other point. /// - public Option Owner { get; set; } + public Option Owner { get; set; } /// /// Gets or sets the position of the object. @@ -90,7 +90,7 @@ public abstract class ObjectBuilder throw new InvalidOperationException("Owner can only be assigned during an object load."); } - User oldOwner = TargetObject.Owner; + IUser oldOwner = TargetObject.Owner; _ = vp_int_set(handle, ObjectUserId, Owner.ValueOr(oldOwner).Id); } diff --git a/VpSharp/src/Entities/User.cs b/VpSharp/src/Entities/User.cs index 3cae146..f4c417e 100644 --- a/VpSharp/src/Entities/User.cs +++ b/VpSharp/src/Entities/User.cs @@ -8,7 +8,7 @@ namespace VpSharp.Entities; /// /// Represents a Virtual Paradise user. /// -public sealed class User : IEquatable +public sealed class User : IEquatable, IUser { private readonly VirtualParadiseClient _client; diff --git a/VpSharp/src/Entities/UserMessage.cs b/VpSharp/src/Entities/UserMessage.cs new file mode 100644 index 0000000..832e81f --- /dev/null +++ b/VpSharp/src/Entities/UserMessage.cs @@ -0,0 +1,17 @@ +namespace VpSharp.Entities; + +/// +/// Represents a chat message that was sent by a user. +/// +public sealed class UserMessage : Message, IUserMessage +{ + /// + /// Initializes a new instance of the class. + /// + /// The author of the message. + /// The content of the message. + public UserMessage(IAvatar author, string content) + : base(author, author.Name, content) + { + } +} diff --git a/VpSharp/src/Entities/VirtualParadiseObject.cs b/VpSharp/src/Entities/VirtualParadiseObject.cs index 69dcd49..4566505 100644 --- a/VpSharp/src/Entities/VirtualParadiseObject.cs +++ b/VpSharp/src/Entities/VirtualParadiseObject.cs @@ -51,7 +51,7 @@ public abstract class VirtualParadiseObject : IEquatable /// Gets the owner of this object. /// /// The owner of this object. - public User Owner { get; internal set; } = null!; + public IUser Owner { get; internal set; } = null!; internal byte[] Data { get; set; } = Array.Empty(); diff --git a/VpSharp/src/InviteRequest.cs b/VpSharp/src/InviteRequest.cs index e4b4160..aa13560 100644 --- a/VpSharp/src/InviteRequest.cs +++ b/VpSharp/src/InviteRequest.cs @@ -16,7 +16,7 @@ public sealed class InviteRequest : IEquatable VirtualParadiseClient client, int requestId, string name, - User user, + IUser user, Location location) { Name = name; @@ -42,7 +42,7 @@ public sealed class InviteRequest : IEquatable /// Gets the user which sent the request. /// /// The user which sent the request. - public User User { get; } + public IUser User { get; } /// /// Returns a value indicating whether two instances are equal. diff --git a/VpSharp/src/JoinRequest.cs b/VpSharp/src/JoinRequest.cs index 8a05324..9bd935c 100644 --- a/VpSharp/src/JoinRequest.cs +++ b/VpSharp/src/JoinRequest.cs @@ -12,7 +12,7 @@ public sealed class JoinRequest : IEquatable private readonly VirtualParadiseClient _client; private readonly int _requestId; - internal JoinRequest(VirtualParadiseClient client, int requestId, string name, User user) + internal JoinRequest(VirtualParadiseClient client, int requestId, string name, IUser user) { Name = name; User = user; @@ -30,7 +30,7 @@ public sealed class JoinRequest : IEquatable /// Gets the user which sent the request. /// /// The user which sent the request. - public User User { get; } + public IUser User { get; } /// /// Returns a value indicating whether two instances are equal. diff --git a/VpSharp/src/MessageType.cs b/VpSharp/src/MessageType.cs deleted file mode 100644 index b57dfbe..0000000 --- a/VpSharp/src/MessageType.cs +++ /dev/null @@ -1,17 +0,0 @@ -namespace VpSharp; - -/// -/// An enumeration of message types. -/// -public enum MessageType -{ - /// - /// A chat message sent by an avatar. - /// - ChatMessage, - - /// - /// A console message sent by a bot. - /// - ConsoleMessage -} diff --git a/VpSharp/src/VirtualParadiseClient.Events.cs b/VpSharp/src/VirtualParadiseClient.Events.cs index 0ce4eac..dffb7bb 100644 --- a/VpSharp/src/VirtualParadiseClient.Events.cs +++ b/VpSharp/src/VirtualParadiseClient.Events.cs @@ -13,7 +13,7 @@ public sealed partial class VirtualParadiseClient private readonly Subject _avatarTypeChanged = new(); private readonly Subject _inviteRequestReceived = new(); private readonly Subject _joinRequestReceived = new(); - private readonly Subject _messageReceived = new(); + private readonly Subject _messageReceived = new(); private readonly Subject _objectBump = new(); private readonly Subject _objectChanged = new(); private readonly Subject _objectClicked = new(); @@ -83,7 +83,7 @@ public sealed partial class VirtualParadiseClient /// /// Occurs when a chat message or console message has been received. /// - public IObservable MessageReceived + public IObservable MessageReceived { get => _messageReceived; } diff --git a/VpSharp/src/VirtualParadiseClient.NativeEvents.cs b/VpSharp/src/VirtualParadiseClient.NativeEvents.cs index 2d38b13..863287c 100644 --- a/VpSharp/src/VirtualParadiseClient.NativeEvents.cs +++ b/VpSharp/src/VirtualParadiseClient.NativeEvents.cs @@ -52,7 +52,7 @@ public sealed partial class VirtualParadiseClient private void OnChatNativeEvent(nint sender) { - Message message; + IMessage message; lock (Lock) { @@ -61,6 +61,7 @@ public sealed partial class VirtualParadiseClient string content = vp_string(sender, StringAttribute.ChatMessage); int type = vp_int(sender, IntegerAttribute.ChatType); + IAvatar avatar = GetAvatar(session)!; Color color = Color.Black; var style = FontStyle.Regular; @@ -72,10 +73,12 @@ public sealed partial class VirtualParadiseClient int b = vp_int(sender, IntegerAttribute.ChatColorBlue); color = Color.FromArgb(r, g, b); style = (FontStyle)vp_int(sender, IntegerAttribute.ChatEffects); + message = new ConsoleMessage(avatar, name, content, color, style); + } + else + { + message = new UserMessage(avatar, content); } - - IAvatar avatar = GetAvatar(session)!; - message = new Message((MessageType)type, name, content, avatar, style, color); } _messageReceived.OnNext(message); @@ -332,7 +335,7 @@ public sealed partial class VirtualParadiseClient userId = vp_int(sender, IntegerAttribute.FriendUserId); } - User user = await GetUserAsync(userId).ConfigureAwait(false); + var user = (User)await GetUserAsync(userId).ConfigureAwait(false); _friends.AddOrUpdate(userId, user, (_, _) => user); } @@ -548,7 +551,7 @@ public sealed partial class VirtualParadiseClient name = vp_string(NativeInstanceHandle, StringAttribute.JoinName); } - User user = await GetUserAsync(userId).ConfigureAwait(false); + IUser user = await GetUserAsync(userId).ConfigureAwait(false); var joinRequest = new JoinRequest(this, requestId, name, user); _joinRequestReceived.OnNext(joinRequest); } @@ -582,7 +585,7 @@ public sealed partial class VirtualParadiseClient } World world = (await GetWorldAsync(worldName).ConfigureAwait(false))!; - User user = await GetUserAsync(userId).ConfigureAwait(false); + IUser user = await GetUserAsync(userId).ConfigureAwait(false); var location = new Location(world, position, rotation); var request = new InviteRequest(this, requestId, avatarName, user, location); diff --git a/VpSharp/src/VirtualParadiseClient.Users.cs b/VpSharp/src/VirtualParadiseClient.Users.cs index 1cf42eb..2fe64cd 100644 --- a/VpSharp/src/VirtualParadiseClient.Users.cs +++ b/VpSharp/src/VirtualParadiseClient.Users.cs @@ -16,7 +16,7 @@ public sealed partial class VirtualParadiseClient /// /// The user whose ID is equal to , or if no match was found. /// - public async Task GetUserAsync(int userId) + public async Task GetUserAsync(int userId) { if (_users.TryGetValue(userId, out User? user)) { diff --git a/VpSharp/src/VirtualParadiseClient.cs b/VpSharp/src/VirtualParadiseClient.cs index ceb8c1c..c32b22d 100644 --- a/VpSharp/src/VirtualParadiseClient.cs +++ b/VpSharp/src/VirtualParadiseClient.cs @@ -83,9 +83,9 @@ public sealed partial class VirtualParadiseClient : IDisposable /// Gets the current user to which this client is logged in. /// /// - /// An instance of , or if this client is not logged in. + /// An instance of , or if this client is not logged in. /// - public User? CurrentUser { get; internal set; } + public IUser? CurrentUser { get; internal set; } /// /// Gets the world to which this client is currently connected. @@ -565,7 +565,7 @@ public sealed partial class VirtualParadiseClient : IDisposable /// -or- /// is too long to send. /// - public Task SendMessageAsync(string message) + public Task SendMessageAsync(string message) { if (message is null) { @@ -593,14 +593,9 @@ public sealed partial class VirtualParadiseClient : IDisposable } } - IAvatar? avatar = CurrentAvatar; - return Task.FromResult(new Message( - MessageType.ChatMessage, - avatar!.Name, - message, - avatar, - FontStyle.Regular, - Color.Black + return Task.FromResult((IUserMessage)new UserMessage( + CurrentAvatar!, + message )); } @@ -620,7 +615,7 @@ public sealed partial class VirtualParadiseClient : IDisposable /// -or- /// is too long to send. /// - public Task SendMessageAsync(string message, FontStyle fontStyle, Color color) + public Task SendMessageAsync(string message, FontStyle fontStyle, Color color) { return SendMessageAsync(null, message, fontStyle, color); } @@ -642,7 +637,7 @@ public sealed partial class VirtualParadiseClient : IDisposable /// -or- /// is too long to send. /// - public Task SendMessageAsync(string? name, string message, FontStyle fontStyle, Color color) + public Task SendMessageAsync(string? name, string message, FontStyle fontStyle, Color color) { if (message is null) { @@ -680,13 +675,13 @@ public sealed partial class VirtualParadiseClient : IDisposable } } - return Task.FromResult(new Message( - MessageType.ConsoleMessage, - name, + IAvatar avatar = CurrentAvatar!; + return Task.FromResult((IConsoleMessage)new ConsoleMessage( + avatar, + avatar.Name, message, - CurrentAvatar!, - fontStyle, - color + color, + fontStyle )); }