Skip to content

Commit

Permalink
feat: add support for more frameworks
Browse files Browse the repository at this point in the history
  • Loading branch information
XeroxDev committed Feb 25, 2024
1 parent 6b66c56 commit 73766a8
Show file tree
Hide file tree
Showing 28 changed files with 1,869 additions and 1,125 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ This is a library for the YTMDesktop Companion Server which lets you easier comm
authorization and so on.

## Table of contents

<!-- toc -->

- [Badges](#badges)
Expand All @@ -25,7 +26,6 @@ authorization and so on.

[![Awesome Badges](https://img.shields.io/badge/badges-awesome-green?style=for-the-badge)](https://shields.io)


## Installation

TODO: Add installation instructions
Expand Down
28 changes: 27 additions & 1 deletion YTMDesktopCompanion.Example/Program.cs
Original file line number Diff line number Diff line change
@@ -1,8 +1,34 @@
using System.Text.Json;
// This file is part of the YTMDesktopCompanion.Example project.
//
// Copyright (c) 2024 Dominic Ris
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#region

using System.Text.Json;
using NuGet.Versioning;
using XeroxDev.YTMDesktop.Companion;
using XeroxDev.YTMDesktop.Companion.Settings;

#endregion

#region Setup

// Set YOUR version (or fetch them from anywhere) I will use a static version for this example
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,11 @@
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<RootNamespace>XeroxDev.YTMDesktop.Companion.Example</RootNamespace>
<LangVersion>latest</LangVersion>
<NeutralLanguage>en</NeutralLanguage>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\YTMDesktopCompanion\YTMDesktopCompanion.csproj" />
</ItemGroup>

</Project>
518 changes: 308 additions & 210 deletions YTMDesktopCompanion/Clients/RestClient.cs

Large diffs are not rendered by default.

251 changes: 142 additions & 109 deletions YTMDesktopCompanion/Clients/SocketClient.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,30 @@
using SocketIOClient;
// This file is part of the YTMDesktopCompanion project.
//
// Copyright (c) 2024 Dominic Ris
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#region

using System;
using System.Threading.Tasks;
using SocketIOClient;
using SocketIOClient.Transport;
using SocketIOClient.Windows7;
using XeroxDev.YTMDesktop.Companion.Constants;
Expand All @@ -7,132 +33,139 @@
using XeroxDev.YTMDesktop.Companion.Models.Output;
using XeroxDev.YTMDesktop.Companion.Settings;

namespace XeroxDev.YTMDesktop.Companion.Clients;
#endregion

public class SocketClient : IGenericClient
namespace XeroxDev.YTMDesktop.Companion.Clients
{
/// <summary>
/// The settings for the socket client.
/// </summary>
public ConnectorSettings Settings
public class SocketClient : IGenericClient
{
get => _settings;
set
private ConnectorSettings _settings;

/// <summary>
/// The socket client
/// </summary>
private SocketIOClient.SocketIO _socket;

public SocketClient(ConnectorSettings settings)
{
if (value is null) throw new ArgumentNullException(nameof(value), "The settings cannot be null.");
var reconnect = false;
try
{
reconnect = Settings.Host != value.Host || Settings.Port != value.Port || Settings.Token != value.Token;
}
catch
{
// ignored
}
_settings = settings;
}

#region IGenericClient Members

_settings = value;
/// <summary>
/// The settings for the socket client.
/// </summary>
public ConnectorSettings Settings
{
get => _settings;
set
{
if (value is null) throw new ArgumentNullException(nameof(value), "The settings cannot be null.");
var reconnect = false;
try
{
reconnect = Settings.Host != value.Host || Settings.Port != value.Port || Settings.Token != value.Token;
}
catch
{
// ignored
}

_settings = value;
#pragma warning disable CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
if (reconnect && _socket is not null) Connect();
if (reconnect && _socket != null) Connect();
#pragma warning restore CS4014 // Because this call is not awaited, execution of the current method continues before the call is completed
}
}
}

/// <inheritdoc />
public void SetAuthToken(string token)
{
var settings = Settings;
settings.Token = token;
Settings = settings;
}

/// <summary>
/// The socket client
/// </summary>
private SocketIOClient.SocketIO? _socket;

private ConnectorSettings _settings;

#region Events

/// <summary>
/// The event that is raised when the client receives errors.
/// </summary>
public event EventHandler<Exception> OnError = delegate { };
/// <inheritdoc />
public void SetAuthToken(string token)
{
var settings = Settings;
settings.Token = token;
Settings = settings;
}

/// <summary>
/// The event that is raised when the socket connection is changed.
/// </summary>
public event EventHandler<ESocketState> OnConnectionChange = delegate { };
#endregion

/// <summary>
/// The event that is raised when the YTMDesktop State has changed.
/// </summary>
public event EventHandler<StateOutput> OnStateChange = delegate { };
/// <summary>
/// Get the whole socket object. Use with caution!<br />
/// Useful for custom things that are not implemented in the library yet.
/// </summary>
/// <returns>The socket object</returns>
public SocketIOClient.SocketIO GetSocket()
{
return _socket;
}

/// <summary>
/// The event that is raised when a playlist was created
/// </summary>
public event EventHandler<PlaylistOutput> OnPlaylistCreated = delegate { };
/// <summary>
/// Connect to the socket server
/// </summary>
public async Task Connect()
{
try
{
if (_socket != null)
{
await _socket.DisconnectAsync();
_socket.Dispose();
_socket = null;
OnConnectionChange(this, ESocketState.Disconnected);
}

OnConnectionChange(this, ESocketState.Connecting);

_socket = new SocketIOClient.SocketIO($"http://{Settings.Host}:{Settings.Port}{Endpoints.Realtime}", new SocketIOOptions
{
Transport = TransportProtocol.WebSocket,
Auth = Settings.Token
});
_socket.ClientWebSocketProvider = () => new SystemNetWebSocketsClientWebSocket();

_socket.OnConnected += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Connected);
_socket.OnDisconnected += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Disconnected);
_socket.OnError += (sender, args) => OnError(sender ?? this, new Exception(args));
_socket.OnReconnectError += (sender, args) => OnError(sender ?? this, args);
_socket.OnReconnected += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Connected);
_socket.OnReconnectAttempt += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Connecting);
_socket.On("state-update", data => OnStateChange(this, data.GetValue<StateOutput>()));
_socket.On("playlist-created", data => OnPlaylistCreated(this, data.GetValue<PlaylistOutput>()));
_socket.On("playlist-delete", data => OnPlaylistDeleted(this, data.GetValue<string>()));
}
catch (Exception ex)
{
OnError(this, ex);
}
}

