Fix warnings

This commit is contained in:
Bond_009 2020-07-24 16:37:54 +02:00
parent f5a3cc654f
commit 01e781035f
13 changed files with 163 additions and 166 deletions

View File

@ -2776,82 +2776,82 @@ namespace Emby.Server.Implementations.Data
private string FixUnicodeChars(string buffer) private string FixUnicodeChars(string buffer)
{ {
if (buffer.IndexOf('\u2013') > -1) if (buffer.IndexOf('\u2013', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2013', '-'); // en dash buffer = buffer.Replace('\u2013', '-'); // en dash
} }
if (buffer.IndexOf('\u2014') > -1) if (buffer.IndexOf('\u2014', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2014', '-'); // em dash buffer = buffer.Replace('\u2014', '-'); // em dash
} }
if (buffer.IndexOf('\u2015') > -1) if (buffer.IndexOf('\u2015', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2015', '-'); // horizontal bar buffer = buffer.Replace('\u2015', '-'); // horizontal bar
} }
if (buffer.IndexOf('\u2017') > -1) if (buffer.IndexOf('\u2017', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2017', '_'); // double low line buffer = buffer.Replace('\u2017', '_'); // double low line
} }
if (buffer.IndexOf('\u2018') > -1) if (buffer.IndexOf('\u2018', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2018', '\''); // left single quotation mark buffer = buffer.Replace('\u2018', '\''); // left single quotation mark
} }
if (buffer.IndexOf('\u2019') > -1) if (buffer.IndexOf('\u2019', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2019', '\''); // right single quotation mark buffer = buffer.Replace('\u2019', '\''); // right single quotation mark
} }
if (buffer.IndexOf('\u201a') > -1) if (buffer.IndexOf('\u201a', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u201a', ','); // single low-9 quotation mark buffer = buffer.Replace('\u201a', ','); // single low-9 quotation mark
} }
if (buffer.IndexOf('\u201b') > -1) if (buffer.IndexOf('\u201b', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u201b', '\''); // single high-reversed-9 quotation mark buffer = buffer.Replace('\u201b', '\''); // single high-reversed-9 quotation mark
} }
if (buffer.IndexOf('\u201c') > -1) if (buffer.IndexOf('\u201c', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u201c', '\"'); // left double quotation mark buffer = buffer.Replace('\u201c', '\"'); // left double quotation mark
} }
if (buffer.IndexOf('\u201d') > -1) if (buffer.IndexOf('\u201d', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u201d', '\"'); // right double quotation mark buffer = buffer.Replace('\u201d', '\"'); // right double quotation mark
} }
if (buffer.IndexOf('\u201e') > -1) if (buffer.IndexOf('\u201e', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u201e', '\"'); // double low-9 quotation mark buffer = buffer.Replace('\u201e', '\"'); // double low-9 quotation mark
} }
if (buffer.IndexOf('\u2026') > -1) if (buffer.IndexOf('\u2026', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace("\u2026", "..."); // horizontal ellipsis buffer = buffer.Replace("\u2026", "...", StringComparison.Ordinal); // horizontal ellipsis
} }
if (buffer.IndexOf('\u2032') > -1) if (buffer.IndexOf('\u2032', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2032', '\''); // prime buffer = buffer.Replace('\u2032', '\''); // prime
} }
if (buffer.IndexOf('\u2033') > -1) if (buffer.IndexOf('\u2033', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u2033', '\"'); // double prime buffer = buffer.Replace('\u2033', '\"'); // double prime
} }
if (buffer.IndexOf('\u0060') > -1) if (buffer.IndexOf('\u0060', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u0060', '\''); // grave accent buffer = buffer.Replace('\u0060', '\''); // grave accent
} }
if (buffer.IndexOf('\u00B4') > -1) if (buffer.IndexOf('\u00B4', StringComparison.Ordinal) > -1)
{ {
buffer = buffer.Replace('\u00B4', '\''); // acute accent buffer = buffer.Replace('\u00B4', '\''); // acute accent
} }
@ -3000,7 +3000,6 @@ namespace Emby.Server.Implementations.Data
{ {
connection.RunInTransaction(db => connection.RunInTransaction(db =>
{ {
var statements = PrepareAll(db, statementTexts).ToList(); var statements = PrepareAll(db, statementTexts).ToList();
if (!isReturningZeroItems) if (!isReturningZeroItems)
@ -4670,8 +4669,12 @@ namespace Emby.Server.Implementations.Data
if (query.BlockUnratedItems.Length > 1) if (query.BlockUnratedItems.Length > 1)
{ {
var inClause = string.Join(",", query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'")); var inClause = string.Join(',', query.BlockUnratedItems.Select(i => "'" + i.ToString() + "'"));
whereClauses.Add(string.Format("(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))", inClause)); whereClauses.Add(
string.Format(
CultureInfo.InvariantCulture,
"(InheritedParentalRatingValue > 0 or UnratedType not in ({0}))",
inClause));
} }
if (query.ExcludeInheritedTags.Length > 0) if (query.ExcludeInheritedTags.Length > 0)
@ -4680,7 +4683,7 @@ namespace Emby.Server.Implementations.Data
if (statement == null) if (statement == null)
{ {
int index = 0; int index = 0;
string excludedTags = string.Join(",", query.ExcludeInheritedTags.Select(t => paramName + index++)); string excludedTags = string.Join(',', query.ExcludeInheritedTags.Select(t => paramName + index++));
whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + excludedTags + ")) is null)"); whereClauses.Add("((select CleanValue from itemvalues where ItemId=Guid and Type=6 and cleanvalue in (" + excludedTags + ")) is null)");
} }
else else

View File

@ -449,7 +449,7 @@ namespace Emby.Server.Implementations.HttpServer
if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase)) if (string.Equals(httpReq.Verb, "OPTIONS", StringComparison.OrdinalIgnoreCase))
{ {
httpRes.StatusCode = 200; httpRes.StatusCode = 200;
foreach(var (key, value) in GetDefaultCorsHeaders(httpReq)) foreach (var (key, value) in GetDefaultCorsHeaders(httpReq))
{ {
httpRes.Headers.Add(key, value); httpRes.Headers.Add(key, value);
} }
@ -486,7 +486,7 @@ namespace Emby.Server.Implementations.HttpServer
var handler = GetServiceHandler(httpReq); var handler = GetServiceHandler(httpReq);
if (handler != null) if (handler != null)
{ {
await handler.ProcessRequestAsync(this, httpReq, httpRes, _logger, cancellationToken).ConfigureAwait(false); await handler.ProcessRequestAsync(this, httpReq, httpRes, cancellationToken).ConfigureAwait(false);
} }
else else
{ {

View File

@ -21,6 +21,7 @@ namespace Emby.Server.Implementations.IO
private readonly List<string> _affectedPaths = new List<string>(); private readonly List<string> _affectedPaths = new List<string>();
private readonly object _timerLock = new object(); private readonly object _timerLock = new object();
private Timer _timer; private Timer _timer;
private bool _disposed;
public FileRefresher(string path, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ILogger logger) public FileRefresher(string path, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ILogger logger)
{ {
@ -213,11 +214,11 @@ namespace Emby.Server.Implementations.IO
} }
} }
private bool _disposed;
public void Dispose() public void Dispose()
{ {
_disposed = true; _disposed = true;
DisposeTimer(); DisposeTimer();
GC.SuppressFinalize(this);
} }
} }
} }

View File

@ -46,8 +46,6 @@ namespace Emby.Server.Implementations.Library
private readonly Dictionary<string, ILiveStream> _openStreams = new Dictionary<string, ILiveStream>(StringComparer.OrdinalIgnoreCase); private readonly Dictionary<string, ILiveStream> _openStreams = new Dictionary<string, ILiveStream>(StringComparer.OrdinalIgnoreCase);
private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1); private readonly SemaphoreSlim _liveStreamSemaphore = new SemaphoreSlim(1, 1);
private readonly object _disposeLock = new object();
private IMediaSourceProvider[] _providers; private IMediaSourceProvider[] _providers;
public MediaSourceManager( public MediaSourceManager(
@ -623,12 +621,14 @@ namespace Emby.Server.Implementations.Library
if (liveStreamInfo is IDirectStreamProvider) if (liveStreamInfo is IDirectStreamProvider)
{ {
var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest var info = await _mediaEncoder.GetMediaInfo(
{ new MediaInfoRequest
MediaSource = mediaSource, {
ExtractChapters = false, MediaSource = mediaSource,
MediaType = DlnaProfileType.Video ExtractChapters = false,
}, cancellationToken).ConfigureAwait(false); MediaType = DlnaProfileType.Video
},
cancellationToken).ConfigureAwait(false);
mediaSource.MediaStreams = info.MediaStreams; mediaSource.MediaStreams = info.MediaStreams;
mediaSource.Container = info.Container; mediaSource.Container = info.Container;
@ -859,21 +859,21 @@ namespace Emby.Server.Implementations.Library
} }
} }
private Tuple<IMediaSourceProvider, string> GetProvider(string key) private (IMediaSourceProvider, string) GetProvider(string key)
{ {
if (string.IsNullOrEmpty(key)) if (string.IsNullOrEmpty(key))
{ {
throw new ArgumentException("key"); throw new ArgumentException("Key can't be empty.", nameof(key));
} }
var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2); var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2);
var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase)); var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase));
var splitIndex = key.IndexOf(LiveStreamIdDelimeter); var splitIndex = key.IndexOf(LiveStreamIdDelimeter, StringComparison.Ordinal);
var keyId = key.Substring(splitIndex + 1); var keyId = key.Substring(splitIndex + 1);
return new Tuple<IMediaSourceProvider, string>(provider, keyId); return (provider, keyId);
} }
/// <summary> /// <summary>
@ -893,15 +893,12 @@ namespace Emby.Server.Implementations.Library
{ {
if (dispose) if (dispose)
{ {
lock (_disposeLock) foreach (var key in _openStreams.Keys.ToList())
{ {
foreach (var key in _openStreams.Keys.ToList()) CloseLiveStream(key).GetAwaiter().GetResult();
{
var task = CloseLiveStream(key);
Task.WaitAll(task);
}
} }
_liveStreamSemaphore.Dispose();
} }
} }
} }

