Skip to content

Commit

Permalink
Add DSharpPlus.Nightly sample bot
Browse files Browse the repository at this point in the history
  • Loading branch information
NycroV committed Aug 14, 2024
1 parent 1467e7e commit 598262d
Show file tree
Hide file tree
Showing 4 changed files with 203 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="DSharpPlus.Commands" Version="5.0.0-nightly-02355" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.Logging.Console" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Lavalink4NET.DSharpPlus.Nightly\Lavalink4NET.DSharpPlus.Nightly.csproj" />
</ItemGroup>

</Project>
121 changes: 121 additions & 0 deletions samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/MusicCommands.cs
Original file line number Diff line number Diff line change
@@ -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<QueuedLavalinkPlayer?> 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;
}
}
54 changes: 54 additions & 0 deletions samples/Lavalink4NET.DSharpPlus.Nightly.ExampleBot/Program.cs
Original file line number Diff line number Diff line change
@@ -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<ApplicationHost>();


// 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);
}
}
7 changes: 7 additions & 0 deletions src/Lavalink4NET.sln
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down

0 comments on commit 598262d

Please sign in to comment.