From 598262d9528a4f49d47dc31154e5c703bf9360e2 Mon Sep 17 00:00:00 2001
From: NycroV <83246959+NycroV@users.noreply.github.com>
Date: Wed, 14 Aug 2024 06:54:37 -0400
Subject: [PATCH] Add DSharpPlus.Nightly sample bot
---
...k4NET.DSharpPlus.Nightly.ExampleBot.csproj | 21 +++
.../MusicCommands.cs | 121 ++++++++++++++++++
.../Program.cs | 54 ++++++++
src/Lavalink4NET.sln | 7 +
4 files changed, 203 insertions(+)
create mode 100644 samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Lavalink4NET.DSharpPlus.Nightly.ExampleBot.csproj
create mode 100644 samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/MusicCommands.cs
create mode 100644 samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Program.cs
diff --git a/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Lavalink4NET.DSharpPlus.Nightly.ExampleBot.csproj b/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Lavalink4NET.DSharpPlus.Nightly.ExampleBot.csproj
new file mode 100644
index 00000000..6a339b33
--- /dev/null
+++ b/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Lavalink4NET.DSharpPlus.Nightly.ExampleBot.csproj
@@ -0,0 +1,21 @@
+
+
+
+ Exe
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/MusicCommands.cs b/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/MusicCommands.cs
new file mode 100644
index 00000000..ac31b92a
--- /dev/null
+++ b/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/MusicCommands.cs
@@ -0,0 +1,121 @@
+namespace ExampleBot;
+
+using System;
+using System.Threading.Tasks;
+using DSharpPlus.Entities;
+using DSharpPlus.Commands;
+using Lavalink4NET;
+using Lavalink4NET.Players;
+using Lavalink4NET.Players.Queued;
+using Lavalink4NET.Rest.Entities.Tracks;
+using Microsoft.Extensions.Options;
+using System.ComponentModel;
+using DSharpPlus.Commands.ContextChecks;
+
+public class MusicCommands
+{
+ private readonly IAudioService _audioService;
+
+ public MusicCommands(IAudioService audioService)
+ {
+ ArgumentNullException.ThrowIfNull(audioService);
+ _audioService = audioService;
+ }
+
+ [Command("play")]
+ [Description("Plays music")]
+ [DirectMessageUsage(DirectMessageUsage.DenyDMs)]
+ public async Task Play(CommandContext context,
+
+ [Parameter("query")]
+ [Description("Track to play")]
+ string query)
+ {
+ // This operation could take a while - deferring the interaction lets Discord know we've
+ // received it and lets us update it later. Users see a "thinking..." state.
+ await context.DeferResponseAsync().ConfigureAwait(false);
+
+ // Attempt to get the player
+ var player = await GetPlayerAsync(context, connectToVoiceChannel: true).ConfigureAwait(false);
+
+ // If something went wrong getting the player, don't attempt to play any tracks
+ if (player is null)
+ return;
+
+ // Fetch the tracks
+ var track = await _audioService.Tracks
+ .LoadTrackAsync(query, TrackSearchMode.YouTube)
+ .ConfigureAwait(false);
+
+ // If no results were found
+ if (track is null)
+ {
+ var errorResponse = new DiscordFollowupMessageBuilder()
+ .WithContent("😖 No results.")
+ .AsEphemeral();
+
+ await context
+ .EditResponseAsync(errorResponse)
+ .ConfigureAwait(false);
+
+ return;
+ }
+
+ // Play the track
+ var position = await player
+ .PlayAsync(track)
+ .ConfigureAwait(false);
+
+ // If it was added to the queue
+ if (position is 0)
+ {
+ await context
+ .FollowupAsync(new DiscordFollowupMessageBuilder().WithContent($"🔈 Playing: {track.Uri}"))
+ .ConfigureAwait(false);
+ }
+
+ // If it was played directly
+ else
+ {
+ await context
+ .FollowupAsync(new DiscordFollowupMessageBuilder().WithContent($"🔈 Added to queue: {track.Uri}"))
+ .ConfigureAwait(false);
+ }
+ }
+
+ private async ValueTask GetPlayerAsync(CommandContext commandContext, bool connectToVoiceChannel = true)
+ {
+ ArgumentNullException.ThrowIfNull(commandContext);
+
+ var retrieveOptions = new PlayerRetrieveOptions(
+ ChannelBehavior: connectToVoiceChannel ? PlayerChannelBehavior.Join : PlayerChannelBehavior.None);
+
+ var playerOptions = new QueuedLavalinkPlayerOptions { HistoryCapacity = 10000 };
+
+ var result = await _audioService.Players
+ .RetrieveAsync(commandContext.Guild!.Id, commandContext.Member?.VoiceState?.Channel?.Id ?? null, playerFactory: PlayerFactory.Queued, Options.Create(playerOptions), retrieveOptions)
+ .ConfigureAwait(false);
+
+ if (!result.IsSuccess)
+ {
+ var errorMessage = result.Status switch
+ {
+ PlayerRetrieveStatus.UserNotInVoiceChannel => "You are not connected to a voice channel.",
+ PlayerRetrieveStatus.BotNotConnected => "The bot is currently not connected.",
+ _ => "Unknown error.",
+ };
+
+ var errorResponse = new DiscordFollowupMessageBuilder()
+ .WithContent(errorMessage)
+ .AsEphemeral();
+
+ await commandContext
+ .FollowupAsync(errorResponse)
+ .ConfigureAwait(false);
+
+ return null;
+ }
+
+ return result.Player;
+ }
+}
\ No newline at end of file
diff --git a/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Program.cs b/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Program.cs
new file mode 100644
index 00000000..42c6b8ec
--- /dev/null
+++ b/samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Program.cs
@@ -0,0 +1,54 @@
+using DSharpPlus;
+using DSharpPlus.Commands;
+using DSharpPlus.Extensions;
+using ExampleBot;
+using Lavalink4NET.Extensions;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Hosting;
+using Microsoft.Extensions.Logging;
+
+var builder = new HostApplicationBuilder(args);
+
+// Your host service
+builder.Services.AddHostedService();
+
+
+// DSharpPlus
+builder.Services.AddDiscordClient("Your token here", DiscordIntents.AllUnprivileged);
+builder.Services.AddCommandsExtension(extension => extension.AddCommands(typeof(MusicCommands).Assembly));
+
+
+// Lavalink4NET
+builder.Services.AddLavalink();
+
+
+// Logging
+builder.Services.AddLogging(s => s.AddConsole().SetMinimumLevel(LogLevel.Debug));
+
+
+// Start the host
+builder.Build().Run();
+
+
+file sealed class ApplicationHost : BackgroundService
+{
+ private readonly DiscordClient _discordClient;
+
+ public ApplicationHost(DiscordClient discordClient)
+ {
+ ArgumentNullException.ThrowIfNull(discordClient);
+ _discordClient = discordClient;
+ }
+
+ protected override async Task ExecuteAsync(CancellationToken stoppingToken)
+ {
+ // Connect to discord gateway and initialize node connection
+ await _discordClient
+ .ConnectAsync()
+ .ConfigureAwait(false);
+
+ await Task
+ .Delay(-1, stoppingToken)
+ .ConfigureAwait(false);
+ }
+}
\ No newline at end of file
diff --git a/src/Lavalink4NET.sln b/src/Lavalink4NET.sln
index 035963e4..191bea52 100644
--- a/src/Lavalink4NET.sln
+++ b/src/Lavalink4NET.sln
@@ -98,6 +98,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lavalink4NET.Integrations.L
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Lavalink4NET.DSharpPlus.Nightly", "Lavalink4NET.DSharpPlus.Nightly\Lavalink4NET.DSharpPlus.Nightly.csproj", "{1A30629A-399B-4293-B5F4-B3909C1772D0}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Lavalink4NET.DSharpPlus.Nightly.ExampleBot", "..\samples\Lavalink4NET.DSharpPlus.Nightly.ExampleBot\Lavalink4NET.DSharpPlus.Nightly.ExampleBot.csproj", "{E4390813-D7C6-4FF8-BF3E-B4504696CAF6}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -264,6 +266,10 @@ Global
{1A30629A-399B-4293-B5F4-B3909C1772D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1A30629A-399B-4293-B5F4-B3909C1772D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1A30629A-399B-4293-B5F4-B3909C1772D0}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4390813-D7C6-4FF8-BF3E-B4504696CAF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4390813-D7C6-4FF8-BF3E-B4504696CAF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4390813-D7C6-4FF8-BF3E-B4504696CAF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4390813-D7C6-4FF8-BF3E-B4504696CAF6}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -293,6 +299,7 @@ Global
{9A30E985-6D67-41D4-A12F-F1ADCD2ED0FE} = {48ECDC71-B9E3-4086-8194-DA81B4667CA6}
{176B0345-DF57-42B4-A8FD-4E6436D9554C} = {48ECDC71-B9E3-4086-8194-DA81B4667CA6}
{1A30629A-399B-4293-B5F4-B3909C1772D0} = {5FAEC63E-9752-48C4-8BC9-B101E0DBDBD3}
+ {E4390813-D7C6-4FF8-BF3E-B4504696CAF6} = {B9402D29-5B12-4672-97B8-570A60C0F878}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {466A619D-5C4B-4A8F-9852-7A5322F160A2}