View File

@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
} }
public class HdHomerunManager : IDisposable public sealed class HdHomerunManager : IDisposable
{ {
public const int HdHomeRunPort = 65001; public const int HdHomeRunPort = 65001;
@ -105,6 +105,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
StopStreaming(socket).GetAwaiter().GetResult(); StopStreaming(socket).GetAwaiter().GetResult();
} }
} }
GC.SuppressFinalize(this);
} }
public async Task<bool> CheckTunerAvailability(IPAddress remoteIp, int tuner, CancellationToken cancellationToken) public async Task<bool> CheckTunerAvailability(IPAddress remoteIp, int tuner, CancellationToken cancellationToken)
@ -162,7 +164,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
_activeTuner = i; _activeTuner = i;
var lockKeyString = string.Format("{0:d}", lockKeyValue); var lockKeyString = string.Format(CultureInfo.InvariantCulture, "{0:d}", lockKeyValue);
var lockkeyMsg = CreateSetMessage(i, "lockkey", lockKeyString, null); var lockkeyMsg = CreateSetMessage(i, "lockkey", lockKeyString, null);
await stream.WriteAsync(lockkeyMsg, 0, lockkeyMsg.Length, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(lockkeyMsg, 0, lockkeyMsg.Length, cancellationToken).ConfigureAwait(false);
int receivedBytes = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false); int receivedBytes = await stream.ReadAsync(buffer, 0, buffer.Length, cancellationToken).ConfigureAwait(false);
@ -173,8 +175,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
continue; continue;
} }
var commandList = commands.GetCommands(); foreach (var command in commands.GetCommands())
foreach (var command in commandList)
{ {
var channelMsg = CreateSetMessage(i, command.Item1, command.Item2, lockKeyValue); var channelMsg = CreateSetMessage(i, command.Item1, command.Item2, lockKeyValue);
await stream.WriteAsync(channelMsg, 0, channelMsg.Length, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(channelMsg, 0, channelMsg.Length, cancellationToken).ConfigureAwait(false);
@ -188,7 +189,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
} }
} }
var targetValue = string.Format("rtp://{0}:{1}", localIp, localPort); var targetValue = string.Format(CultureInfo.InvariantCulture, "rtp://{0}:{1}", localIp, localPort);
var targetMsg = CreateSetMessage(i, "target", targetValue, lockKeyValue); var targetMsg = CreateSetMessage(i, "target", targetValue, lockKeyValue);
await stream.WriteAsync(targetMsg, 0, targetMsg.Length, cancellationToken).ConfigureAwait(false); await stream.WriteAsync(targetMsg, 0, targetMsg.Length, cancellationToken).ConfigureAwait(false);

