| @@ -18,8 +18,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{ | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Providers.WS4Net", "src\Discord.Net.Providers.WS4Net\Discord.Net.Providers.WS4Net.csproj", "{6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Providers.UdpClient", "src\Discord.Net.Providers.UdpClient\Discord.Net.Providers.UdpClient.csproj", "{ABC9F4B9-2452-4725-B522-754E0A02E282}" | |||
| EndProject | |||
| Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Extensions", "Extensions", "{CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A}" | |||
| EndProject | |||
| Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Discord.Net.Tests", "test\Discord.Net.Tests\Discord.Net.Tests.csproj", "{C38E5BC1-11CB-4101-8A38-5B40A1BC6433}" | |||
| @@ -108,18 +106,6 @@ Global | |||
| {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x64.Build.0 = Release|Any CPU | |||
| {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x86.ActiveCfg = Release|Any CPU | |||
| {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7}.Release|x86.Build.0 = Release|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Debug|x64.Build.0 = Debug|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Debug|x86.ActiveCfg = Debug|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Debug|x86.Build.0 = Debug|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Release|Any CPU.ActiveCfg = Release|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Release|Any CPU.Build.0 = Release|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Release|x64.ActiveCfg = Release|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Release|x64.Build.0 = Release|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Release|x86.ActiveCfg = Release|Any CPU | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282}.Release|x86.Build.0 = Release|Any CPU | |||
| {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | |||
| {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|Any CPU.Build.0 = Debug|Any CPU | |||
| {C38E5BC1-11CB-4101-8A38-5B40A1BC6433}.Debug|x64.ActiveCfg = Debug|Any CPU | |||
| @@ -154,7 +140,6 @@ Global | |||
| {078DD7E6-943D-4D09-AFC2-D2BA58B76C9C} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A} | |||
| {688FD1D8-7F01-4539-B2E9-F473C5D699C7} = {288C363D-A636-4EAE-9AC1-4698B641B26E} | |||
| {6BDEEC08-417B-459F-9CA3-FF8BAB18CAC7} = {B0657AAE-DCC5-4FBF-8E5D-1FB578CF3012} | |||
| {ABC9F4B9-2452-4725-B522-754E0A02E282} = {B0657AAE-DCC5-4FBF-8E5D-1FB578CF3012} | |||
| {9AFAB80E-D2D3-4EDB-B58C-BACA78D1EA30} = {CC3D4B1C-9DE0-448B-8AE7-F3F1F3EC5C3A} | |||
| EndGlobalSection | |||
| EndGlobal | |||
| @@ -1,12 +0,0 @@ | |||
| <Project ToolsVersion="15.0" Sdk="Microsoft.NET.Sdk" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <Import Project="../../Discord.Net.targets" /> | |||
| <PropertyGroup> | |||
| <AssemblyName>Discord.Net.Providers.UDPClient</AssemblyName> | |||
| <RootNamespace>Discord.Providers.UDPClient</RootNamespace> | |||
| <Description>An optional UDP client provider for Discord.Net using System.Net.UdpClient</Description> | |||
| <TargetFramework>net45</TargetFramework> | |||
| </PropertyGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\Discord.Net.Core\Discord.Net.Core.csproj" /> | |||
| </ItemGroup> | |||
| </Project> | |||
| @@ -1,131 +0,0 @@ | |||
| using Discord.Net.Udp; | |||
| using System; | |||
| using System.Net; | |||
| using System.Threading; | |||
| using System.Threading.Tasks; | |||
| using UdpSocket = System.Net.Sockets.UdpClient; | |||
| namespace Discord.Net.Providers.UDPClient | |||
| { | |||
| internal class UDPClient : IUdpSocket, IDisposable | |||
| { | |||
| public event Func<byte[], int, int, Task> ReceivedDatagram; | |||
| private readonly SemaphoreSlim _lock; | |||
| private UdpSocket _udp; | |||
| private IPEndPoint _destination; | |||
| private CancellationTokenSource _cancelTokenSource; | |||
| private CancellationToken _cancelToken, _parentToken; | |||
| private Task _task; | |||
| private bool _isDisposed; | |||
| public ushort Port => (ushort)((_udp?.Client.LocalEndPoint as IPEndPoint)?.Port ?? 0); | |||
| public UDPClient() | |||
| { | |||
| _lock = new SemaphoreSlim(1, 1); | |||
| _cancelTokenSource = new CancellationTokenSource(); | |||
| } | |||
| private void Dispose(bool disposing) | |||
| { | |||
| if (!_isDisposed) | |||
| { | |||
| if (disposing) | |||
| StopInternalAsync(true).GetAwaiter().GetResult(); | |||
| _isDisposed = true; | |||
| } | |||
| } | |||
| public void Dispose() | |||
| { | |||
| Dispose(true); | |||
| } | |||
| public async Task StartAsync() | |||
| { | |||
| await _lock.WaitAsync().ConfigureAwait(false); | |||
| try | |||
| { | |||
| await StartInternalAsync(_cancelToken).ConfigureAwait(false); | |||
| } | |||
| finally | |||
| { | |||
| _lock.Release(); | |||
| } | |||
| } | |||
| public async Task StartInternalAsync(CancellationToken cancelToken) | |||
| { | |||
| await StopInternalAsync().ConfigureAwait(false); | |||
| _cancelTokenSource = new CancellationTokenSource(); | |||
| _cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_parentToken, _cancelTokenSource.Token).Token; | |||
| _udp = new UdpSocket(); | |||
| _task = RunAsync(_cancelToken); | |||
| } | |||
| public async Task StopAsync() | |||
| { | |||
| await _lock.WaitAsync().ConfigureAwait(false); | |||
| try | |||
| { | |||
| await StopInternalAsync().ConfigureAwait(false); | |||
| } | |||
| finally | |||
| { | |||
| _lock.Release(); | |||
| } | |||
| } | |||
| public async Task StopInternalAsync(bool isDisposing = false) | |||
| { | |||
| try { _cancelTokenSource.Cancel(false); } catch { } | |||
| if (!isDisposing) | |||
| await (_task ?? Task.Delay(0)).ConfigureAwait(false); | |||
| if (_udp != null) | |||
| { | |||
| try { _udp.Close(); } | |||
| catch { } | |||
| _udp = null; | |||
| } | |||
| } | |||
| public void SetDestination(string host, int port) | |||
| { | |||
| var entry = Dns.GetHostEntryAsync(host).GetAwaiter().GetResult(); | |||
| _destination = new IPEndPoint(entry.AddressList[0], port); | |||
| } | |||
| public void SetCancelToken(CancellationToken cancelToken) | |||
| { | |||
| _parentToken = cancelToken; | |||
| _cancelToken = CancellationTokenSource.CreateLinkedTokenSource(_parentToken, _cancelTokenSource.Token).Token; | |||
| } | |||
| public async Task SendAsync(byte[] data, int index, int count) | |||
| { | |||
| if (index != 0) //Should never happen? | |||
| { | |||
| var newData = new byte[count]; | |||
| Buffer.BlockCopy(data, index, newData, 0, count); | |||
| data = newData; | |||
| } | |||
| await _udp.SendAsync(data, count, _destination).ConfigureAwait(false); | |||
| } | |||
| private async Task RunAsync(CancellationToken cancelToken) | |||
| { | |||
| var closeTask = Task.Delay(-1, cancelToken); | |||
| while (!cancelToken.IsCancellationRequested) | |||
| { | |||
| var receiveTask = _udp.ReceiveAsync(); | |||
| var task = await Task.WhenAny(closeTask, receiveTask).ConfigureAwait(false); | |||
| if (task == closeTask) | |||
| break; | |||
| var result = receiveTask.Result; | |||
| await ReceivedDatagram(result.Buffer, 0, result.Buffer.Length).ConfigureAwait(false); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,9 +0,0 @@ | |||
| using Discord.Net.Udp; | |||
| namespace Discord.Net.Providers.UDPClient | |||
| { | |||
| public static class UDPClientProvider | |||
| { | |||
| public static readonly UdpSocketProvider Instance = () => new UDPClient(); | |||
| } | |||
| } | |||