diff --git a/VPLink.Common/Configuration/IBotConfiguration.cs b/VPLink.Common/Configuration/IBotConfiguration.cs
new file mode 100644
index 0000000..ecffb1e
--- /dev/null
+++ b/VPLink.Common/Configuration/IBotConfiguration.cs
@@ -0,0 +1,33 @@
+namespace VPLink.Common.Configuration;
+
+///
+/// Represents the bot configuration.
+///
+public interface IBotConfiguration
+{
+ ///
+ /// Gets a value indicating whether the bot should announce avatar events.
+ ///
+ ///
+ /// if the bot should announce avatar events; otherwise, .
+ ///
+ bool AnnounceAvatarEvents { get; }
+
+ ///
+ /// Gets a value indicating whether the bot should announce avatar events for bots.
+ ///
+ ///
+ /// if the bot should announce avatar events for bots; otherwise,
+ /// .
+ ///
+ bool AnnounceBots { get; }
+
+ ///
+ /// Gets a value indicating whether the bot should relay messages from other bots.
+ ///
+ ///
+ /// if the bot should relay messages from other bots; otherwise,
+ /// .
+ ///
+ bool RelayBotMessages { get; }
+}
diff --git a/VPLink.Common/Configuration/IChatConfiguration.cs b/VPLink.Common/Configuration/IChatConfiguration.cs
new file mode 100644
index 0000000..86351a5
--- /dev/null
+++ b/VPLink.Common/Configuration/IChatConfiguration.cs
@@ -0,0 +1,21 @@
+using VpSharp;
+
+namespace VPLink.Common.Configuration;
+
+///
+/// Represents the chat configuration.
+///
+public interface IChatConfiguration
+{
+ ///
+ /// Gets or sets the color of the message.
+ ///
+ /// The message color.
+ uint Color { get; set; }
+
+ ///
+ /// Gets or sets the font style of the message.
+ ///
+ /// The font style.
+ FontStyle Style { get; set; }
+}
diff --git a/VPLink.Common/Configuration/IDiscordConfiguration.cs b/VPLink.Common/Configuration/IDiscordConfiguration.cs
new file mode 100644
index 0000000..ae927b9
--- /dev/null
+++ b/VPLink.Common/Configuration/IDiscordConfiguration.cs
@@ -0,0 +1,19 @@
+namespace VPLink.Common.Configuration;
+
+///
+/// Represents the Discord configuration.
+///
+public interface IDiscordConfiguration
+{
+ ///
+ /// Gets the channel ID to which the bot should relay messages.
+ ///
+ /// The channel ID.
+ ulong ChannelId { get; }
+
+ ///
+ /// Gets the Discord token.
+ ///
+ /// The Discord token.
+ string Token { get; }
+}
diff --git a/VPLink.Common/Configuration/IVirtualParadiseConfiguration.cs b/VPLink.Common/Configuration/IVirtualParadiseConfiguration.cs
new file mode 100644
index 0000000..956cc68
--- /dev/null
+++ b/VPLink.Common/Configuration/IVirtualParadiseConfiguration.cs
@@ -0,0 +1,37 @@
+namespace VPLink.Common.Configuration;
+
+///
+/// Represents the Virtual Paradise configuration.
+///
+public interface IVirtualParadiseConfiguration
+{
+ ///
+ /// Gets or sets the display name of the bot.
+ ///
+ /// The display name.
+ string BotName { get; set; }
+
+ ///
+ /// Gets or sets the chat configuration.
+ ///
+ /// The chat configuration.
+ IChatConfiguration Chat { get; }
+
+ ///
+ /// Gets or sets the password with which to log in to Virtual Paradise.
+ ///
+ /// The login password.
+ string Password { get; set; }
+
+ ///
+ /// Gets or sets the username with which to log in to Virtual Paradise.
+ ///
+ /// The login username.
+ string Username { get; set; }
+
+ ///
+ /// Gets or sets the world into which the bot should enter.
+ ///
+ /// The world to enter.
+ string World { get; set; }
+}
diff --git a/VPLink/Data/RelayedMessage.cs b/VPLink.Common/Data/RelayedMessage.cs
similarity index 96%
rename from VPLink/Data/RelayedMessage.cs
rename to VPLink.Common/Data/RelayedMessage.cs
index 07b1469..b4f9886 100644
--- a/VPLink/Data/RelayedMessage.cs
+++ b/VPLink.Common/Data/RelayedMessage.cs
@@ -1,4 +1,4 @@
-namespace VPLink.Data;
+namespace VPLink.Common.Data;
///
/// Represents a message that is relayed between Discord and Virtual Paradise.
diff --git a/VPLink/Services/IAvatarService.cs b/VPLink.Common/Services/IAvatarService.cs
similarity index 96%
rename from VPLink/Services/IAvatarService.cs
rename to VPLink.Common/Services/IAvatarService.cs
index 0bee759..5317f4a 100644
--- a/VPLink/Services/IAvatarService.cs
+++ b/VPLink.Common/Services/IAvatarService.cs
@@ -1,6 +1,6 @@
using VpSharp.Entities;
-namespace VPLink.Services;
+namespace VPLink.Common.Services;
///
/// Represents a service that listens for, and triggers, avatar events.
diff --git a/VPLink/Services/IConfigurationService.cs b/VPLink.Common/Services/IConfigurationService.cs
similarity index 68%
rename from VPLink/Services/IConfigurationService.cs
rename to VPLink.Common/Services/IConfigurationService.cs
index c8d657e..cfefe26 100644
--- a/VPLink/Services/IConfigurationService.cs
+++ b/VPLink.Common/Services/IConfigurationService.cs
@@ -1,6 +1,6 @@
-using VPLink.Configuration;
+using VPLink.Common.Configuration;
-namespace VPLink.Services;
+namespace VPLink.Common.Services;
///
/// Represents the configuration service.
@@ -11,17 +11,17 @@ public interface IConfigurationService
/// Gets the bot configuration.
///
/// The bot configuration.
- BotConfiguration BotConfiguration { get; }
+ IBotConfiguration BotConfiguration { get; }
///
/// Gets the Discord configuration.
///
/// The Discord configuration.
- DiscordConfiguration DiscordConfiguration { get; }
+ IDiscordConfiguration DiscordConfiguration { get; }
///
/// Gets the Virtual Paradise configuration.
///
/// The Virtual Paradise configuration.
- VirtualParadiseConfiguration VirtualParadiseConfiguration { get; }
+ IVirtualParadiseConfiguration VirtualParadiseConfiguration { get; }
}
diff --git a/VPLink/Services/IDiscordMessageService.cs b/VPLink.Common/Services/IDiscordMessageService.cs
similarity index 94%
rename from VPLink/Services/IDiscordMessageService.cs
rename to VPLink.Common/Services/IDiscordMessageService.cs
index b338686..c9a5009 100644
--- a/VPLink/Services/IDiscordMessageService.cs
+++ b/VPLink.Common/Services/IDiscordMessageService.cs
@@ -1,7 +1,7 @@
-using VPLink.Data;
+using VPLink.Common.Data;
using VpSharp.Entities;
-namespace VPLink.Services;
+namespace VPLink.Common.Services;
///
/// Represents a service that listens for messages from the Discord bridge channel.
diff --git a/VPLink/Services/IRelayTarget.cs b/VPLink.Common/Services/IRelayTarget.cs
similarity index 87%
rename from VPLink/Services/IRelayTarget.cs
rename to VPLink.Common/Services/IRelayTarget.cs
index e5a6cd6..4fe6987 100644
--- a/VPLink/Services/IRelayTarget.cs
+++ b/VPLink.Common/Services/IRelayTarget.cs
@@ -1,6 +1,6 @@
-using VPLink.Data;
+using VPLink.Common.Data;
-namespace VPLink.Services;
+namespace VPLink.Common.Services;
///
/// Represents an object that can be used as a relay target.
diff --git a/VPLink/Services/IVirtualParadiseMessageService.cs b/VPLink.Common/Services/IVirtualParadiseMessageService.cs
similarity index 89%
rename from VPLink/Services/IVirtualParadiseMessageService.cs
rename to VPLink.Common/Services/IVirtualParadiseMessageService.cs
index a08ed6a..a6fc294 100644
--- a/VPLink/Services/IVirtualParadiseMessageService.cs
+++ b/VPLink.Common/Services/IVirtualParadiseMessageService.cs
@@ -1,6 +1,6 @@
-using VPLink.Data;
+using VPLink.Common.Data;
-namespace VPLink.Services;
+namespace VPLink.Common.Services;
///
/// Represents a service that listens for messages from the Virtual Paradise world.
diff --git a/VPLink.Common/VPLink.Common.csproj b/VPLink.Common/VPLink.Common.csproj
new file mode 100644
index 0000000..4c50db9
--- /dev/null
+++ b/VPLink.Common/VPLink.Common.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/VPLink.Tests/BotConfigurationTests.cs b/VPLink.Tests/BotConfigurationTests.cs
new file mode 100644
index 0000000..5239270
--- /dev/null
+++ b/VPLink.Tests/BotConfigurationTests.cs
@@ -0,0 +1,35 @@
+using NSubstitute;
+using NSubstitute.Extensions;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
+
+namespace VPLink.Tests;
+
+public class BotConfigurationTests
+{
+ private IConfigurationService _configurationService = null!;
+
+ [SetUp]
+ public void Setup()
+ {
+ var configuration = Substitute.For();
+ configuration.AnnounceAvatarEvents.Returns(true);
+ configuration.AnnounceBots.Returns(false);
+ configuration.RelayBotMessages.Returns(false);
+
+ _configurationService = Substitute.For();
+ _configurationService.Configure().BotConfiguration.Returns(configuration);
+ }
+
+ [Test]
+ public void BotConfiguration_ShouldReturnCorrectValues_GivenDefaultConfig()
+ {
+ IBotConfiguration configuration = _configurationService.BotConfiguration;
+ Assert.Multiple(() =>
+ {
+ Assert.That(configuration.AnnounceAvatarEvents, Is.True);
+ Assert.That(configuration.AnnounceBots, Is.False);
+ Assert.That(configuration.RelayBotMessages, Is.False);
+ });
+ }
+}
diff --git a/VPLink.Tests/DiscordConfigurationTests.cs b/VPLink.Tests/DiscordConfigurationTests.cs
new file mode 100644
index 0000000..50bfefe
--- /dev/null
+++ b/VPLink.Tests/DiscordConfigurationTests.cs
@@ -0,0 +1,33 @@
+using NSubstitute;
+using NSubstitute.Extensions;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
+
+namespace VPLink.Tests;
+
+public class DiscordConfigurationTests
+{
+ private IConfigurationService _configurationService = null!;
+
+ [SetUp]
+ public void Setup()
+ {
+ var configuration = Substitute.For();
+ configuration.Token.Returns("DISCORD_TOKEN");
+ configuration.ChannelId.Returns(1234567890UL);
+
+ _configurationService = Substitute.For();
+ _configurationService.Configure().DiscordConfiguration.Returns(configuration);
+ }
+
+ [Test]
+ public void DiscordConfiguration_ShouldReturnCorrectValues_GivenDefaultConfig()
+ {
+ IDiscordConfiguration configuration = _configurationService.DiscordConfiguration;
+ Assert.Multiple(() =>
+ {
+ Assert.That(configuration.Token, Is.EqualTo("DISCORD_TOKEN"));
+ Assert.That(configuration.ChannelId, Is.EqualTo(1234567890UL));
+ });
+ }
+}
diff --git a/VPLink.Tests/GlobalUsings.cs b/VPLink.Tests/GlobalUsings.cs
new file mode 100644
index 0000000..3244567
--- /dev/null
+++ b/VPLink.Tests/GlobalUsings.cs
@@ -0,0 +1 @@
+global using NUnit.Framework;
diff --git a/VPLink.Tests/RelayTests.cs b/VPLink.Tests/RelayTests.cs
new file mode 100644
index 0000000..68a3ee1
--- /dev/null
+++ b/VPLink.Tests/RelayTests.cs
@@ -0,0 +1,64 @@
+using System.Reactive.Linq;
+using System.Reactive.Subjects;
+using NSubstitute;
+using NSubstitute.Extensions;
+using VPLink.Common.Data;
+using VPLink.Common.Services;
+using VpSharp.Extensions;
+
+namespace VPLink.Tests;
+
+public class RelayTests
+{
+ private readonly Subject _vpMessageReceived = new();
+ private readonly Subject _discordMessageReceived = new();
+ private IVirtualParadiseMessageService _vpMessageService = null!;
+ private IDiscordMessageService _discordMessageService = null!;
+
+ [SetUp]
+ public void Setup()
+ {
+ _discordMessageService = Substitute.For();
+ _discordMessageService.Configure().SendMessageAsync(Arg.Any()).Returns(Task.CompletedTask);
+
+ _vpMessageService = Substitute.For();
+ _vpMessageService.Configure().OnMessageReceived.Returns(_vpMessageReceived.AsObservable());
+
+ _discordMessageService = Substitute.For();
+ _discordMessageService.Configure().OnMessageReceived.Returns(_discordMessageReceived.AsObservable());
+
+ _discordMessageReceived.SubscribeAsync(_vpMessageService.SendMessageAsync);
+ _vpMessageReceived.SubscribeAsync(_discordMessageService.SendMessageAsync);
+ }
+
+ [Test]
+ public void VirtualParadiseMessage_ShouldRelay_ToDiscordService()
+ {
+ var observer = Substitute.For>();
+ _vpMessageReceived.Subscribe(observer);
+
+ const string author = "Admin";
+ const string message = "Hello, world!";
+
+ _vpMessageReceived.OnNext(new RelayedMessage(author, message));
+
+ observer.Received(1).OnNext(Arg.Is(m => m.Author == author && m.Content == message));
+ _discordMessageService.Received(1)
+ .SendMessageAsync(Arg.Is(m => m.Author == author && m.Content == message));
+ }
+
+ [Test]
+ public void DiscordMessage_ShouldRelay_ToVirtualParadiseService()
+ {
+ var observer = Substitute.For>();
+ _discordMessageReceived.Subscribe(observer);
+
+ const string author = "Admin";
+ const string message = "Hello, world!";
+
+ _discordMessageReceived.OnNext(new RelayedMessage(author, message));
+
+ observer.Received(1).OnNext(Arg.Is(m => m.Author == author && m.Content == message));
+ _vpMessageService.Received(1).SendMessageAsync(Arg.Is(m => m.Author == author && m.Content == message));
+ }
+}
diff --git a/VPLink.Tests/VPLink.Tests.csproj b/VPLink.Tests/VPLink.Tests.csproj
new file mode 100644
index 0000000..fd7977f
--- /dev/null
+++ b/VPLink.Tests/VPLink.Tests.csproj
@@ -0,0 +1,25 @@
+
+
+
+ net7.0
+ enable
+ enable
+
+ false
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/VPLink.Tests/VirtualParadiseConfigurationTests.cs b/VPLink.Tests/VirtualParadiseConfigurationTests.cs
new file mode 100644
index 0000000..c24f280
--- /dev/null
+++ b/VPLink.Tests/VirtualParadiseConfigurationTests.cs
@@ -0,0 +1,37 @@
+using NSubstitute;
+using NSubstitute.Extensions;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
+
+namespace VPLink.Tests;
+
+public class VirtualParadiseConfigurationTests
+{
+ private IConfigurationService _configurationService = null!;
+
+ [SetUp]
+ public void Setup()
+ {
+ var configuration = Substitute.For();
+ configuration.Username.Returns("Admin");
+ configuration.Password.Returns("Password1234");
+ configuration.World.Returns("Blizzard");
+ configuration.BotName.Returns("VPLink");
+
+ _configurationService = Substitute.For();
+ _configurationService.Configure().VirtualParadiseConfiguration.Returns(configuration);
+ }
+
+ [Test]
+ public void DiscordConfiguration_ShouldReturnCorrectValues_GivenDefaultConfig()
+ {
+ IVirtualParadiseConfiguration configuration = _configurationService.VirtualParadiseConfiguration;
+ Assert.Multiple(() =>
+ {
+ Assert.That(configuration.Username, Is.EqualTo("Admin"));
+ Assert.That(configuration.Password, Is.EqualTo("Password1234"));
+ Assert.That(configuration.World, Is.EqualTo("Blizzard"));
+ Assert.That(configuration.BotName, Is.EqualTo("VPLink"));
+ });
+ }
+}
diff --git a/VPLink.sln b/VPLink.sln
index 104038c..5152bbb 100644
--- a/VPLink.sln
+++ b/VPLink.sln
@@ -19,6 +19,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Workflows", "Workflows", "{
.github\workflows\release.yml = .github\workflows\release.yml
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VPLink.Tests", "VPLink.Tests\VPLink.Tests.csproj", "{17F63B22-1E27-4438-8C76-7E89706713E8}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VPLink.Common", "VPLink.Common\VPLink.Common.csproj", "{F1CE3BA6-05AC-47F3-BB7E-C489DC132367}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -29,5 +33,13 @@ Global
{CD488A1E-0232-4EB5-A381-38A42B267B11}.Debug|Any CPU.Build.0 = Debug|Any CPU
{CD488A1E-0232-4EB5-A381-38A42B267B11}.Release|Any CPU.ActiveCfg = Release|Any CPU
{CD488A1E-0232-4EB5-A381-38A42B267B11}.Release|Any CPU.Build.0 = Release|Any CPU
+ {17F63B22-1E27-4438-8C76-7E89706713E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {17F63B22-1E27-4438-8C76-7E89706713E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {17F63B22-1E27-4438-8C76-7E89706713E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {17F63B22-1E27-4438-8C76-7E89706713E8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F1CE3BA6-05AC-47F3-BB7E-C489DC132367}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F1CE3BA6-05AC-47F3-BB7E-C489DC132367}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F1CE3BA6-05AC-47F3-BB7E-C489DC132367}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F1CE3BA6-05AC-47F3-BB7E-C489DC132367}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
EndGlobal
diff --git a/VPLink/Configuration/BotConfiguration.cs b/VPLink/Configuration/BotConfiguration.cs
index c1b92e5..cd19664 100644
--- a/VPLink/Configuration/BotConfiguration.cs
+++ b/VPLink/Configuration/BotConfiguration.cs
@@ -1,33 +1,16 @@
+using VPLink.Common.Configuration;
+
namespace VPLink.Configuration;
-///
-/// Represents the bot configuration.
-///
-public sealed class BotConfiguration
+///
+internal sealed class BotConfiguration : IBotConfiguration
{
- ///
- /// Gets or sets a value indicating whether the bot should announce avatar events.
- ///
- ///
- /// if the bot should announce avatar events; otherwise, .
- ///
+ ///
public bool AnnounceAvatarEvents { get; set; } = true;
- ///
- /// Gets or sets a value indicating whether the bot should announce avatar events for bots.
- ///
- ///
- /// if the bot should announce avatar events for bots; otherwise,
- /// .
- ///
+ ///
public bool AnnounceBots { get; set; } = false;
- ///
- /// Gets or sets a value indicating whether the bot should relay messages from other bots.
- ///
- ///
- /// if the bot should relay messages from other bots; otherwise,
- /// .
- ///
+ ///
public bool RelayBotMessages { get; set; } = false;
}
diff --git a/VPLink/Configuration/ChatConfiguration.cs b/VPLink/Configuration/ChatConfiguration.cs
index dd99157..7fe03cb 100644
--- a/VPLink/Configuration/ChatConfiguration.cs
+++ b/VPLink/Configuration/ChatConfiguration.cs
@@ -1,21 +1,14 @@
+using VPLink.Common.Configuration;
using VpSharp;
namespace VPLink.Configuration;
-///
-/// Represents the chat configuration.
-///
-public sealed class ChatConfiguration
+///
+internal sealed class ChatConfiguration : IChatConfiguration
{
- ///
- /// Gets or sets the color of the message.
- ///
- /// The message color.
+ ///
public uint Color { get; set; } = 0x191970;
- ///
- /// Gets or sets the font style of the message.
- ///
- /// The font style.
+ ///
public FontStyle Style { get; set; } = FontStyle.Regular;
}
diff --git a/VPLink/Configuration/DiscordConfiguration.cs b/VPLink/Configuration/DiscordConfiguration.cs
index e9b473a..a1aae0e 100644
--- a/VPLink/Configuration/DiscordConfiguration.cs
+++ b/VPLink/Configuration/DiscordConfiguration.cs
@@ -1,19 +1,13 @@
+using VPLink.Common.Configuration;
+
namespace VPLink.Configuration;
-///
-/// Represents the Discord configuration.
-///
-public sealed class DiscordConfiguration
+///
+internal sealed class DiscordConfiguration : IDiscordConfiguration
{
- ///
- /// Gets or sets the channel ID to which the bot should relay messages.
- ///
- /// The channel ID.
+ ///
public ulong ChannelId { get; set; }
- ///
- /// Gets or sets the Discord token.
- ///
- /// The Discord token.
+ ///
public string Token { get; set; } = string.Empty;
}
diff --git a/VPLink/Configuration/VirtualParadiseConfiguration.cs b/VPLink/Configuration/VirtualParadiseConfiguration.cs
index 53b8f09..b77774a 100644
--- a/VPLink/Configuration/VirtualParadiseConfiguration.cs
+++ b/VPLink/Configuration/VirtualParadiseConfiguration.cs
@@ -1,37 +1,22 @@
+using VPLink.Common.Configuration;
+
namespace VPLink.Configuration;
-///
-/// Represents the Virtual Paradise configuration.
-///
-public sealed class VirtualParadiseConfiguration
+///
+internal sealed class VirtualParadiseConfiguration : IVirtualParadiseConfiguration
{
- ///
- /// Gets or sets the display name of the bot.
- ///
- /// The display name.
+ ///
public string BotName { get; set; } = "VPLink";
- ///
- /// Gets or sets the chat configuration.
- ///
- /// The chat configuration.
- public ChatConfiguration Chat { get; } = new();
+ ///
+ public IChatConfiguration Chat { get; } = new ChatConfiguration();
- ///
- /// Gets or sets the password with which to log in to Virtual Paradise.
- ///
- /// The login password.
+ ///
public string Password { get; set; } = string.Empty;
- ///
- /// Gets or sets the username with which to log in to Virtual Paradise.
- ///
- /// The login username.
+ ///
public string Username { get; set; } = string.Empty;
- ///
- /// Gets or sets the world into which the bot should enter.
- ///
- /// The world to enter.
+ ///
public string World { get; set; } = string.Empty;
}
diff --git a/VPLink/Program.cs b/VPLink/Program.cs
index 48613e0..2cb9a15 100644
--- a/VPLink/Program.cs
+++ b/VPLink/Program.cs
@@ -6,6 +6,7 @@ using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Tomlyn.Extensions.Configuration;
+using VPLink.Common.Services;
using VPLink.Services;
using VpSharp;
using X10D.Hosting.DependencyInjection;
diff --git a/VPLink/Services/AvatarService.cs b/VPLink/Services/AvatarService.cs
index 15c74d1..f2d5a80 100644
--- a/VPLink/Services/AvatarService.cs
+++ b/VPLink/Services/AvatarService.cs
@@ -2,7 +2,8 @@ using System.Reactive.Linq;
using System.Reactive.Subjects;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-using VPLink.Configuration;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
using VpSharp;
using VpSharp.Entities;
@@ -50,7 +51,7 @@ internal sealed class AvatarService : BackgroundService, IAvatarService
{
_logger.LogInformation("{Avatar} joined", avatar);
- BotConfiguration configuration = _configurationService.BotConfiguration;
+ IBotConfiguration configuration = _configurationService.BotConfiguration;
if (!configuration.AnnounceAvatarEvents || avatar.IsBot && !configuration.AnnounceBots)
return;
@@ -61,7 +62,7 @@ internal sealed class AvatarService : BackgroundService, IAvatarService
{
_logger.LogInformation("{Avatar} left", avatar);
- BotConfiguration configuration = _configurationService.BotConfiguration;
+ IBotConfiguration configuration = _configurationService.BotConfiguration;
if (!configuration.AnnounceAvatarEvents || avatar.IsBot && !configuration.AnnounceBots)
return;
diff --git a/VPLink/Services/ConfigurationService.cs b/VPLink/Services/ConfigurationService.cs
index 1ce3939..3b915a1 100644
--- a/VPLink/Services/ConfigurationService.cs
+++ b/VPLink/Services/ConfigurationService.cs
@@ -1,4 +1,6 @@
using Microsoft.Extensions.Configuration;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
using VPLink.Configuration;
namespace VPLink.Services;
@@ -18,19 +20,19 @@ internal sealed class ConfigurationService : IConfigurationService
}
///
- public BotConfiguration BotConfiguration
+ public IBotConfiguration BotConfiguration
{
get => _configuration.GetSection("Bot").Get() ?? new BotConfiguration();
}
///
- public DiscordConfiguration DiscordConfiguration
+ public IDiscordConfiguration DiscordConfiguration
{
get => _configuration.GetSection("Discord").Get() ?? new DiscordConfiguration();
}
///
- public VirtualParadiseConfiguration VirtualParadiseConfiguration
+ public IVirtualParadiseConfiguration VirtualParadiseConfiguration
{
get => _configuration.GetSection("VirtualParadise").Get() ??
new VirtualParadiseConfiguration();
diff --git a/VPLink/Services/DiscordMessageService.cs b/VPLink/Services/DiscordMessageService.cs
index c4f344a..d50bd8e 100644
--- a/VPLink/Services/DiscordMessageService.cs
+++ b/VPLink/Services/DiscordMessageService.cs
@@ -8,9 +8,11 @@ using Discord;
using Discord.WebSocket;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-using VPLink.Configuration;
-using VPLink.Data;
+using VPLink.Common.Configuration;
+using VPLink.Common.Data;
+using VPLink.Common.Services;
using VpSharp.Entities;
+using IUser = Discord.IUser;
namespace VPLink.Services;
@@ -144,7 +146,7 @@ internal sealed partial class DiscordMessageService : BackgroundService, IDiscor
private bool TryGetRelayChannel([NotNullWhen(true)] out ITextChannel? channel)
{
- DiscordConfiguration configuration = _configurationService.DiscordConfiguration;
+ IDiscordConfiguration configuration = _configurationService.DiscordConfiguration;
ulong channelId = configuration.ChannelId;
if (_discordClient.GetChannel(channelId) is ITextChannel textChannel)
diff --git a/VPLink/Services/DiscordService.cs b/VPLink/Services/DiscordService.cs
index e01f909..530bf02 100644
--- a/VPLink/Services/DiscordService.cs
+++ b/VPLink/Services/DiscordService.cs
@@ -4,7 +4,8 @@ using Discord.WebSocket;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using VPLink.Commands;
-using VPLink.Configuration;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
namespace VPLink.Services;
@@ -48,7 +49,7 @@ internal sealed class DiscordService : BackgroundService
_discordClient.Ready += OnReady;
_discordClient.InteractionCreated += OnInteractionCreated;
- DiscordConfiguration configuration = _configurationService.DiscordConfiguration;
+ IDiscordConfiguration configuration = _configurationService.DiscordConfiguration;
string token = configuration.Token ?? throw new InvalidOperationException("Token is not set.");
_logger.LogDebug("Connecting to Discord");
diff --git a/VPLink/Services/RelayService.cs b/VPLink/Services/RelayService.cs
index 791e640..dd7087c 100644
--- a/VPLink/Services/RelayService.cs
+++ b/VPLink/Services/RelayService.cs
@@ -1,5 +1,6 @@
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using VPLink.Common.Services;
using VpSharp.Extensions;
namespace VPLink.Services;
diff --git a/VPLink/Services/VirtualParadiseMessageService.cs b/VPLink/Services/VirtualParadiseMessageService.cs
index cec294f..be7c784 100644
--- a/VPLink/Services/VirtualParadiseMessageService.cs
+++ b/VPLink/Services/VirtualParadiseMessageService.cs
@@ -3,15 +3,16 @@ using System.Reactive.Linq;
using System.Reactive.Subjects;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
-using VPLink.Configuration;
-using VPLink.Data;
+using VPLink.Common.Configuration;
+using VPLink.Common.Data;
+using VPLink.Common.Services;
using VpSharp;
using VpSharp.Entities;
using FontStyle = VpSharp.FontStyle;
namespace VPLink.Services;
-///
+///
internal sealed class VirtualParadiseMessageService : BackgroundService, IVirtualParadiseMessageService
{
private readonly ILogger _logger;
@@ -40,7 +41,7 @@ internal sealed class VirtualParadiseMessageService : BackgroundService, IVirtua
///
public Task SendMessageAsync(RelayedMessage message)
{
- ChatConfiguration configuration = _configurationService.VirtualParadiseConfiguration.Chat;
+ IChatConfiguration configuration = _configurationService.VirtualParadiseConfiguration.Chat;
Color color = Color.FromArgb((int)configuration.Color);
FontStyle style = configuration.Style;
diff --git a/VPLink/Services/VirtualParadiseService.cs b/VPLink/Services/VirtualParadiseService.cs
index dc15115..5036d9e 100644
--- a/VPLink/Services/VirtualParadiseService.cs
+++ b/VPLink/Services/VirtualParadiseService.cs
@@ -1,9 +1,10 @@
using System.Reactive.Subjects;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
+using VPLink.Common.Configuration;
+using VPLink.Common.Services;
using VpSharp;
using VpSharp.Entities;
-using VirtualParadiseConfiguration = VPLink.Configuration.VirtualParadiseConfiguration;
namespace VPLink.Services;
@@ -35,7 +36,7 @@ internal sealed class VirtualParadiseService : BackgroundService
_logger.LogInformation("Establishing relay");
_virtualParadiseClient.MessageReceived.Subscribe(_messageReceived);
- VirtualParadiseConfiguration configuration = _configurationService.VirtualParadiseConfiguration;
+ IVirtualParadiseConfiguration configuration = _configurationService.VirtualParadiseConfiguration;
string username = configuration.Username ?? throw new InvalidOperationException("Username is not set.");
string password = configuration.Password ?? throw new InvalidOperationException("Password is not set.");
diff --git a/VPLink/VPLink.csproj b/VPLink/VPLink.csproj
index 78f73df..7b45bd8 100644
--- a/VPLink/VPLink.csproj
+++ b/VPLink/VPLink.csproj
@@ -55,4 +55,8 @@
+
+
+
+