View File

@ -15,13 +15,11 @@ namespace Emby.Server.Implementations.Net
public sealed class UdpSocket : ISocket, IDisposable public sealed class UdpSocket : ISocket, IDisposable
{ {
private Socket _socket; private Socket _socket;
private int _localPort; private readonly int _localPort;
private bool _disposed = false; private bool _disposed = false;
public Socket Socket => _socket; public Socket Socket => _socket;
public IPAddress LocalIPAddress { get; }
private readonly SocketAsyncEventArgs _receiveSocketAsyncEventArgs = new SocketAsyncEventArgs() private readonly SocketAsyncEventArgs _receiveSocketAsyncEventArgs = new SocketAsyncEventArgs()
{ {
SocketFlags = SocketFlags.None SocketFlags = SocketFlags.None
@ -51,18 +49,33 @@ namespace Emby.Server.Implementations.Net
InitReceiveSocketAsyncEventArgs(); InitReceiveSocketAsyncEventArgs();
} }
public UdpSocket(Socket socket, IPEndPoint endPoint)
{
if (socket == null)
{
throw new ArgumentNullException(nameof(socket));
}
_socket = socket;
_socket.Connect(endPoint);
InitReceiveSocketAsyncEventArgs();
}
public IPAddress LocalIPAddress { get; }
private void InitReceiveSocketAsyncEventArgs() private void InitReceiveSocketAsyncEventArgs()
{ {
var receiveBuffer = new byte[8192]; var receiveBuffer = new byte[8192];
_receiveSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length); _receiveSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
_receiveSocketAsyncEventArgs.Completed += _receiveSocketAsyncEventArgs_Completed; _receiveSocketAsyncEventArgs.Completed += OnReceiveSocketAsyncEventArgsCompleted;
var sendBuffer = new byte[8192]; var sendBuffer = new byte[8192];
_sendSocketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length); _sendSocketAsyncEventArgs.SetBuffer(sendBuffer, 0, sendBuffer.Length);
_sendSocketAsyncEventArgs.Completed += _sendSocketAsyncEventArgs_Completed; _sendSocketAsyncEventArgs.Completed += OnSendSocketAsyncEventArgsCompleted;
} }
private void _receiveSocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e) private void OnReceiveSocketAsyncEventArgsCompleted(object sender, SocketAsyncEventArgs e)
{ {
var tcs = _currentReceiveTaskCompletionSource; var tcs = _currentReceiveTaskCompletionSource;
if (tcs != null) if (tcs != null)
@ -86,7 +99,7 @@ namespace Emby.Server.Implementations.Net
} }
} }
private void _sendSocketAsyncEventArgs_Completed(object sender, SocketAsyncEventArgs e) private void OnSendSocketAsyncEventArgsCompleted(object sender, SocketAsyncEventArgs e)
{ {
var tcs = _currentSendTaskCompletionSource; var tcs = _currentSendTaskCompletionSource;
if (tcs != null) if (tcs != null)
@ -104,19 +117,6 @@ namespace Emby.Server.Implementations.Net
} }
} }
public UdpSocket(Socket socket, IPEndPoint endPoint)
{
if (socket == null)
{
throw new ArgumentNullException(nameof(socket));
}
_socket = socket;
_socket.Connect(endPoint);
InitReceiveSocketAsyncEventArgs();
}
public IAsyncResult BeginReceive(byte[] buffer, int offset, int count, AsyncCallback callback) public IAsyncResult BeginReceive(byte[] buffer, int offset, int count, AsyncCallback callback)
{ {
ThrowIfDisposed(); ThrowIfDisposed();
@ -247,6 +247,7 @@ namespace Emby.Server.Implementations.Net
} }
} }
/// <inheritdoc />
public void Dispose() public void Dispose()
{ {
if (_disposed) if (_disposed)
@ -255,6 +256,8 @@ namespace Emby.Server.Implementations.Net
} }
_socket?.Dispose(); _socket?.Dispose();
_receiveSocketAsyncEventArgs.Dispose();
_sendSocketAsyncEventArgs.Dispose();
_currentReceiveTaskCompletionSource?.TrySetCanceled(); _currentReceiveTaskCompletionSource?.TrySetCanceled();
_currentSendTaskCompletionSource?.TrySetCanceled(); _currentSendTaskCompletionSource?.TrySetCanceled();