/// <summary>
/// The event that is raised when a playlist was deleted
/// </summary>
public event EventHandler<string> OnPlaylistDeleted = delegate { };
#region Events

#endregion
/// <summary>
/// The event that is raised when the client receives errors.
/// </summary>
public event EventHandler<Exception> OnError = delegate { };

public SocketClient(ConnectorSettings settings)
{
_settings = settings;
}
/// <summary>
/// The event that is raised when the socket connection is changed.
/// </summary>
public event EventHandler<ESocketState> OnConnectionChange = delegate { };

/// <summary>
/// Get the whole socket object. Use with caution!<br/>
/// Useful for custom things that are not implemented in the library yet.
/// </summary>
/// <returns>The socket object</returns>
public SocketIOClient.SocketIO GetSocket()
{
return _socket!;
}
/// <summary>
/// The event that is raised when the YTMDesktop State has changed.
/// </summary>
public event EventHandler<StateOutput> OnStateChange = delegate { };

/// <summary>
/// Connect to the socket server
/// </summary>
public async Task Connect()
{
try
{
if (_socket is not null)
{
await _socket.DisconnectAsync();
_socket.Dispose();
_socket = null;
OnConnectionChange(this, ESocketState.Disconnected);
}
/// <summary>
/// The event that is raised when a playlist was created
/// </summary>
public event EventHandler<PlaylistOutput> OnPlaylistCreated = delegate { };

OnConnectionChange(this, ESocketState.Connecting);
/// <summary>
/// The event that is raised when a playlist was deleted
/// </summary>
public event EventHandler<string> OnPlaylistDeleted = delegate { };

_socket = new SocketIOClient.SocketIO($"http://{Settings.Host}:{Settings.Port}{Endpoints.Realtime}", new SocketIOOptions
{
Transport = TransportProtocol.WebSocket,
Auth = Settings.Token,
});
_socket.ClientWebSocketProvider = () => new SystemNetWebSocketsClientWebSocket();

_socket.OnConnected += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Connected);
_socket.OnDisconnected += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Disconnected);
_socket.OnError += (sender, args) => OnError(sender ?? this, new Exception(args));
_socket.OnReconnectError += (sender, args) => OnError(sender ?? this, args);
_socket.OnReconnected += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Connected);
_socket.OnReconnectAttempt += (sender, _) => OnConnectionChange(sender ?? this, ESocketState.Connecting);
_socket.On("state-update", data => OnStateChange(this, data.GetValue<StateOutput>()));
_socket.On("playlist-created", data => OnPlaylistCreated(this, data.GetValue<PlaylistOutput>()));
_socket.On("playlist-delete", data => OnPlaylistDeleted(this, data.GetValue<string>()));
}
catch (Exception ex)
{
OnError(this, ex);
}
#endregion
}
}

0 comments on commit 73766a8

Please sign in to comment.