-
-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'dev' of https://github.com/angelobreuer/Lavalink4NET in…
…to dev
- Loading branch information
Showing
14 changed files
with
871 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
23 changes: 23 additions & 0 deletions
23
samples/Lavalink4NET.Samples.NetCord/Lavalink4NET.Samples.NetCord.csproj
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Exe</OutputType> | ||
<TargetFramework>net8.0</TargetFramework> | ||
<ImplicitUsings>enable</ImplicitUsings> | ||
<Nullable>enable</Nullable> | ||
<RootNamespace>ExampleBot</RootNamespace> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="Microsoft.Extensions.Hosting" Version="7.0.1" /> | ||
<PackageReference Include="NetCord" Version="1.0.0-alpha.270" /> | ||
<PackageReference Include="NetCord.Hosting" Version="1.0.0-alpha.40" /> | ||
<PackageReference Include="NetCord.Hosting.Services" Version="1.0.0-alpha.49" /> | ||
<PackageReference Include="NetCord.Services" Version="1.0.0-alpha.171" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\..\src\Lavalink4NET.NetCord\Lavalink4NET.NetCord.csproj" /> | ||
</ItemGroup> | ||
|
||
</Project> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
namespace ExampleBot; | ||
|
||
using Lavalink4NET; | ||
using Lavalink4NET.NetCord; | ||
using Lavalink4NET.Players; | ||
using Lavalink4NET.Rest.Entities.Tracks; | ||
using NetCord.Services.ApplicationCommands; | ||
|
||
public class MusicModule(IAudioService audioService) : ApplicationCommandModule<SlashCommandContext> | ||
{ | ||
[SlashCommand("play", "Plays a track!")] | ||
public async Task<string> PlayAsync([SlashCommandParameter(Name = "query", Description = "The query to search for")] string query) | ||
{ | ||
var retrieveOptions = new PlayerRetrieveOptions(ChannelBehavior: PlayerChannelBehavior.Join); | ||
|
||
var result = await audioService.Players | ||
.RetrieveAsync(Context, playerFactory: PlayerFactory.Queued, retrieveOptions); | ||
|
||
if (!result.IsSuccess) | ||
{ | ||
return GetErrorMessage(result.Status); | ||
} | ||
|
||
var player = result.Player; | ||
|
||
var track = await audioService.Tracks | ||
.LoadTrackAsync(query, TrackSearchMode.YouTube); | ||
|
||
if (track is null) | ||
{ | ||
return "No tracks found."; | ||
} | ||
|
||
await player.PlayAsync(track); | ||
|
||
return $"Now playing: {track.Title}"; | ||
} | ||
|
||
private static string GetErrorMessage(PlayerRetrieveStatus retrieveStatus) => retrieveStatus switch | ||
{ | ||
PlayerRetrieveStatus.UserNotInVoiceChannel => "You are not connected to a voice channel.", | ||
PlayerRetrieveStatus.BotNotConnected => "The bot is currently not connected.", | ||
_ => "Unknown error.", | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
using Lavalink4NET.NetCord; | ||
using Microsoft.Extensions.Hosting; | ||
using NetCord; | ||
using NetCord.Hosting.Gateway; | ||
using NetCord.Hosting.Services; | ||
using NetCord.Hosting.Services.ApplicationCommands; | ||
using NetCord.Services.ApplicationCommands; | ||
|
||
var builder = Host.CreateDefaultBuilder(args) | ||
.UseDiscordGateway() | ||
.UseLavalink() | ||
.UseApplicationCommands<SlashCommandInteraction, SlashCommandContext>(); | ||
|
||
var host = builder.Build() | ||
.AddModules(typeof(Program).Assembly) | ||
.UseGatewayEventHandlers(); | ||
|
||
host.Run(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
namespace Lavalink4NET.NetCord; | ||
|
||
using System; | ||
using System.Collections.Immutable; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using global::NetCord.Gateway; | ||
using Lavalink4NET.Clients; | ||
using Lavalink4NET.Clients.Events; | ||
using Lavalink4NET.Events; | ||
|
||
public sealed class DiscordClientWrapper : IDiscordClientWrapper | ||
{ | ||
private readonly IDiscordClientWrapper _client; | ||
|
||
public DiscordClientWrapper(GatewayClient client) | ||
{ | ||
ArgumentNullException.ThrowIfNull(client); | ||
|
||
_client = new GatewayClientWrapper(client); | ||
} | ||
|
||
public DiscordClientWrapper(ShardedGatewayClient client) | ||
{ | ||
ArgumentNullException.ThrowIfNull(client); | ||
|
||
_client = new ShardedGatewayClientWrapper(client); | ||
} | ||
|
||
public event AsyncEventHandler<VoiceServerUpdatedEventArgs>? VoiceServerUpdated | ||
{ | ||
add => _client.VoiceServerUpdated += value; | ||
remove => _client.VoiceServerUpdated -= value; | ||
} | ||
|
||
public event AsyncEventHandler<VoiceStateUpdatedEventArgs>? VoiceStateUpdated | ||
{ | ||
add => _client.VoiceStateUpdated += value; | ||
remove => _client.VoiceStateUpdated -= value; | ||
} | ||
|
||
public ValueTask<ImmutableArray<ulong>> GetChannelUsersAsync(ulong guildId, ulong voiceChannelId, bool includeBots = false, CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
return _client.GetChannelUsersAsync(guildId, voiceChannelId, includeBots, cancellationToken); | ||
} | ||
|
||
public ValueTask SendVoiceUpdateAsync(ulong guildId, ulong? voiceChannelId, bool selfDeaf = false, bool selfMute = false, CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
return _client.SendVoiceUpdateAsync(guildId, voiceChannelId, selfDeaf, selfMute, cancellationToken); | ||
} | ||
|
||
public ValueTask<ClientInformation> WaitForReadyAsync(CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
return _client.WaitForReadyAsync(cancellationToken); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
namespace Lavalink4NET.NetCord; | ||
|
||
using System; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using global::NetCord.Gateway; | ||
using Lavalink4NET.Clients; | ||
|
||
internal sealed class GatewayClientWrapper : GatewayClientWrapperBase, IDiscordClientWrapper, IDisposable | ||
{ | ||
private readonly GatewayClient _client; | ||
|
||
public GatewayClientWrapper(GatewayClient client) | ||
{ | ||
ArgumentNullException.ThrowIfNull(client); | ||
|
||
_client = client; | ||
|
||
_client.VoiceStateUpdate += HandleVoiceStateUpdateAsync; | ||
_client.VoiceServerUpdate += HandleVoiceServerUpdateAsync; | ||
} | ||
|
||
public void Dispose() | ||
{ | ||
_client.VoiceStateUpdate -= HandleVoiceStateUpdateAsync; | ||
_client.VoiceServerUpdate -= HandleVoiceServerUpdateAsync; | ||
} | ||
|
||
public override async ValueTask<ClientInformation> WaitForReadyAsync(CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
await _client.ReadyAsync | ||
.WaitAsync(cancellationToken) | ||
.ConfigureAwait(false); | ||
|
||
var shardCount = _client.Shard?.Count ?? 1; | ||
|
||
return new ClientInformation("NetCord", _client.Id, shardCount); | ||
} | ||
|
||
protected override GatewayClient GetClient(ulong guildId) => _client; | ||
|
||
protected override bool TryGetGuild(ulong guildId, [MaybeNullWhen(false)] out Guild guild) | ||
{ | ||
return _client.Cache.Guilds.TryGetValue(guildId, out guild); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
namespace Lavalink4NET.NetCord; | ||
|
||
using System; | ||
using System.Collections.Immutable; | ||
using System.Diagnostics.CodeAnalysis; | ||
using System.Linq; | ||
using System.Threading; | ||
using System.Threading.Tasks; | ||
using global::NetCord.Gateway; | ||
using Lavalink4NET.Clients; | ||
using Lavalink4NET.Clients.Events; | ||
using Lavalink4NET.Events; | ||
|
||
internal abstract class GatewayClientWrapperBase : IDiscordClientWrapper | ||
{ | ||
public event AsyncEventHandler<VoiceServerUpdatedEventArgs>? VoiceServerUpdated; | ||
|
||
public event AsyncEventHandler<VoiceStateUpdatedEventArgs>? VoiceStateUpdated; | ||
|
||
public ValueTask<ImmutableArray<ulong>> GetChannelUsersAsync(ulong guildId, ulong voiceChannelId, bool includeBots = false, CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
if (!TryGetGuild(guildId, out var guild)) | ||
{ | ||
return new ValueTask<ImmutableArray<ulong>>([]); | ||
} | ||
|
||
var currentUserId = GetClient(guildId).Id; | ||
|
||
var voiceStates = guild.VoiceStates | ||
.Where(x => x.Value.ChannelId == voiceChannelId) | ||
.Where(x => x.Value.UserId != currentUserId); | ||
|
||
if (!includeBots) | ||
{ | ||
voiceStates = voiceStates.Where(x => x.Value.User is not { IsBot: true, }); | ||
} | ||
|
||
var userIds = voiceStates.Select(x => x.Value.UserId).ToImmutableArray(); | ||
return new ValueTask<ImmutableArray<ulong>>(userIds); | ||
} | ||
|
||
public async ValueTask SendVoiceUpdateAsync(ulong guildId, ulong? voiceChannelId, bool selfDeaf = false, bool selfMute = false, CancellationToken cancellationToken = default) | ||
{ | ||
cancellationToken.ThrowIfCancellationRequested(); | ||
|
||
var voiceStateProperties = new VoiceStateProperties(guildId, voiceChannelId) { SelfDeaf = selfDeaf, SelfMute = selfMute, }; | ||
|
||
await GetClient(guildId) | ||
.UpdateVoiceStateAsync(voiceStateProperties) | ||
.ConfigureAwait(false); | ||
} | ||
|
||
protected abstract bool TryGetGuild(ulong guildId, [MaybeNullWhen(false)] out Guild guild); | ||
|
||
protected abstract GatewayClient GetClient(ulong guildId); | ||
|
||
protected ValueTask HandleVoiceServerUpdateAsync(VoiceServerUpdateEventArgs eventArgs) | ||
{ | ||
ArgumentNullException.ThrowIfNull(eventArgs); | ||
|
||
if (eventArgs.Endpoint is null) | ||
{ | ||
return default; | ||
} | ||
|
||
var voiceServerUpdatedEventArgs = new VoiceServerUpdatedEventArgs( | ||
guildId: eventArgs.GuildId, | ||
voiceServer: new VoiceServer(eventArgs.Token, eventArgs.Endpoint)); | ||
|
||
return VoiceServerUpdated.InvokeAsync(this, voiceServerUpdatedEventArgs); | ||
} | ||
|
||
protected async ValueTask HandleVoiceStateUpdateAsync(global::NetCord.Gateway.VoiceState eventArgs) | ||
{ | ||
ArgumentNullException.ThrowIfNull(eventArgs); | ||
|
||
// Retrieve previous voice state from cache | ||
var previousVoiceState = TryGetGuild(eventArgs.GuildId, out var guild) | ||
&& guild.VoiceStates.TryGetValue(eventArgs.UserId, out var previousVoiceStateData) | ||
? new Clients.VoiceState(VoiceChannelId: previousVoiceStateData.ChannelId, SessionId: previousVoiceStateData.SessionId) | ||
: default; | ||
|
||
var currentUserId = GetClient(eventArgs.GuildId).Id; | ||
|
||
var updatedVoiceState = new Clients.VoiceState( | ||
VoiceChannelId: eventArgs.ChannelId, | ||
SessionId: eventArgs.SessionId); | ||
|
||
var voiceStateUpdatedEventArgs = new VoiceStateUpdatedEventArgs( | ||
eventArgs.GuildId, | ||
eventArgs.UserId, | ||
eventArgs.UserId == currentUserId, | ||
updatedVoiceState, | ||
previousVoiceState); | ||
|
||
await VoiceStateUpdated | ||
.InvokeAsync(this, voiceStateUpdatedEventArgs) | ||
.ConfigureAwait(false); | ||
} | ||
|
||
public abstract ValueTask<ClientInformation> WaitForReadyAsync(CancellationToken cancellationToken = default); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
namespace Lavalink4NET.NetCord; | ||
|
||
using System; | ||
using Microsoft.Extensions.Hosting; | ||
|
||
public static class HostBuilderExtensions | ||
{ | ||
public static IHostBuilder UseLavalink(this IHostBuilder hostBuilder) | ||
{ | ||
ArgumentNullException.ThrowIfNull(hostBuilder); | ||
|
||
return hostBuilder.ConfigureServices(static (_, services) => services.AddLavalink()); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
<Project Sdk="Microsoft.NET.Sdk"> | ||
|
||
<PropertyGroup> | ||
<OutputType>Library</OutputType> | ||
<TargetFrameworks>net8.0</TargetFrameworks> | ||
<LangVersion>latest</LangVersion> | ||
|
||
<!-- Package Description --> | ||
<Description>High performance Lavalink wrapper for .NET | Add powerful audio playback to your NetCord-based applications with this integration for Lavalink4NET. Suitable for end users developing with NetCord.</Description> | ||
<PackageTags>lavalink,lavalink-wrapper,discord,discord-music,discord-music-bot,netcord</PackageTags> | ||
</PropertyGroup> | ||
|
||
<ItemGroup> | ||
<PackageReference Include="NetCord" Version="1.0.0-alpha.270" /> | ||
<PackageReference Include="NetCord.Services" Version="1.0.0-alpha.171" /> | ||
</ItemGroup> | ||
|
||
<ItemGroup> | ||
<ProjectReference Include="..\Lavalink4NET\Lavalink4NET.csproj" /> | ||
</ItemGroup> | ||
|
||
<Import Project="../Lavalink4NET.targets" /> | ||
</Project> |
Oops, something went wrong.