View File

@ -349,16 +349,14 @@ namespace Emby.Server.Implementations.Playlists
AlbumTitle = child.Album AlbumTitle = child.Album
}; };
var hasAlbumArtist = child as IHasAlbumArtist; if (child is IHasAlbumArtist hasAlbumArtist)
if (hasAlbumArtist != null)
{ {
entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); entry.AlbumArtist = hasAlbumArtist.AlbumArtists.Count > 0 ? hasAlbumArtist.AlbumArtists[0] : null;
} }
var hasArtist = child as IHasArtist; if (child is IHasArtist hasArtist)
if (hasArtist != null)
{ {
entry.TrackArtist = hasArtist.Artists.FirstOrDefault(); entry.TrackArtist = hasArtist.Artists.Count > 0 ? hasArtist.Artists[0] : null;
} }
if (child.RunTimeTicks.HasValue) if (child.RunTimeTicks.HasValue)
@ -385,16 +383,14 @@ namespace Emby.Server.Implementations.Playlists
AlbumTitle = child.Album AlbumTitle = child.Album
}; };
var hasAlbumArtist = child as IHasAlbumArtist; if (child is IHasAlbumArtist hasAlbumArtist)
if (hasAlbumArtist != null)
{ {
entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); entry.AlbumArtist = hasAlbumArtist.AlbumArtists.Count > 0 ? hasAlbumArtist.AlbumArtists[0] : null;
} }
var hasArtist = child as IHasArtist; if (child is IHasArtist hasArtist)
if (hasArtist != null)
{ {
entry.TrackArtist = hasArtist.Artists.FirstOrDefault(); entry.TrackArtist = hasArtist.Artists.Count > 0 ? hasArtist.Artists[0] : null;
} }
if (child.RunTimeTicks.HasValue) if (child.RunTimeTicks.HasValue)
@ -411,8 +407,10 @@ namespace Emby.Server.Implementations.Playlists
if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase)) if (string.Equals(".m3u", extension, StringComparison.OrdinalIgnoreCase))
{ {
var playlist = new M3uPlaylist(); var playlist = new M3uPlaylist
playlist.IsExtended = true; {
IsExtended = true
};
foreach (var child in item.GetLinkedChildren()) foreach (var child in item.GetLinkedChildren())
{ {
var entry = new M3uPlaylistEntry() var entry = new M3uPlaylistEntry()
@ -422,10 +420,9 @@ namespace Emby.Server.Implementations.Playlists
Album = child.Album Album = child.Album
}; };
var hasAlbumArtist = child as IHasAlbumArtist; if (child is IHasAlbumArtist hasAlbumArtist)
if (hasAlbumArtist != null)
{ {
entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); entry.AlbumArtist = hasAlbumArtist.AlbumArtists.Count > 0 ? hasAlbumArtist.AlbumArtists[0] : null;
} }
if (child.RunTimeTicks.HasValue) if (child.RunTimeTicks.HasValue)
@ -453,10 +450,9 @@ namespace Emby.Server.Implementations.Playlists
Album = child.Album Album = child.Album
}; };
var hasAlbumArtist = child as IHasAlbumArtist; if (child is IHasAlbumArtist hasAlbumArtist)
if (hasAlbumArtist != null)
{ {
entry.AlbumArtist = hasAlbumArtist.AlbumArtists.FirstOrDefault(); entry.AlbumArtist = hasAlbumArtist.AlbumArtists.Count > 0 ? hasAlbumArtist.AlbumArtists[0] : null;
} }
if (child.RunTimeTicks.HasValue) if (child.RunTimeTicks.HasValue)
@ -514,7 +510,7 @@ namespace Emby.Server.Implementations.Playlists
if (!folderPath.EndsWith(Path.DirectorySeparatorChar)) if (!folderPath.EndsWith(Path.DirectorySeparatorChar))
{ {
folderPath = folderPath + Path.DirectorySeparatorChar; folderPath += Path.DirectorySeparatorChar;
} }
var folderUri = new Uri(folderPath); var folderUri = new Uri(folderPath);
@ -537,32 +533,12 @@ namespace Emby.Server.Implementations.Playlists
return relativePath; return relativePath;
} }
private static string UnEscape(string content)
{
if (content == null)
{
return content;
}
return content.Replace("&amp;", "&").Replace("&apos;", "'").Replace("&quot;", "\"").Replace("&gt;", ">").Replace("&lt;", "<");
}
private static string Escape(string content)
{
if (content == null)
{
return null;
}
return content.Replace("&", "&amp;").Replace("'", "&apos;").Replace("\"", "&quot;").Replace(">", "&gt;").Replace("<", "&lt;");
}
public Folder GetPlaylistsFolder(Guid userId) public Folder GetPlaylistsFolder(Guid userId)
{ {
var typeName = "PlaylistsFolder"; const string TypeName = "PlaylistsFolder";
return _libraryManager.RootFolder.Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, typeName, StringComparison.Ordinal)) ?? return _libraryManager.RootFolder.Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, TypeName, StringComparison.Ordinal)) ??
_libraryManager.GetUserRootFolder().Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, typeName, StringComparison.Ordinal)); _libraryManager.GetUserRootFolder().Children.OfType<Folder>().FirstOrDefault(i => string.Equals(i.GetType().Name, TypeName, StringComparison.Ordinal));
} }
} }
} }

View File

@ -2,6 +2,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Threading.Tasks; using System.Threading.Tasks;
using Emby.Server.Implementations.HttpServer; using Emby.Server.Implementations.HttpServer;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
@ -91,12 +92,22 @@ namespace Emby.Server.Implementations.Services
{ {
if (restPath.Path[0] != '/') if (restPath.Path[0] != '/')
{ {
throw new ArgumentException(string.Format("Route '{0}' on '{1}' must start with a '/'", restPath.Path, restPath.RequestType.GetMethodName())); throw new ArgumentException(
string.Format(
CultureInfo.InvariantCulture,
"Route '{0}' on '{1}' must start with a '/'",
restPath.Path,
restPath.RequestType.GetMethodName()));
} }
if (restPath.Path.IndexOfAny(InvalidRouteChars) != -1) if (restPath.Path.IndexOfAny(InvalidRouteChars) != -1)
{ {
throw new ArgumentException(string.Format("Route '{0}' on '{1}' contains invalid chars. ", restPath.Path, restPath.RequestType.GetMethodName())); throw new ArgumentException(
string.Format(
CultureInfo.InvariantCulture,
"Route '{0}' on '{1}' contains invalid chars. ",
restPath.Path,
restPath.RequestType.GetMethodName()));
} }
if (RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out List<RestPath> pathsAtFirstMatch)) if (RestPathMap.TryGetValue(restPath.FirstMatchHashKey, out List<RestPath> pathsAtFirstMatch))
@ -179,8 +190,7 @@ namespace Emby.Server.Implementations.Services
var service = httpHost.CreateInstance(serviceType); var service = httpHost.CreateInstance(serviceType);
var serviceRequiresContext = service as IRequiresRequest; if (service is IRequiresRequest serviceRequiresContext)
if (serviceRequiresContext != null)
{ {
serviceRequiresContext.Request = req; serviceRequiresContext.Request = req;
} }

View File

@ -67,7 +67,7 @@ namespace Emby.Server.Implementations.Services
} }
} }
public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, HttpResponse httpRes, ILogger logger, CancellationToken cancellationToken) public async Task ProcessRequestAsync(HttpListenerHost httpHost, IRequest httpReq, HttpResponse httpRes, CancellationToken cancellationToken)
{ {
httpReq.Items["__route"] = _restPath; httpReq.Items["__route"] = _restPath;
@ -76,10 +76,10 @@ namespace Emby.Server.Implementations.Services
httpReq.ResponseContentType = _responseContentType; httpReq.ResponseContentType = _responseContentType;
} }
var request = await CreateRequest(httpHost, httpReq, _restPath, logger).ConfigureAwait(false); var request = await CreateRequest(httpHost, httpReq, _restPath).ConfigureAwait(false);
httpHost.ApplyRequestFilters(httpReq, httpRes, request); httpHost.ApplyRequestFilters(httpReq, httpRes, request);
httpRes.HttpContext.SetServiceStackRequest(httpReq); httpRes.HttpContext.SetServiceStackRequest(httpReq);
var response = await httpHost.ServiceController.Execute(httpHost, request, httpReq).ConfigureAwait(false); var response = await httpHost.ServiceController.Execute(httpHost, request, httpReq).ConfigureAwait(false);
@ -92,7 +92,7 @@ namespace Emby.Server.Implementations.Services
await ResponseHelper.WriteToResponse(httpRes, httpReq, response, cancellationToken).ConfigureAwait(false); await ResponseHelper.WriteToResponse(httpRes, httpReq, response, cancellationToken).ConfigureAwait(false);
} }
public static async Task<object> CreateRequest(HttpListenerHost host, IRequest httpReq, RestPath restPath, ILogger logger) public static async Task<object> CreateRequest(HttpListenerHost host, IRequest httpReq, RestPath restPath)
{ {
var requestType = restPath.RequestType; var requestType = restPath.RequestType;

View File

@ -848,8 +848,8 @@ namespace Emby.Server.Implementations.Session
/// </summary> /// </summary>
/// <param name="info">The info.</param> /// <param name="info">The info.</param>
/// <returns>Task.</returns> /// <returns>Task.</returns>
/// <exception cref="ArgumentNullException">info</exception> /// <exception cref="ArgumentNullException"><c>info</c> is <c>null</c>.</exception>
/// <exception cref="ArgumentOutOfRangeException">positionTicks</exception> /// <exception cref="ArgumentOutOfRangeException"><c>info.PositionTicks</c> is <c>null</c> or negative.</exception>
public async Task OnPlaybackStopped(PlaybackStopInfo info) public async Task OnPlaybackStopped(PlaybackStopInfo info)
{ {
CheckDisposed(); CheckDisposed();

View File

@ -93,7 +93,7 @@ namespace Emby.Server.Implementations.Session
if (session != null) if (session != null)
{ {
EnsureController(session, e.Argument); EnsureController(session, e.Argument);
await KeepAliveWebSocket(e.Argument); await KeepAliveWebSocket(e.Argument).ConfigureAwait(false);
} }
else else
{ {
@ -177,7 +177,7 @@ namespace Emby.Server.Implementations.Session
// Notify WebSocket about timeout // Notify WebSocket about timeout
try try
{ {
await SendForceKeepAlive(webSocket); await SendForceKeepAlive(webSocket).ConfigureAwait(false);
} }
catch (WebSocketException exception) catch (WebSocketException exception)
{ {
@ -233,6 +233,7 @@ namespace Emby.Server.Implementations.Session
if (_keepAliveCancellationToken != null) if (_keepAliveCancellationToken != null)
{ {
_keepAliveCancellationToken.Cancel(); _keepAliveCancellationToken.Cancel();
_keepAliveCancellationToken.Dispose();
_keepAliveCancellationToken = null; _keepAliveCancellationToken = null;
} }
} }
@ -268,7 +269,7 @@ namespace Emby.Server.Implementations.Session
lost = _webSockets.Where(i => (DateTime.UtcNow - i.LastKeepAliveDate).TotalSeconds >= WebSocketLostTimeout).ToList(); lost = _webSockets.Where(i => (DateTime.UtcNow - i.LastKeepAliveDate).TotalSeconds >= WebSocketLostTimeout).ToList();
} }
if (inactive.Any()) if (inactive.Count > 0)
{ {
_logger.LogInformation("Sending ForceKeepAlive message to {0} inactive WebSockets.", inactive.Count); _logger.LogInformation("Sending ForceKeepAlive message to {0} inactive WebSockets.", inactive.Count);
} }
@ -277,7 +278,7 @@ namespace Emby.Server.Implementations.Session
{ {
try try
{ {
await SendForceKeepAlive(webSocket); await SendForceKeepAlive(webSocket).ConfigureAwait(false);
} }
catch (WebSocketException exception) catch (WebSocketException exception)
{ {
@ -288,7 +289,7 @@ namespace Emby.Server.Implementations.Session
lock (_webSocketsLock) lock (_webSocketsLock)
{ {
if (lost.Any()) if (lost.Count > 0)
{ {
_logger.LogInformation("Lost {0} WebSockets.", lost.Count); _logger.LogInformation("Lost {0} WebSockets.", lost.Count);
foreach (var webSocket in lost) foreach (var webSocket in lost)
@ -298,7 +299,7 @@ namespace Emby.Server.Implementations.Session
} }
} }
if (!_webSockets.Any()) if (_webSockets.Count == 0)
{ {
StopKeepAlive(); StopKeepAlive();
} }
@ -312,11 +313,13 @@ namespace Emby.Server.Implementations.Session
/// <returns>Task.</returns> /// <returns>Task.</returns>
private Task SendForceKeepAlive(IWebSocketConnection webSocket) private Task SendForceKeepAlive(IWebSocketConnection webSocket)
{ {
return webSocket.SendAsync(new WebSocketMessage<int> return webSocket.SendAsync(
{ new WebSocketMessage<int>
MessageType = "ForceKeepAlive", {
Data = WebSocketLostTimeout MessageType = "ForceKeepAlive",
}, CancellationToken.None); Data = WebSocketLostTimeout
},
CancellationToken.None);
} }
/// <summary> /// <summary>
@ -330,12 +333,11 @@ namespace Emby.Server.Implementations.Session
{ {
while (!cancellationToken.IsCancellationRequested) while (!cancellationToken.IsCancellationRequested)
{ {
await callback(); await callback().ConfigureAwait(false);
Task task = Task.Delay(interval, cancellationToken);
try try
{ {
await task; await Task.Delay(interval, cancellationToken).ConfigureAwait(false);
} }
catch (TaskCanceledException) catch (TaskCanceledException)
{ {

View File

@ -154,8 +154,8 @@ namespace Emby.Server.Implementations.Sorting
private static int CompareEpisodes(Episode x, Episode y) private static int CompareEpisodes(Episode x, Episode y)
{ {
var xValue = (x.ParentIndexNumber ?? -1) * 1000 + (x.IndexNumber ?? -1); var xValue = ((x.ParentIndexNumber ?? -1) * 1000) + (x.IndexNumber ?? -1);
var yValue = (y.ParentIndexNumber ?? -1) * 1000 + (y.IndexNumber ?? -1); var yValue = ((y.ParentIndexNumber ?? -1) * 1000) + (y.IndexNumber ?? -1);
return xValue.CompareTo(yValue); return xValue.CompareTo(yValue);
} }

View File

@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
@ -27,14 +28,17 @@ namespace Emby.Server.Implementations.SyncPlay
/// All sessions will receive the message. /// All sessions will receive the message.
/// </summary> /// </summary>
AllGroup = 0, AllGroup = 0,
/// <summary> /// <summary>
/// Only the specified session will receive the message. /// Only the specified session will receive the message.
/// </summary> /// </summary>
CurrentSession = 1, CurrentSession = 1,
/// <summary> /// <summary>
/// All sessions, except the current one, will receive the message. /// All sessions, except the current one, will receive the message.
/// </summary> /// </summary>
AllExceptCurrentSession = 2, AllExceptCurrentSession = 2,
/// <summary> /// <summary>
/// Only sessions that are not buffering will receive the message. /// Only sessions that are not buffering will receive the message.
/// </summary> /// </summary>
@ -56,15 +60,6 @@ namespace Emby.Server.Implementations.SyncPlay
/// </summary> /// </summary>
private readonly GroupInfo _group = new GroupInfo(); private readonly GroupInfo _group = new GroupInfo();
/// <inheritdoc />
public Guid GetGroupId() => _group.GroupId;
/// <inheritdoc />
public Guid GetPlayingItemId() => _group.PlayingItem.Id;
/// <inheritdoc />
public bool IsGroupEmpty() => _group.IsEmpty();
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="SyncPlayController" /> class. /// Initializes a new instance of the <see cref="SyncPlayController" /> class.
/// </summary> /// </summary>
@ -78,6 +73,15 @@ namespace Emby.Server.Implementations.SyncPlay
_syncPlayManager = syncPlayManager; _syncPlayManager = syncPlayManager;
} }
/// <inheritdoc />
public Guid GetGroupId() => _group.GroupId;
/// <inheritdoc />
public Guid GetPlayingItemId() => _group.PlayingItem.Id;
/// <inheritdoc />
public bool IsGroupEmpty() => _group.IsEmpty();
/// <summary> /// <summary>
/// Converts DateTime to UTC string. /// Converts DateTime to UTC string.
/// </summary> /// </summary>
@ -85,7 +89,7 @@ namespace Emby.Server.Implementations.SyncPlay
/// <value>The UTC string.</value> /// <value>The UTC string.</value>
private string DateToUTCString(DateTime date) private string DateToUTCString(DateTime date)
{ {
return date.ToUniversalTime().ToString("o"); return date.ToUniversalTime().ToString("o", CultureInfo.InvariantCulture);
} }
/// <summary> /// <summary>
@ -94,23 +98,23 @@ namespace Emby.Server.Implementations.SyncPlay
/// <param name="from">The current session.</param> /// <param name="from">The current session.</param>
/// <param name="type">The filtering type.</param> /// <param name="type">The filtering type.</param>
/// <value>The array of sessions matching the filter.</value> /// <value>The array of sessions matching the filter.</value>
private SessionInfo[] FilterSessions(SessionInfo from, BroadcastType type) private IEnumerable<SessionInfo> FilterSessions(SessionInfo from, BroadcastType type)
{ {
switch (type) switch (type)
{ {
case BroadcastType.CurrentSession: case BroadcastType.CurrentSession:
return new SessionInfo[] { from }; return new SessionInfo[] { from };
case BroadcastType.AllGroup: case BroadcastType.AllGroup:
return _group.Participants.Values.Select( return _group.Participants.Values
session => session.Session).ToArray(); .Select(session => session.Session);
case BroadcastType.AllExceptCurrentSession: case BroadcastType.AllExceptCurrentSession:
return _group.Participants.Values.Select( return _group.Participants.Values
session => session.Session).Where( .Select(session => session.Session)
session => !session.Id.Equals(from.Id)).ToArray(); .Where(session => !session.Id.Equals(from.Id, StringComparison.Ordinal));
case BroadcastType.AllReady: case BroadcastType.AllReady:
return _group.Participants.Values.Where( return _group.Participants.Values
session => !session.IsBuffering).Select( .Where(session => !session.IsBuffering)
session => session.Session).ToArray(); .Select(session => session.Session);
default: default:
return Array.Empty<SessionInfo>(); return Array.Empty<SessionInfo>();
} }
@ -128,10 +132,9 @@ namespace Emby.Server.Implementations.SyncPlay
{ {
IEnumerable<Task> GetTasks() IEnumerable<Task> GetTasks()
{ {
SessionInfo[] sessions = FilterSessions(from, type); foreach (var session in FilterSessions(from, type))
foreach (var session in sessions)
{ {
yield return _sessionManager.SendSyncPlayGroupUpdate(session.Id.ToString(), message, cancellationToken); yield return _sessionManager.SendSyncPlayGroupUpdate(session.Id, message, cancellationToken);
} }
} }
@ -150,10 +153,9 @@ namespace Emby.Server.Implementations.SyncPlay
{ {
IEnumerable<Task> GetTasks() IEnumerable<Task> GetTasks()
{ {
SessionInfo[] sessions = FilterSessions(from, type); foreach (var session in FilterSessions(from, type))
foreach (var session in sessions)
{ {
yield return _sessionManager.SendSyncPlayCommand(session.Id.ToString(), message, cancellationToken); yield return _sessionManager.SendSyncPlayCommand(session.Id, message, cancellationToken);
} }
} }
@ -236,9 +238,11 @@ namespace Emby.Server.Implementations.SyncPlay
} }
else else
{ {
var playRequest = new PlayRequest(); var playRequest = new PlayRequest
playRequest.ItemIds = new Guid[] { _group.PlayingItem.Id }; {
playRequest.StartPositionTicks = _group.PositionTicks; ItemIds = new Guid[] { _group.PlayingItem.Id },
StartPositionTicks = _group.PositionTicks
};
var update = NewSyncPlayGroupUpdate(GroupUpdateType.PrepareSession, playRequest); var update = NewSyncPlayGroupUpdate(GroupUpdateType.PrepareSession, playRequest);
SendGroupUpdate(session, BroadcastType.CurrentSession, update, cancellationToken); SendGroupUpdate(session, BroadcastType.CurrentSession, update, cancellationToken);
} }