aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.ci/azure-pipelines.yml2
-rw-r--r--.github/ISSUE_TEMPLATE/enhancement-request.md20
-rw-r--r--.github/ISSUE_TEMPLATE/feature_request.md14
-rw-r--r--.github/stale.yml22
-rw-r--r--Dockerfile6
-rw-r--r--Dockerfile.arm6
-rw-r--r--Dockerfile.arm646
-rw-r--r--Emby.Dlna/Didl/DidlBuilder.cs30
-rw-r--r--Emby.Dlna/Profiles/DishHopperJoeyProfile.cs2
-rw-r--r--Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml2
-rw-r--r--Emby.Server.Implementations/Emby.Server.Implementations.csproj1
-rw-r--r--Emby.Server.Implementations/HttpServer/FileWriter.cs2
-rw-r--r--Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs69
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs27
-rw-r--r--Emby.Server.Implementations/Localization/Core/da.json8
-rw-r--r--Emby.Server.Implementations/Localization/Core/hu.json4
-rw-r--r--Emby.Server.Implementations/Localization/Core/pl.json28
-rw-r--r--Emby.Server.Implementations/Localization/Core/pt-BR.json14
-rw-r--r--Emby.Server.Implementations/Net/UdpSocket.cs1
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs167
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs94
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs2008
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs129
-rw-r--r--Emby.Server.Implementations/Networking/IPNetwork/LICENSE.txt24
-rw-r--r--Emby.Server.Implementations/Networking/NetworkManager.cs2
-rw-r--r--MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs8
-rw-r--r--MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs6
-rw-r--r--MediaBrowser.Model/Net/MimeTypes.cs376
-rw-r--r--MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs5
-rw-r--r--README.md1
30 files changed, 232 insertions, 2852 deletions
diff --git a/.ci/azure-pipelines.yml b/.ci/azure-pipelines.yml
index efd69680e..46db0d9fe 100644
--- a/.ci/azure-pipelines.yml
+++ b/.ci/azure-pipelines.yml
@@ -190,7 +190,7 @@ jobs:
- task: CmdLine@2
displayName: Execute ABI compatibility check tool
inputs:
- script: 'dotnet tools/CompatibilityCheckerCoreCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName)'
+ script: 'dotnet tools/CompatibilityCheckerCoreCLI.dll current-release/$(AssemblyFileName) new-release/$(AssemblyFileName) --azure-pipelines'
workingDirectory: $(System.ArtifactsDirectory) # Optional
#failOnStderr: false # Optional
diff --git a/.github/ISSUE_TEMPLATE/enhancement-request.md b/.github/ISSUE_TEMPLATE/enhancement-request.md
deleted file mode 100644
index a655b60f5..000000000
--- a/.github/ISSUE_TEMPLATE/enhancement-request.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-name: Enhancement request
-about: Suggest an modification to an existing feature
-title: ''
-labels: enhancement
-assignees: ''
-
----
-
-**Is your feature request related to a problem? Please describe.**
-<!-- A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] -->
-
-**Describe the solution you'd like**
-<!-- A clear and concise description of what you want to happen. -->
-
-**Describe alternatives you've considered**
-<!-- A clear and concise description of any alternative solutions or features you've considered. -->
-
-**Additional context**
-<!-- Add any other context or screenshots about the feature request here. -->
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
deleted file mode 100644
index 3cbc8cbb9..000000000
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ /dev/null
@@ -1,14 +0,0 @@
----
-name: Feature request
-about: Suggest a new feature
-title: ''
-labels: feature
-assignees: ''
-
----
-
-**Describe the feature you'd like**
-<!-- A clear and concise description of what you want to happen. -->
-
-**Additional context**
-<!-- Add any other context or screenshots about the feature request here. -->
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 000000000..ce9fb01a1
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,22 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 90
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 14
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - regression
+ - security
+ - dotnet-3.0-future
+ - roadmap
+ - future
+ - feature
+ - enhancement
+# Label to use when marking an issue as stale
+staleLabel: stale
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ Issues go stale after 90d of inactivity. Mark the issue as fresh by adding a comment or commit. Stale issues close after an additional 14d of inactivity.
+ If this issue is safe to close now please do so.
+ If you have any questions you can reach us on [Matrix or Social Media](https://jellyfin.readthedocs.io/en/latest/getting-help/).
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
diff --git a/Dockerfile b/Dockerfile
index 057d4b041..f8e6fec31 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -21,10 +21,10 @@ RUN apt-get update \
COPY --from=ffmpeg / /
COPY --from=builder /jellyfin /jellyfin
-ARG JELLYFIN_WEB_VERSION=10.3.7
-RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
+ARG JELLYFIN_WEB_VERSION=v10.3.7
+RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
- && mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
+ && mv jellyfin-web-* /jellyfin/jellyfin-web
EXPOSE 8096
VOLUME /cache /config /media
diff --git a/Dockerfile.arm b/Dockerfile.arm
index dad4da1f1..651bdeff4 100644
--- a/Dockerfile.arm
+++ b/Dockerfile.arm
@@ -26,10 +26,10 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
-ARG JELLYFIN_WEB_VERSION=10.3.7
-RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
+ARG JELLYFIN_WEB_VERSION=v10.3.7
+RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
- && mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
+ && mv jellyfin-web-* /jellyfin/jellyfin-web
EXPOSE 8096
VOLUME /cache /config /media
diff --git a/Dockerfile.arm64 b/Dockerfile.arm64
index 5d4e86bff..f6bd81e4c 100644
--- a/Dockerfile.arm64
+++ b/Dockerfile.arm64
@@ -26,10 +26,10 @@ RUN apt-get update \
&& chmod 777 /cache /config /media
COPY --from=builder /jellyfin /jellyfin
-ARG JELLYFIN_WEB_VERSION=10.3.7
-RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/v${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
+ARG JELLYFIN_WEB_VERSION=v10.3.7
+RUN curl -L https://github.com/jellyfin/jellyfin-web/archive/${JELLYFIN_WEB_VERSION}.tar.gz | tar zxf - \
&& rm -rf /jellyfin/jellyfin-web \
- && mv jellyfin-web-${JELLYFIN_WEB_VERSION} /jellyfin/jellyfin-web
+ && mv jellyfin-web-* /jellyfin/jellyfin-web
EXPOSE 8096
VOLUME /cache /config /media
diff --git a/Emby.Dlna/Didl/DidlBuilder.cs b/Emby.Dlna/Didl/DidlBuilder.cs
index 992a50e67..a21aff9f9 100644
--- a/Emby.Dlna/Didl/DidlBuilder.cs
+++ b/Emby.Dlna/Didl/DidlBuilder.cs
@@ -181,19 +181,6 @@ namespace Emby.Dlna.Didl
writer.WriteFullEndElement();
}
- private string GetMimeType(string input)
- {
- var mime = MimeTypes.GetMimeType(input);
-
- // TODO: Instead of being hard-coded here, this should probably be moved into all of the existing profiles
- if (string.Equals(mime, "video/mp2t", StringComparison.OrdinalIgnoreCase))
- {
- mime = "video/mpeg";
- }
-
- return mime;
- }
-
private void AddVideoResource(DlnaOptions options, XmlWriter writer, BaseItem video, string deviceId, Filter filter, StreamInfo streamInfo = null)
{
if (streamInfo == null)
@@ -384,7 +371,7 @@ namespace Emby.Dlna.Didl
var filename = url.Substring(0, url.IndexOf('?'));
var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
- ? GetMimeType(filename)
+ ? MimeTypes.GetMimeType(filename)
: mediaProfile.MimeType;
writer.WriteAttributeString("protocolInfo", string.Format(
@@ -520,7 +507,7 @@ namespace Emby.Dlna.Didl
var filename = url.Substring(0, url.IndexOf('?'));
var mimeType = mediaProfile == null || string.IsNullOrEmpty(mediaProfile.MimeType)
- ? GetMimeType(filename)
+ ? MimeTypes.GetMimeType(filename)
: mediaProfile.MimeType;
var contentFeatures = new ContentFeatureBuilder(_profile).BuildAudioHeader(streamInfo.Container,
@@ -545,17 +532,10 @@ namespace Emby.Dlna.Didl
}
public static bool IsIdRoot(string id)
- {
- if (string.IsNullOrWhiteSpace(id)
+ => string.IsNullOrWhiteSpace(id)
|| string.Equals(id, "0", StringComparison.OrdinalIgnoreCase)
// Samsung sometimes uses 1 as root
- || string.Equals(id, "1", StringComparison.OrdinalIgnoreCase))
- {
- return true;
- }
-
- return false;
- }
+ || string.Equals(id, "1", StringComparison.OrdinalIgnoreCase);
public void WriteFolderElement(XmlWriter writer, BaseItem folder, StubType? stubType, BaseItem context, int childCount, Filter filter, string requestedId = null)
{
@@ -971,7 +951,7 @@ namespace Emby.Dlna.Didl
writer.WriteAttributeString("protocolInfo", string.Format(
"http-get:*:{0}:{1}",
- GetMimeType("file." + format),
+ MimeTypes.GetMimeType("file." + format),
contentFeatures
));
diff --git a/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs b/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
index d501cce0d..8d8ab41ca 100644
--- a/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
+++ b/Emby.Dlna/Profiles/DishHopperJoeyProfile.cs
@@ -9,7 +9,7 @@ namespace Emby.Dlna.Profiles
{
Name = "Dish Hopper-Joey";
- ProtocolInfo = "http-get:*:video/mp2t:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*";
+ ProtocolInfo = "http-get:*:video/mp2t:*,http-get:*:video/mpeg:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*";
Identification = new DeviceIdentification
{
diff --git a/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
index 5ff497560..5b299577e 100644
--- a/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
+++ b/Emby.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
@@ -28,7 +28,7 @@
<MaxStaticBitrate>140000000</MaxStaticBitrate>
<MusicStreamingTranscodingBitrate>192000</MusicStreamingTranscodingBitrate>
<MaxStaticMusicBitrate xsi:nil="true" />
- <ProtocolInfo>http-get:*:video/mp2t:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*</ProtocolInfo>
+ <ProtocolInfo>http-get:*:video/mp2t:http-get:*:video/mpeg:*,http-get:*:video/MP1S:*,http-get:*:video/mpeg2:*,http-get:*:video/mp4:*,http-get:*:video/x-matroska:*,http-get:*:audio/mpeg:*,http-get:*:audio/mpeg3:*,http-get:*:audio/mp3:*,http-get:*:audio/mp4:*,http-get:*:audio/mp4a-latm:*,http-get:*:image/jpeg:*</ProtocolInfo>
<TimelineOffsetSeconds>0</TimelineOffsetSeconds>
<RequiresPlainVideoItems>false</RequiresPlainVideoItems>
<RequiresPlainFolders>false</RequiresPlainFolders>
diff --git a/Emby.Server.Implementations/Emby.Server.Implementations.csproj b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
index 49015a07e..abbaef26b 100644
--- a/Emby.Server.Implementations/Emby.Server.Implementations.csproj
+++ b/Emby.Server.Implementations/Emby.Server.Implementations.csproj
@@ -20,6 +20,7 @@
</ItemGroup>
<ItemGroup>
+ <PackageReference Include="IPNetwork2" Version="2.4.0.126" />
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Hosting.Server.Abstractions" Version="2.2.0" />
diff --git a/Emby.Server.Implementations/HttpServer/FileWriter.cs b/Emby.Server.Implementations/HttpServer/FileWriter.cs
index c6b7d31a8..ec41cc0a9 100644
--- a/Emby.Server.Implementations/HttpServer/FileWriter.cs
+++ b/Emby.Server.Implementations/HttpServer/FileWriter.cs
@@ -106,7 +106,7 @@ namespace Emby.Server.Implementations.HttpServer
var rangeString = $"bytes {RangeStart}-{RangeEnd}/{TotalContentLength}";
Headers[HeaderNames.ContentRange] = rangeString;
- Logger.LogInformation("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
+ Logger.LogDebug("Setting range response values for {0}. RangeRequest: {1} Content-Length: {2}, Content-Range: {3}", Path, RangeHeader, lengthString, rangeString);
}
/// <summary>
diff --git a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
index a70077163..f1ae2fc9c 100644
--- a/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
+++ b/Emby.Server.Implementations/Library/CoreResolutionIgnoreRule.cs
@@ -5,7 +5,6 @@ using System.Text.RegularExpressions;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
-using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library
@@ -17,12 +16,10 @@ namespace Emby.Server.Implementations.Library
{
private readonly ILibraryManager _libraryManager;
- private bool _ignoreDotPrefix;
-
/// <summary>
- /// Any folder named in this list will be ignored - can be added to at runtime for extensibility
+ /// Any folder named in this list will be ignored
/// </summary>
- public static readonly string[] IgnoreFolders =
+ private static readonly string[] _ignoreFolders =
{
"metadata",
"ps3_update",
@@ -43,25 +40,14 @@ namespace Emby.Server.Implementations.Library
"$RECYCLE.BIN",
"System Volume Information",
".grab",
-
- // macos
- ".AppleDouble"
-
};
public CoreResolutionIgnoreRule(ILibraryManager libraryManager)
{
_libraryManager = libraryManager;
-
- _ignoreDotPrefix = Environment.OSVersion.Platform != PlatformID.Win32NT;
}
- /// <summary>
- /// Shoulds the ignore.
- /// </summary>
- /// <param name="fileInfo">The file information.</param>
- /// <param name="parent">The parent.</param>
- /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns>
+ /// <inheritdoc />
public bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem parent)
{
// Don't ignore top level folders
@@ -73,46 +59,17 @@ namespace Emby.Server.Implementations.Library
var filename = fileInfo.Name;
var path = fileInfo.FullName;
- // Handle mac .DS_Store
- // https://github.com/MediaBrowser/MediaBrowser/issues/427
- if (_ignoreDotPrefix)
+ // Ignore hidden files on UNIX
+ if (Environment.OSVersion.Platform != PlatformID.Win32NT
+ && filename[0] == '.')
{
- if (filename.IndexOf('.') == 0)
- {
- return true;
- }
+ return true;
}
- // Ignore hidden files and folders
- //if (fileInfo.IsHidden)
- //{
- // if (parent == null)
- // {
- // var parentFolderName = Path.GetFileName(_fileSystem.GetDirectoryName(path));
-
- // if (string.Equals(parentFolderName, BaseItem.ThemeSongsFolderName, StringComparison.OrdinalIgnoreCase))
- // {
- // return false;
- // }
- // if (string.Equals(parentFolderName, BaseItem.ThemeVideosFolderName, StringComparison.OrdinalIgnoreCase))
- // {
- // return false;
- // }
- // }
-
- // // Sometimes these are marked hidden
- // if (_fileSystem.IsRootPath(path))
- // {
- // return false;
- // }
-
- // return true;
- //}
-
if (fileInfo.IsDirectory)
{
// Ignore any folders in our list
- if (IgnoreFolders.Contains(filename, StringComparer.OrdinalIgnoreCase))
+ if (_ignoreFolders.Contains(filename, StringComparer.OrdinalIgnoreCase))
{
return true;
}
@@ -120,8 +77,9 @@ namespace Emby.Server.Implementations.Library
if (parent != null)
{
// Ignore trailer folders but allow it at the collection level
- if (string.Equals(filename, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase) &&
- !(parent is AggregateFolder) && !(parent is UserRootFolder))
+ if (string.Equals(filename, BaseItem.TrailerFolderName, StringComparison.OrdinalIgnoreCase)
+ && !(parent is AggregateFolder)
+ && !(parent is UserRootFolder))
{
return true;
}
@@ -142,14 +100,15 @@ namespace Emby.Server.Implementations.Library
if (parent != null)
{
// Don't resolve these into audio files
- if (string.Equals(Path.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename) && _libraryManager.IsAudioFile(filename))
+ if (string.Equals(Path.GetFileNameWithoutExtension(filename), BaseItem.ThemeSongFilename)
+ && _libraryManager.IsAudioFile(filename))
{
return true;
}
}
// Ignore samples
- Match m = Regex.Match(filename,@"\bsample\b",RegexOptions.IgnoreCase);
+ Match m = Regex.Match(filename, @"\bsample\b", RegexOptions.IgnoreCase);
return m.Success;
}
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 47c3e71d7..1b63b00a3 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -12,7 +12,6 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.Library.Resolvers.Movies
@@ -28,7 +27,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
/// <value>The priority.</value>
public override ResolverPriority Priority => ResolverPriority.Third;
- public MultiItemResolverResult ResolveMultiple(Folder parent,
+ public MultiItemResolverResult ResolveMultiple(
+ Folder parent,
List<FileSystemMetadata> files,
string collectionType,
IDirectoryService directoryService)
@@ -46,7 +46,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return result;
}
- private MultiItemResolverResult ResolveMultipleInternal(Folder parent,
+ private MultiItemResolverResult ResolveMultipleInternal(
+ Folder parent,
List<FileSystemMetadata> files,
string collectionType,
IDirectoryService directoryService)
@@ -91,7 +92,13 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
return null;
}
- private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemMetadata> fileSystemEntries, IDirectoryService directoryService, bool suppportMultiEditions, string collectionType, bool parseName)
+ private MultiItemResolverResult ResolveVideos<T>(
+ Folder parent,
+ IEnumerable<FileSystemMetadata> fileSystemEntries,
+ IDirectoryService directoryService,
+ bool suppportMultiEditions,
+ string collectionType,
+ bool parseName)
where T : Video, new()
{
var files = new List<FileSystemMetadata>();
@@ -104,8 +111,8 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
// This is a hack but currently no better way to resolve a sometimes ambiguous situation
if (string.IsNullOrEmpty(collectionType))
{
- if (string.Equals(child.Name, "tvshow.nfo", StringComparison.OrdinalIgnoreCase) ||
- string.Equals(child.Name, "season.nfo", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(child.Name, "tvshow.nfo", StringComparison.OrdinalIgnoreCase)
+ || string.Equals(child.Name, "season.nfo", StringComparison.OrdinalIgnoreCase))
{
return null;
}
@@ -115,11 +122,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
{
leftOver.Add(child);
}
- else if (IsIgnored(child.Name))
- {
-
- }
- else
+ else if (!IsIgnored(child.Name))
{
files.Add(child);
}
@@ -168,7 +171,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
private static bool IsIgnored(string filename)
{
// Ignore samples
- Match m = Regex.Match(filename,@"\bsample\b",RegexOptions.IgnoreCase);
+ Match m = Regex.Match(filename, @"\bsample\b", RegexOptions.IgnoreCase);
return m.Success;
}
diff --git a/Emby.Server.Implementations/Localization/Core/da.json b/Emby.Server.Implementations/Localization/Core/da.json
index cb8f4576a..b01abafa1 100644
--- a/Emby.Server.Implementations/Localization/Core/da.json
+++ b/Emby.Server.Implementations/Localization/Core/da.json
@@ -18,11 +18,11 @@
"HeaderAlbumArtists": "Albumkunstnere",
"HeaderCameraUploads": "Kamera Uploads",
"HeaderContinueWatching": "Fortsæt Afspilning",
- "HeaderFavoriteAlbums": "Favoritalbum",
+ "HeaderFavoriteAlbums": "Favoritalbummer",
"HeaderFavoriteArtists": "Favoritkunstnere",
- "HeaderFavoriteEpisodes": "Favorit-afsnit",
- "HeaderFavoriteShows": "Favorit-serier",
- "HeaderFavoriteSongs": "Favorit-sange",
+ "HeaderFavoriteEpisodes": "Favoritepisoder",
+ "HeaderFavoriteShows": "Favoritserier",
+ "HeaderFavoriteSongs": "Favoritsange",
"HeaderLiveTV": "Live TV",
"HeaderNextUp": "Næste",
"HeaderRecordingGroups": "Optagelsesgrupper",
diff --git a/Emby.Server.Implementations/Localization/Core/hu.json b/Emby.Server.Implementations/Localization/Core/hu.json
index c0f988abe..a2fc126a2 100644
--- a/Emby.Server.Implementations/Localization/Core/hu.json
+++ b/Emby.Server.Implementations/Localization/Core/hu.json
@@ -19,9 +19,9 @@
"HeaderCameraUploads": "Kamera feltöltések",
"HeaderContinueWatching": "Folyamatban lévő filmek",
"HeaderFavoriteAlbums": "Kedvenc Albumok",
- "HeaderFavoriteArtists": "Kedvenc Művészek",
+ "HeaderFavoriteArtists": "Kedvenc Előadók",
"HeaderFavoriteEpisodes": "Kedvenc Epizódok",
- "HeaderFavoriteShows": "Kedvenc Műsorok",
+ "HeaderFavoriteShows": "Kedvenc Sorozatok",
"HeaderFavoriteSongs": "Kedvenc Dalok",
"HeaderLiveTV": "Élő TV",
"HeaderNextUp": "Következik",
diff --git a/Emby.Server.Implementations/Localization/Core/pl.json b/Emby.Server.Implementations/Localization/Core/pl.json
index 92b12409d..e72f1a262 100644
--- a/Emby.Server.Implementations/Localization/Core/pl.json
+++ b/Emby.Server.Implementations/Localization/Core/pl.json
@@ -18,11 +18,11 @@
"HeaderAlbumArtists": "Wykonawcy albumów",
"HeaderCameraUploads": "Przekazane obrazy",
"HeaderContinueWatching": "Kontynuuj odtwarzanie",
- "HeaderFavoriteAlbums": "Albumy ulubione",
- "HeaderFavoriteArtists": "Wykonawcy ulubieni",
- "HeaderFavoriteEpisodes": "Odcinki ulubione",
- "HeaderFavoriteShows": "Seriale ulubione",
- "HeaderFavoriteSongs": "Utwory ulubione",
+ "HeaderFavoriteAlbums": "Ulubione albumy",
+ "HeaderFavoriteArtists": "Ulubieni wykonawcy",
+ "HeaderFavoriteEpisodes": "Ulubione odcinki",
+ "HeaderFavoriteShows": "Ulubione seriale",
+ "HeaderFavoriteSongs": "Ulubione utwory",
"HeaderLiveTV": "Telewizja",
"HeaderNextUp": "Do obejrzenia",
"HeaderRecordingGroups": "Grupy nagrań",
@@ -41,26 +41,26 @@
"Movies": "Filmy",
"Music": "Muzyka",
"MusicVideos": "Teledyski",
- "NameInstallFailed": "Instalacja {0} nieudana.",
+ "NameInstallFailed": "Instalacja {0} nieudana",
"NameSeasonNumber": "Sezon {0}",
- "NameSeasonUnknown": "Sezon nieznany",
+ "NameSeasonUnknown": "Nieznany sezon",
"NewVersionIsAvailable": "Nowa wersja serwera Jellyfin jest dostępna do pobrania.",
"NotificationOptionApplicationUpdateAvailable": "Dostępna aktualizacja aplikacji",
- "NotificationOptionApplicationUpdateInstalled": "Zainstalowano aktualizację aplikacji",
+ "NotificationOptionApplicationUpdateInstalled": "Zaktualizowano aplikację",
"NotificationOptionAudioPlayback": "Rozpoczęto odtwarzanie muzyki",
"NotificationOptionAudioPlaybackStopped": "Odtwarzane dźwięku zatrzymane",
- "NotificationOptionCameraImageUploaded": "Przekazano obraz z urządzenia mobilnego",
- "NotificationOptionInstallationFailed": "Niepowodzenie instalacji",
+ "NotificationOptionCameraImageUploaded": "Przekazano obraz z urządzenia przenośnego",
+ "NotificationOptionInstallationFailed": "Nieudana instalacja",
"NotificationOptionNewLibraryContent": "Dodano nową zawartość",
"NotificationOptionPluginError": "Awaria wtyczki",
"NotificationOptionPluginInstalled": "Zainstalowano wtyczkę",
"NotificationOptionPluginUninstalled": "Odinstalowano wtyczkę",
- "NotificationOptionPluginUpdateInstalled": "Zainstalowano aktualizację wtyczki",
+ "NotificationOptionPluginUpdateInstalled": "Zaktualizowano wtyczkę",
"NotificationOptionServerRestartRequired": "Wymagane ponowne uruchomienie serwera",
"NotificationOptionTaskFailed": "Awaria zaplanowanego zadania",
"NotificationOptionUserLockedOut": "Użytkownik zablokowany",
"NotificationOptionVideoPlayback": "Rozpoczęto odtwarzanie wideo",
- "NotificationOptionVideoPlaybackStopped": "Odtwarzanie wideo zatrzymane",
+ "NotificationOptionVideoPlaybackStopped": "Zatrzymano odtwarzanie wideo",
"Photos": "Zdjęcia",
"Playlists": "Listy odtwarzania",
"Plugin": "Wtyczka",
@@ -73,7 +73,7 @@
"ServerNameNeedsToBeRestarted": "{0} wymaga ponownego uruchomienia",
"Shows": "Seriale",
"Songs": "Utwory",
- "StartupEmbyServerIsLoading": "Twa wczytywanie serwera Jellyfin. Spróbuj ponownie za chwilę.",
+ "StartupEmbyServerIsLoading": "Trwa wczytywanie serwera Jellyfin. Spróbuj ponownie za chwilę.",
"SubtitleDownloadFailureForItem": "Pobieranie napisów dla {0} zakończone niepowodzeniem",
"SubtitleDownloadFailureFromForItem": "Nieudane pobieranie napisów z {0} dla {1}",
"SubtitlesDownloadedForItem": "Pobrano napisy dla {0}",
@@ -91,7 +91,7 @@
"UserPolicyUpdatedWithName": "Zmieniono zasady użytkowania dla {0}",
"UserStartedPlayingItemWithValues": "{0} odtwarza {1} na {2}",
"UserStoppedPlayingItemWithValues": "{0} zakończył odtwarzanie {1} na {2}",
- "ValueHasBeenAddedToLibrary": "{0} został dodany to biblioteki mediów",
+ "ValueHasBeenAddedToLibrary": "{0} został dodany do biblioteki mediów",
"ValueSpecialEpisodeName": "Specjalne - {0}",
"VersionNumber": "Wersja {0}"
}
diff --git a/Emby.Server.Implementations/Localization/Core/pt-BR.json b/Emby.Server.Implementations/Localization/Core/pt-BR.json
index 5d68416e9..c4ce16dc8 100644
--- a/Emby.Server.Implementations/Localization/Core/pt-BR.json
+++ b/Emby.Server.Implementations/Localization/Core/pt-BR.json
@@ -21,8 +21,8 @@
"HeaderFavoriteAlbums": "Álbuns Favoritos",
"HeaderFavoriteArtists": "Artistas Favoritos",
"HeaderFavoriteEpisodes": "Episódios Favoritos",
- "HeaderFavoriteShows": "Shows Favoritos",
- "HeaderFavoriteSongs": "Musicas Favoritas",
+ "HeaderFavoriteShows": "Séries Favoritas",
+ "HeaderFavoriteSongs": "Músicas Favoritas",
"HeaderLiveTV": "TV ao Vivo",
"HeaderNextUp": "Próximos",
"HeaderRecordingGroups": "Grupos de Gravação",
@@ -32,19 +32,19 @@
"ItemRemovedWithName": "{0} foi removido da biblioteca",
"LabelIpAddressValue": "Endereço IP: {0}",
"LabelRunningTimeValue": "Tempo de execução: {0}",
- "Latest": "Recente",
- "MessageApplicationUpdated": "O servidor Jellyfin foi atualizado",
- "MessageApplicationUpdatedTo": "O Servidor Jellyfin foi atualizado para {0}",
+ "Latest": "Recentes",
+ "MessageApplicationUpdated": "Servidor Jellyfin atualizado",
+ "MessageApplicationUpdatedTo": "Servidor Jellyfin atualizado para {0}",
"MessageNamedServerConfigurationUpdatedWithValue": "A seção {0} da configuração do servidor foi atualizada",
"MessageServerConfigurationUpdated": "A configuração do servidor foi atualizada",
"MixedContent": "Conteúdo misto",
"Movies": "Filmes",
"Music": "Música",
- "MusicVideos": "Vídeos musicais",
+ "MusicVideos": "Clipes",
"NameInstallFailed": "A instalação de {0} falhou",
"NameSeasonNumber": "Temporada {0}",
"NameSeasonUnknown": "Temporada Desconhecida",
- "NewVersionIsAvailable": "Uma nova versão do servidor Jellyfin está disponível para download.",
+ "NewVersionIsAvailable": "Uma nova versão do Servidor Jellyfin está disponível para download.",
"NotificationOptionApplicationUpdateAvailable": "Atualização de aplicativo disponível",
"NotificationOptionApplicationUpdateInstalled": "Atualização de aplicativo instalada",
"NotificationOptionAudioPlayback": "Reprodução de áudio iniciada",
diff --git a/Emby.Server.Implementations/Net/UdpSocket.cs b/Emby.Server.Implementations/Net/UdpSocket.cs
index 2908ee9af..dde4a2a34 100644
--- a/Emby.Server.Implementations/Net/UdpSocket.cs
+++ b/Emby.Server.Implementations/Net/UdpSocket.cs
@@ -3,7 +3,6 @@ using System.Net;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
-using Emby.Server.Implementations.Networking;
using MediaBrowser.Model.Net;
namespace Emby.Server.Implementations.Net
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs b/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
deleted file mode 100644
index e4e944839..000000000
--- a/Emby.Server.Implementations/Networking/IPNetwork/BigIntegerExt.cs
+++ /dev/null
@@ -1,167 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Numerics;
-using System.Text;
-
-namespace Emby.Server.Implementations.Networking.IPNetwork
-{
- /// <summary>
- /// Extension methods to convert <see cref="BigInteger"/>
- /// instances to hexadecimal, octal, and binary strings.
- /// </summary>
- public static class BigIntegerExtensions
- {
- /// <summary>
- /// Converts a <see cref="BigInteger"/> to a binary string.
- /// </summary>
- /// <param name="bigint">A <see cref="BigInteger"/>.</param>
- /// <returns>
- /// A <see cref="string"/> containing a binary
- /// representation of the supplied <see cref="BigInteger"/>.
- /// </returns>
- public static string ToBinaryString(this BigInteger bigint)
- {
- var bytes = bigint.ToByteArray();
- var idx = bytes.Length - 1;
-
- // Create a StringBuilder having appropriate capacity.
- var base2 = new StringBuilder(bytes.Length * 8);
-
- // Convert first byte to binary.
- var binary = Convert.ToString(bytes[idx], 2);
-
- // Ensure leading zero exists if value is positive.
- if (binary[0] != '0' && bigint.Sign == 1)
- {
- base2.Append('0');
- }
-
- // Append binary string to StringBuilder.
- base2.Append(binary);
-
- // Convert remaining bytes adding leading zeros.
- for (idx--; idx >= 0; idx--)
- {
- base2.Append(Convert.ToString(bytes[idx], 2).PadLeft(8, '0'));
- }
-
- return base2.ToString();
- }
-
- /// <summary>
- /// Converts a <see cref="BigInteger"/> to a hexadecimal string.
- /// </summary>
- /// <param name="bigint">A <see cref="BigInteger"/>.</param>
- /// <returns>
- /// A <see cref="string"/> containing a hexadecimal
- /// representation of the supplied <see cref="BigInteger"/>.
- /// </returns>
- public static string ToHexadecimalString(this BigInteger bigint)
- {
- return bigint.ToString("X");
- }
-
- /// <summary>
- /// Converts a <see cref="BigInteger"/> to a octal string.
- /// </summary>
- /// <param name="bigint">A <see cref="BigInteger"/>.</param>
- /// <returns>
- /// A <see cref="string"/> containing an octal
- /// representation of the supplied <see cref="BigInteger"/>.
- /// </returns>
- public static string ToOctalString(this BigInteger bigint)
- {
- var bytes = bigint.ToByteArray();
- var idx = bytes.Length - 1;
-
- // Create a StringBuilder having appropriate capacity.
- var base8 = new StringBuilder(((bytes.Length / 3) + 1) * 8);
-
- // Calculate how many bytes are extra when byte array is split
- // into three-byte (24-bit) chunks.
- var extra = bytes.Length % 3;
-
- // If no bytes are extra, use three bytes for first chunk.
- if (extra == 0)
- {
- extra = 3;
- }
-
- // Convert first chunk (24-bits) to integer value.
- int int24 = 0;
- for (; extra != 0; extra--)
- {
- int24 <<= 8;
- int24 += bytes[idx--];
- }
-
- // Convert 24-bit integer to octal without adding leading zeros.
- var octal = Convert.ToString(int24, 8);
-
- // Ensure leading zero exists if value is positive.
- if (octal[0] != '0')
- {
- if (bigint.Sign == 1)
- {
- base8.Append('0');
- }
- }
-
- // Append first converted chunk to StringBuilder.
- base8.Append(octal);
-
- // Convert remaining 24-bit chunks, adding leading zeros.
- for (; idx >= 0; idx -= 3)
- {
- int24 = (bytes[idx] << 16) + (bytes[idx - 1] << 8) + bytes[idx - 2];
- base8.Append(Convert.ToString(int24, 8).PadLeft(8, '0'));
- }
-
- return base8.ToString();
- }
-
- /// <summary>
- ///
- /// Reverse a Positive BigInteger ONLY
- /// Bitwise ~ operator
- ///
- /// Input : FF FF FF FF
- /// Width : 4
- /// Result : 00 00 00 00
- ///
- ///
- /// Input : 00 00 00 00
- /// Width : 4
- /// Result : FF FF FF FF
- ///
- /// Input : FF FF FF FF
- /// Width : 8
- /// Result : FF FF FF FF 00 00 00 00
- ///
- ///
- /// Input : 00 00 00 00
- /// Width : 8
- /// Result : FF FF FF FF FF FF FF FF
- ///
- /// </summary>
- /// <param name="input"></param>
- /// <param name="width"></param>
- /// <returns></returns>
- public static BigInteger PositiveReverse(this BigInteger input, int width)
- {
-
- var result = new List<byte>();
- var bytes = input.ToByteArray();
- var work = new byte[width];
- Array.Copy(bytes, 0, work, 0, bytes.Length - 1); // Length -1 : positive BigInteger
-
- for (int i = 0; i < work.Length; i++)
- {
- result.Add((byte)(~work[i]));
- }
- result.Add(0); // positive BigInteger
- return new BigInteger(result.ToArray());
-
- }
- }
-}
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs
deleted file mode 100644
index a0c5f73af..000000000
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPAddressCollection.cs
+++ /dev/null
@@ -1,94 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Net;
-using System.Numerics;
-
-namespace Emby.Server.Implementations.Networking.IPNetwork
-{
- public class IPAddressCollection : IEnumerable<IPAddress>, IEnumerator<IPAddress>
- {
-
- private IPNetwork _ipnetwork;
- private BigInteger _enumerator;
-
- internal IPAddressCollection(IPNetwork ipnetwork)
- {
- this._ipnetwork = ipnetwork;
- this._enumerator = -1;
- }
-
-
- #region Count, Array, Enumerator
-
- public BigInteger Count => this._ipnetwork.Total;
-
- public IPAddress this[BigInteger i]
- {
- get
- {
- if (i >= this.Count)
- {
- throw new ArgumentOutOfRangeException(nameof(i));
- }
- byte width = this._ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? (byte)32 : (byte)128;
- var ipn = this._ipnetwork.Subnet(width);
- return ipn[i].Network;
- }
- }
-
- #endregion
-
- #region IEnumerable Members
-
- IEnumerator<IPAddress> IEnumerable<IPAddress>.GetEnumerator()
- {
- return this;
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return this;
- }
-
- #region IEnumerator<IPNetwork> Members
-
- public IPAddress Current => this[this._enumerator];
-
- #endregion
-
- #region IDisposable Members
-
- public void Dispose()
- {
- // nothing to dispose
- return;
- }
-
- #endregion
-
- #region IEnumerator Members
-
- object IEnumerator.Current => this.Current;
-
- public bool MoveNext()
- {
- this._enumerator++;
- if (this._enumerator >= this.Count)
- {
- return false;
- }
- return true;
-
- }
-
- public void Reset()
- {
- this._enumerator = -1;
- }
-
- #endregion
-
- #endregion
- }
-}
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
deleted file mode 100644
index d6de61c0c..000000000
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPNetwork.cs
+++ /dev/null
@@ -1,2008 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Net;
-using System.Net.Sockets;
-using System.Numerics;
-using System.Text.RegularExpressions;
-
-namespace Emby.Server.Implementations.Networking.IPNetwork
-{
- /// <summary>
- /// IP Network utility class.
- /// Use IPNetwork.Parse to create instances.
- /// </summary>
- public class IPNetwork : IComparable<IPNetwork>
- {
-
- #region properties
-
- //private uint _network;
- private BigInteger _ipaddress;
- private AddressFamily _family;
- //private uint _netmask;
- //private uint _broadcast;
- //private uint _firstUsable;
- //private uint _lastUsable;
- //private uint _usable;
- private byte _cidr;
-
- #endregion
-
- #region accessors
-
- private BigInteger _network
- {
- get
- {
- var uintNetwork = this._ipaddress & this._netmask;
- return uintNetwork;
- }
- }
-
- /// <summary>
- /// Network address
- /// </summary>
- public IPAddress Network => IPNetwork.ToIPAddress(this._network, this._family);
-
- /// <summary>
- /// Address Family
- /// </summary>
- public AddressFamily AddressFamily => this._family;
-
- private BigInteger _netmask => IPNetwork.ToUint(this._cidr, this._family);
-
- /// <summary>
- /// Netmask
- /// </summary>
- public IPAddress Netmask => IPNetwork.ToIPAddress(this._netmask, this._family);
-
- private BigInteger _broadcast
- {
- get
- {
-
- int width = this._family == System.Net.Sockets.AddressFamily.InterNetwork ? 4 : 16;
- var uintBroadcast = this._network + this._netmask.PositiveReverse(width);
- return uintBroadcast;
- }
- }
-
- /// <summary>
- /// Broadcast address
- /// </summary>
- public IPAddress Broadcast
- {
- get
- {
- if (this._family == System.Net.Sockets.AddressFamily.InterNetworkV6)
- {
- return null;
- }
- return IPNetwork.ToIPAddress(this._broadcast, this._family);
- }
- }
-
- /// <summary>
- /// First usable IP adress in Network
- /// </summary>
- public IPAddress FirstUsable
- {
- get
- {
- var fisrt = this._family == System.Net.Sockets.AddressFamily.InterNetworkV6
- ? this._network
- : (this.Usable <= 0) ? this._network : this._network + 1;
- return IPNetwork.ToIPAddress(fisrt, this._family);
- }
- }
-
- /// <summary>
- /// Last usable IP adress in Network
- /// </summary>
- public IPAddress LastUsable
- {
- get
- {
- var last = this._family == System.Net.Sockets.AddressFamily.InterNetworkV6
- ? this._broadcast
- : (this.Usable <= 0) ? this._network : this._broadcast - 1;
- return IPNetwork.ToIPAddress(last, this._family);
- }
- }
-
- /// <summary>
- /// Number of usable IP adress in Network
- /// </summary>
- public BigInteger Usable
- {
- get
- {
-
- if (this._family == System.Net.Sockets.AddressFamily.InterNetworkV6)
- {
- return this.Total;
- }
- byte[] mask = new byte[] { 0xff, 0xff, 0xff, 0xff, 0x00 };
- var bmask = new BigInteger(mask);
- var usableIps = (_cidr > 30) ? 0 : ((bmask >> _cidr) - 1);
- return usableIps;
- }
- }
-
- /// <summary>
- /// Number of IP adress in Network
- /// </summary>
- public BigInteger Total
- {
- get
- {
-
- int max = this._family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
- var count = BigInteger.Pow(2, (max - _cidr));
- return count;
- }
- }
-
-
- /// <summary>
- /// The CIDR netmask notation
- /// </summary>
- public byte Cidr => this._cidr;
-
- #endregion
-
- #region constructor
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
-
- IPNetwork(BigInteger ipaddress, AddressFamily family, byte cidr)
- {
-
- int maxCidr = family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
- if (cidr > maxCidr)
- {
- throw new ArgumentOutOfRangeException(nameof(cidr));
- }
-
- this._ipaddress = ipaddress;
- this._family = family;
- this._cidr = cidr;
-
- }
-
- #endregion
-
- #region parsers
-
- /// <summary>
- /// 192.168.168.100 - 255.255.255.0
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static IPNetwork Parse(string ipaddress, string netmask)
- {
-
- IPNetwork ipnetwork = null;
- IPNetwork.InternalParse(false, ipaddress, netmask, out ipnetwork);
- return ipnetwork;
- }
-
- /// <summary>
- /// 192.168.168.100/24
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static IPNetwork Parse(string ipaddress, byte cidr)
- {
-
- IPNetwork ipnetwork = null;
- IPNetwork.InternalParse(false, ipaddress, cidr, out ipnetwork);
- return ipnetwork;
-
- }
-
- /// <summary>
- /// 192.168.168.100 255.255.255.0
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static IPNetwork Parse(IPAddress ipaddress, IPAddress netmask)
- {
-
- IPNetwork ipnetwork = null;
- IPNetwork.InternalParse(false, ipaddress, netmask, out ipnetwork);
- return ipnetwork;
-
- }
-
- /// <summary>
- /// 192.168.0.1/24
- /// 192.168.0.1 255.255.255.0
- ///
- /// Network : 192.168.0.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.0.1
- /// End : 192.168.0.254
- /// Broadcast : 192.168.0.255
- /// </summary>
- /// <param name="network"></param>
- /// <returns></returns>
- public static IPNetwork Parse(string network)
- {
-
- IPNetwork ipnetwork = null;
- IPNetwork.InternalParse(false, network, out ipnetwork);
- return ipnetwork;
-
- }
-
- #endregion
-
- #region TryParse
-
-
-
- /// <summary>
- /// 192.168.168.100 - 255.255.255.0
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static bool TryParse(string ipaddress, string netmask, out IPNetwork ipnetwork)
- {
-
- IPNetwork ipnetwork2 = null;
- IPNetwork.InternalParse(true, ipaddress, netmask, out ipnetwork2);
- bool parsed = (ipnetwork2 != null);
- ipnetwork = ipnetwork2;
- return parsed;
-
- }
-
-
-
- /// <summary>
- /// 192.168.168.100/24
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static bool TryParse(string ipaddress, byte cidr, out IPNetwork ipnetwork)
- {
-
- IPNetwork ipnetwork2 = null;
- IPNetwork.InternalParse(true, ipaddress, cidr, out ipnetwork2);
- bool parsed = (ipnetwork2 != null);
- ipnetwork = ipnetwork2;
- return parsed;
-
- }
-
- /// <summary>
- /// 192.168.0.1/24
- /// 192.168.0.1 255.255.255.0
- ///
- /// Network : 192.168.0.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.0.1
- /// End : 192.168.0.254
- /// Broadcast : 192.168.0.255
- /// </summary>
- /// <param name="network"></param>
- /// <param name="ipnetwork"></param>
- /// <returns></returns>
- public static bool TryParse(string network, out IPNetwork ipnetwork)
- {
-
- IPNetwork ipnetwork2 = null;
- IPNetwork.InternalParse(true, network, out ipnetwork2);
- bool parsed = (ipnetwork2 != null);
- ipnetwork = ipnetwork2;
- return parsed;
-
- }
-
- /// <summary>
- /// 192.168.0.1/24
- /// 192.168.0.1 255.255.255.0
- ///
- /// Network : 192.168.0.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.0.1
- /// End : 192.168.0.254
- /// Broadcast : 192.168.0.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="netmask"></param>
- /// <param name="ipnetwork"></param>
- /// <returns></returns>
- public static bool TryParse(IPAddress ipaddress, IPAddress netmask, out IPNetwork ipnetwork)
- {
-
- IPNetwork ipnetwork2 = null;
- IPNetwork.InternalParse(true, ipaddress, netmask, out ipnetwork2);
- bool parsed = (ipnetwork2 != null);
- ipnetwork = ipnetwork2;
- return parsed;
-
- }
-
-
- #endregion
-
- #region InternalParse
-
- /// <summary>
- /// 192.168.168.100 - 255.255.255.0
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="netmask"></param>
- /// <returns></returns>
- private static void InternalParse(bool tryParse, string ipaddress, string netmask, out IPNetwork ipnetwork)
- {
-
- if (string.IsNullOrEmpty(ipaddress))
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(ipaddress));
- }
- ipnetwork = null;
- return;
- }
-
- if (string.IsNullOrEmpty(netmask))
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(netmask));
- }
- ipnetwork = null;
- return;
- }
-
- IPAddress ip = null;
- bool ipaddressParsed = IPAddress.TryParse(ipaddress, out ip);
- if (ipaddressParsed == false)
- {
- if (tryParse == false)
- {
- throw new ArgumentException("ipaddress");
- }
- ipnetwork = null;
- return;
- }
-
- IPAddress mask = null;
- bool netmaskParsed = IPAddress.TryParse(netmask, out mask);
- if (netmaskParsed == false)
- {
- if (tryParse == false)
- {
- throw new ArgumentException("netmask");
- }
- ipnetwork = null;
- return;
- }
-
- IPNetwork.InternalParse(tryParse, ip, mask, out ipnetwork);
- }
-
- private static void InternalParse(bool tryParse, string network, out IPNetwork ipnetwork)
- {
-
- if (string.IsNullOrEmpty(network))
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(network));
- }
- ipnetwork = null;
- return;
- }
-
- network = Regex.Replace(network, @"[^0-9a-fA-F\.\/\s\:]+", "");
- network = Regex.Replace(network, @"\s{2,}", " ");
- network = network.Trim();
- string[] args = network.Split(new char[] { ' ', '/' });
- byte cidr = 0;
- if (args.Length == 1)
- {
-
- if (IPNetwork.TryGuessCidr(args[0], out cidr))
- {
- IPNetwork.InternalParse(tryParse, args[0], cidr, out ipnetwork);
- return;
- }
-
- if (tryParse == false)
- {
- throw new ArgumentException("network");
- }
- ipnetwork = null;
- return;
- }
-
- if (byte.TryParse(args[1], out cidr))
- {
- IPNetwork.InternalParse(tryParse, args[0], cidr, out ipnetwork);
- return;
- }
-
- IPNetwork.InternalParse(tryParse, args[0], args[1], out ipnetwork);
- return;
-
- }
-
-
-
- /// <summary>
- /// 192.168.168.100 255.255.255.0
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="netmask"></param>
- /// <returns></returns>
- private static void InternalParse(bool tryParse, IPAddress ipaddress, IPAddress netmask, out IPNetwork ipnetwork)
- {
-
- if (ipaddress == null)
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(ipaddress));
- }
- ipnetwork = null;
- return;
- }
-
- if (netmask == null)
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(netmask));
- }
- ipnetwork = null;
- return;
- }
-
- var uintIpAddress = IPNetwork.ToBigInteger(ipaddress);
- bool parsed = IPNetwork.TryToCidr(netmask, out var cidr2);
- if (parsed == false)
- {
- if (tryParse == false)
- {
- throw new ArgumentException("netmask");
- }
- ipnetwork = null;
- return;
- }
- byte cidr = (byte)cidr2;
-
- var ipnet = new IPNetwork(uintIpAddress, ipaddress.AddressFamily, cidr);
- ipnetwork = ipnet;
-
- return;
- }
-
-
-
- /// <summary>
- /// 192.168.168.100/24
- ///
- /// Network : 192.168.168.0
- /// Netmask : 255.255.255.0
- /// Cidr : 24
- /// Start : 192.168.168.1
- /// End : 192.168.168.254
- /// Broadcast : 192.168.168.255
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <param name="cidr"></param>
- /// <returns></returns>
- private static void InternalParse(bool tryParse, string ipaddress, byte cidr, out IPNetwork ipnetwork)
- {
-
- if (string.IsNullOrEmpty(ipaddress))
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(ipaddress));
- }
- ipnetwork = null;
- return;
- }
-
-
- IPAddress ip = null;
- bool ipaddressParsed = IPAddress.TryParse(ipaddress, out ip);
- if (ipaddressParsed == false)
- {
- if (tryParse == false)
- {
- throw new ArgumentException("ipaddress");
- }
- ipnetwork = null;
- return;
- }
-
- IPAddress mask = null;
- bool parsedNetmask = IPNetwork.TryToNetmask(cidr, ip.AddressFamily, out mask);
- if (parsedNetmask == false)
- {
- if (tryParse == false)
- {
- throw new ArgumentException("cidr");
- }
- ipnetwork = null;
- return;
- }
-
-
- IPNetwork.InternalParse(tryParse, ip, mask, out ipnetwork);
- }
-
- #endregion
-
- #region converters
-
- #region ToUint
-
- /// <summary>
- /// Convert an ipadress to decimal
- /// 0.0.0.0 -> 0
- /// 0.0.1.0 -> 256
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <returns></returns>
- public static BigInteger ToBigInteger(IPAddress ipaddress)
- {
- IPNetwork.InternalToBigInteger(false, ipaddress, out var uintIpAddress);
- return (BigInteger)uintIpAddress;
-
- }
-
- /// <summary>
- /// Convert an ipadress to decimal
- /// 0.0.0.0 -> 0
- /// 0.0.1.0 -> 256
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <returns></returns>
- public static bool TryToBigInteger(IPAddress ipaddress, out BigInteger? uintIpAddress)
- {
- IPNetwork.InternalToBigInteger(true, ipaddress, out var uintIpAddress2);
- bool parsed = (uintIpAddress2 != null);
- uintIpAddress = uintIpAddress2;
- return parsed;
- }
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static void InternalToBigInteger(bool tryParse, IPAddress ipaddress, out BigInteger? uintIpAddress)
- {
-
- if (ipaddress == null)
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(ipaddress));
- }
- uintIpAddress = null;
- return;
- }
-
- byte[] bytes = ipaddress.GetAddressBytes();
- /// 20180217 lduchosal
- /// code impossible to reach, GetAddressBytes returns either 4 or 16 bytes length addresses
- /// if (bytes.Length != 4 && bytes.Length != 16) {
- /// if (tryParse == false) {
- /// throw new ArgumentException("bytes");
- /// }
- /// uintIpAddress = null;
- /// return;
- /// }
-
- Array.Reverse(bytes);
- var unsigned = new List<byte>(bytes);
- unsigned.Add(0);
- uintIpAddress = new BigInteger(unsigned.ToArray());
- return;
- }
-
-
- /// <summary>
- /// Convert a cidr to BigInteger netmask
- /// </summary>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static BigInteger ToUint(byte cidr, AddressFamily family)
- {
- IPNetwork.InternalToBigInteger(false, cidr, family, out var uintNetmask);
- return (BigInteger)uintNetmask;
- }
-
-
- /// <summary>
- /// Convert a cidr to uint netmask
- /// </summary>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static bool TryToUint(byte cidr, AddressFamily family, out BigInteger? uintNetmask)
- {
- IPNetwork.InternalToBigInteger(true, cidr, family, out var uintNetmask2);
- bool parsed = (uintNetmask2 != null);
- uintNetmask = uintNetmask2;
- return parsed;
- }
-
- /// <summary>
- /// Convert a cidr to uint netmask
- /// </summary>
- /// <param name="cidr"></param>
- /// <returns></returns>
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static void InternalToBigInteger(bool tryParse, byte cidr, AddressFamily family, out BigInteger? uintNetmask)
- {
-
- if (family == AddressFamily.InterNetwork && cidr > 32)
- {
- if (tryParse == false)
- {
- throw new ArgumentOutOfRangeException(nameof(cidr));
- }
- uintNetmask = null;
- return;
- }
-
- if (family == AddressFamily.InterNetworkV6 && cidr > 128)
- {
- if (tryParse == false)
- {
- throw new ArgumentOutOfRangeException(nameof(cidr));
- }
- uintNetmask = null;
- return;
- }
-
- if (family != AddressFamily.InterNetwork
- && family != AddressFamily.InterNetworkV6)
- {
- if (tryParse == false)
- {
- throw new NotSupportedException(family.ToString());
- }
- uintNetmask = null;
- return;
- }
-
- if (family == AddressFamily.InterNetwork)
- {
-
- uintNetmask = cidr == 0 ? 0 : 0xffffffff << (32 - cidr);
- return;
- }
-
- var mask = new BigInteger(new byte[] {
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0x00
- });
-
- var masked = cidr == 0 ? 0 : mask << (128 - cidr);
- byte[] m = masked.ToByteArray();
- byte[] bmask = new byte[17];
- int copy = m.Length > 16 ? 16 : m.Length;
- Array.Copy(m, 0, bmask, 0, copy);
- uintNetmask = new BigInteger(bmask);
-
-
- }
-
- #endregion
-
- #region ToCidr
-
- /// <summary>
- /// Convert netmask to CIDR
- /// 255.255.255.0 -> 24
- /// 255.255.0.0 -> 16
- /// 255.0.0.0 -> 8
- /// </summary>
- /// <param name="netmask"></param>
- /// <returns></returns>
- private static void InternalToCidr(bool tryParse, BigInteger netmask, AddressFamily family, out byte? cidr)
- {
-
- if (!IPNetwork.InternalValidNetmask(netmask, family))
- {
- if (tryParse == false)
- {
- throw new ArgumentException("netmask");
- }
- cidr = null;
- return;
- }
-
- byte cidr2 = IPNetwork.BitsSet(netmask, family);
- cidr = cidr2;
- return;
-
- }
- /// <summary>
- /// Convert netmask to CIDR
- /// 255.255.255.0 -> 24
- /// 255.255.0.0 -> 16
- /// 255.0.0.0 -> 8
- /// </summary>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static byte ToCidr(IPAddress netmask)
- {
- IPNetwork.InternalToCidr(false, netmask, out var cidr);
- return (byte)cidr;
- }
-
- /// <summary>
- /// Convert netmask to CIDR
- /// 255.255.255.0 -> 24
- /// 255.255.0.0 -> 16
- /// 255.0.0.0 -> 8
- /// </summary>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static bool TryToCidr(IPAddress netmask, out byte? cidr)
- {
- IPNetwork.InternalToCidr(true, netmask, out var cidr2);
- bool parsed = (cidr2 != null);
- cidr = cidr2;
- return parsed;
- }
-
- private static void InternalToCidr(bool tryParse, IPAddress netmask, out byte? cidr)
- {
-
- if (netmask == null)
- {
- if (tryParse == false)
- {
- throw new ArgumentNullException(nameof(netmask));
- }
- cidr = null;
- return;
- }
-
- bool parsed = IPNetwork.TryToBigInteger(netmask, out var uintNetmask2);
-
- /// 20180217 lduchosal
- /// impossible to reach code.
- /// if (parsed == false) {
- /// if (tryParse == false) {
- /// throw new ArgumentException("netmask");
- /// }
- /// cidr = null;
- /// return;
- /// }
- var uintNetmask = (BigInteger)uintNetmask2;
-
- IPNetwork.InternalToCidr(tryParse, uintNetmask, netmask.AddressFamily, out var cidr2);
- cidr = cidr2;
-
- return;
-
- }
-
-
- #endregion
-
- #region ToNetmask
-
- /// <summary>
- /// Convert CIDR to netmask
- /// 24 -> 255.255.255.0
- /// 16 -> 255.255.0.0
- /// 8 -> 255.0.0.0
- /// </summary>
- /// <see cref="http://snipplr.com/view/15557/cidr-class-for-ipv4/"/>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static IPAddress ToNetmask(byte cidr, AddressFamily family)
- {
-
- IPAddress netmask = null;
- IPNetwork.InternalToNetmask(false, cidr, family, out netmask);
- return netmask;
- }
-
- /// <summary>
- /// Convert CIDR to netmask
- /// 24 -> 255.255.255.0
- /// 16 -> 255.255.0.0
- /// 8 -> 255.0.0.0
- /// </summary>
- /// <see cref="http://snipplr.com/view/15557/cidr-class-for-ipv4/"/>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static bool TryToNetmask(byte cidr, AddressFamily family, out IPAddress netmask)
- {
-
- IPAddress netmask2 = null;
- IPNetwork.InternalToNetmask(true, cidr, family, out netmask2);
- bool parsed = (netmask2 != null);
- netmask = netmask2;
- return parsed;
- }
-
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static void InternalToNetmask(bool tryParse, byte cidr, AddressFamily family, out IPAddress netmask)
- {
-
- if (family != AddressFamily.InterNetwork
- && family != AddressFamily.InterNetworkV6)
- {
- if (tryParse == false)
- {
- throw new ArgumentException("family");
- }
- netmask = null;
- return;
- }
-
- /// 20180217 lduchosal
- /// impossible to reach code, byte cannot be negative :
- ///
- /// if (cidr < 0) {
- /// if (tryParse == false) {
- /// throw new ArgumentOutOfRangeException("cidr");
- /// }
- /// netmask = null;
- /// return;
- /// }
-
- int maxCidr = family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
- if (cidr > maxCidr)
- {
- if (tryParse == false)
- {
- throw new ArgumentOutOfRangeException(nameof(cidr));
- }
- netmask = null;
- return;
- }
-
- var mask = IPNetwork.ToUint(cidr, family);
- var netmask2 = IPNetwork.ToIPAddress(mask, family);
- netmask = netmask2;
-
- return;
- }
-
- #endregion
-
- #endregion
-
- #region utils
-
- #region BitsSet
-
- /// <summary>
- /// Count bits set to 1 in netmask
- /// </summary>
- /// <see cref="http://stackoverflow.com/questions/109023/best-algorithm-to-count-the-number-of-set-bits-in-a-32-bit-integer"/>
- /// <param name="netmask"></param>
- /// <returns></returns>
- private static byte BitsSet(BigInteger netmask, AddressFamily family)
- {
-
- string s = netmask.ToBinaryString();
- return (byte)s.Replace("0", "")
- .ToCharArray()
- .Length;
-
- }
-
-
- /// <summary>
- /// Count bits set to 1 in netmask
- /// </summary>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static uint BitsSet(IPAddress netmask)
- {
- var uintNetmask = IPNetwork.ToBigInteger(netmask);
- uint bits = IPNetwork.BitsSet(uintNetmask, netmask.AddressFamily);
- return bits;
- }
-
- #endregion
-
- #region ValidNetmask
-
- /// <summary>
- /// return true if netmask is a valid netmask
- /// 255.255.255.0, 255.0.0.0, 255.255.240.0, ...
- /// </summary>
- /// <see cref="http://www.actionsnip.com/snippets/tomo_atlacatl/calculate-if-a-netmask-is-valid--as2-"/>
- /// <param name="netmask"></param>
- /// <returns></returns>
- public static bool ValidNetmask(IPAddress netmask)
- {
-
- if (netmask == null)
- {
- throw new ArgumentNullException(nameof(netmask));
- }
- var uintNetmask = IPNetwork.ToBigInteger(netmask);
- bool valid = IPNetwork.InternalValidNetmask(uintNetmask, netmask.AddressFamily);
- return valid;
- }
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static bool InternalValidNetmask(BigInteger netmask, AddressFamily family)
- {
-
- if (family != AddressFamily.InterNetwork
- && family != AddressFamily.InterNetworkV6)
- {
- throw new ArgumentException("family");
- }
-
- var mask = family == AddressFamily.InterNetwork
- ? new BigInteger(0x0ffffffff)
- : new BigInteger(new byte[]{
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0xff, 0xff, 0xff, 0xff,
- 0x00
- });
-
- var neg = ((~netmask) & (mask));
- bool isNetmask = ((neg + 1) & neg) == 0;
- return isNetmask;
-
- }
-
- #endregion
-
- #region ToIPAddress
-
- /// <summary>
- /// Transform a uint ipaddress into IPAddress object
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <returns></returns>
- public static IPAddress ToIPAddress(BigInteger ipaddress, AddressFamily family)
- {
-
- int width = family == AddressFamily.InterNetwork ? 4 : 16;
- byte[] bytes = ipaddress.ToByteArray();
- byte[] bytes2 = new byte[width];
- int copy = bytes.Length > width ? width : bytes.Length;
- Array.Copy(bytes, 0, bytes2, 0, copy);
- Array.Reverse(bytes2);
-
- byte[] sized = Resize(bytes2, family);
- var ip = new IPAddress(sized);
- return ip;
- }
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static byte[] Resize(byte[] bytes, AddressFamily family)
- {
-
- if (family != AddressFamily.InterNetwork
- && family != AddressFamily.InterNetworkV6)
- {
- throw new ArgumentException("family");
- }
-
- int width = family == AddressFamily.InterNetwork ? 4 : 16;
-
- if (bytes.Length > width)
- {
- throw new ArgumentException("bytes");
- }
-
- byte[] result = new byte[width];
- Array.Copy(bytes, 0, result, 0, bytes.Length);
- return result;
- }
-
- #endregion
-
- #endregion
-
- #region contains
-
- /// <summary>
- /// return true if ipaddress is contained in network
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <returns></returns>
- public bool Contains(IPAddress ipaddress)
- {
-
- if (ipaddress == null)
- {
- throw new ArgumentNullException(nameof(ipaddress));
- }
-
- if (AddressFamily != ipaddress.AddressFamily)
- {
- return false;
- }
-
- var uintNetwork = _network;
- var uintBroadcast = _broadcast;
- var uintAddress = IPNetwork.ToBigInteger(ipaddress);
-
- bool contains = (uintAddress >= uintNetwork
- && uintAddress <= uintBroadcast);
-
- return contains;
-
- }
-
- /// <summary>
- /// return true is network2 is fully contained in network
- /// </summary>
- /// <param name="network2"></param>
- /// <returns></returns>
- public bool Contains(IPNetwork network2)
- {
-
- if (network2 == null)
- {
- throw new ArgumentNullException(nameof(network2));
- }
-
- var uintNetwork = _network;
- var uintBroadcast = _broadcast;
-
- var uintFirst = network2._network;
- var uintLast = network2._broadcast;
-
- bool contains = (uintFirst >= uintNetwork
- && uintLast <= uintBroadcast);
-
- return contains;
- }
-
- #endregion
-
- #region overlap
-
- /// <summary>
- /// return true is network2 overlap network
- /// </summary>
- /// <param name="network2"></param>
- /// <returns></returns>
- public bool Overlap(IPNetwork network2)
- {
-
- if (network2 == null)
- {
- throw new ArgumentNullException(nameof(network2));
- }
-
- var uintNetwork = _network;
- var uintBroadcast = _broadcast;
-
- var uintFirst = network2._network;
- var uintLast = network2._broadcast;
-
- bool overlap =
- (uintFirst >= uintNetwork && uintFirst <= uintBroadcast)
- || (uintLast >= uintNetwork && uintLast <= uintBroadcast)
- || (uintFirst <= uintNetwork && uintLast >= uintBroadcast)
- || (uintFirst >= uintNetwork && uintLast <= uintBroadcast);
-
- return overlap;
- }
-
- #endregion
-
- #region ToString
-
- public override string ToString()
- {
- return string.Format("{0}/{1}", this.Network, this.Cidr);
- }
-
- #endregion
-
- #region IANA block
-
- private static readonly Lazy<IPNetwork> _iana_ablock_reserved = new Lazy<IPNetwork>(() => IPNetwork.Parse("10.0.0.0/8"));
- private static readonly Lazy<IPNetwork> _iana_bblock_reserved = new Lazy<IPNetwork>(() => IPNetwork.Parse("172.16.0.0/12"));
- private static readonly Lazy<IPNetwork> _iana_cblock_reserved = new Lazy<IPNetwork>(() => IPNetwork.Parse("192.168.0.0/16"));
-
- /// <summary>
- /// 10.0.0.0/8
- /// </summary>
- /// <returns></returns>
- public static IPNetwork IANA_ABLK_RESERVED1 => _iana_ablock_reserved.Value;
-
- /// <summary>
- /// 172.12.0.0/12
- /// </summary>
- /// <returns></returns>
- public static IPNetwork IANA_BBLK_RESERVED1 => _iana_bblock_reserved.Value;
-
- /// <summary>
- /// 192.168.0.0/16
- /// </summary>
- /// <returns></returns>
- public static IPNetwork IANA_CBLK_RESERVED1 => _iana_cblock_reserved.Value;
-
- /// <summary>
- /// return true if ipaddress is contained in
- /// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1
- /// </summary>
- /// <param name="ipaddress"></param>
- /// <returns></returns>
- public static bool IsIANAReserved(IPAddress ipaddress)
- {
-
- if (ipaddress == null)
- {
- throw new ArgumentNullException(nameof(ipaddress));
- }
-
- return IPNetwork.IANA_ABLK_RESERVED1.Contains(ipaddress)
- || IPNetwork.IANA_BBLK_RESERVED1.Contains(ipaddress)
- || IPNetwork.IANA_CBLK_RESERVED1.Contains(ipaddress);
- }
-
- /// <summary>
- /// return true if ipnetwork is contained in
- /// IANA_ABLK_RESERVED1, IANA_BBLK_RESERVED1, IANA_CBLK_RESERVED1
- /// </summary>
- /// <returns></returns>
- public bool IsIANAReserved()
- {
- return IPNetwork.IANA_ABLK_RESERVED1.Contains(this)
- || IPNetwork.IANA_BBLK_RESERVED1.Contains(this)
- || IPNetwork.IANA_CBLK_RESERVED1.Contains(this);
- }
-
- #endregion
-
- #region Subnet
-
- /// <summary>
- /// Subnet a network into multiple nets of cidr mask
- /// Subnet 192.168.0.0/24 into cidr 25 gives 192.168.0.0/25, 192.168.0.128/25
- /// Subnet 10.0.0.0/8 into cidr 9 gives 10.0.0.0/9, 10.128.0.0/9
- /// </summary>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public IPNetworkCollection Subnet(byte cidr)
- {
- IPNetworkCollection ipnetworkCollection = null;
- IPNetwork.InternalSubnet(false, this, cidr, out ipnetworkCollection);
- return ipnetworkCollection;
- }
-
- /// <summary>
- /// Subnet a network into multiple nets of cidr mask
- /// Subnet 192.168.0.0/24 into cidr 25 gives 192.168.0.0/25, 192.168.0.128/25
- /// Subnet 10.0.0.0/8 into cidr 9 gives 10.0.0.0/9, 10.128.0.0/9
- /// </summary>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public bool TrySubnet(byte cidr, out IPNetworkCollection ipnetworkCollection)
- {
- IPNetworkCollection inc = null;
- IPNetwork.InternalSubnet(true, this, cidr, out inc);
- if (inc == null)
- {
- ipnetworkCollection = null;
- return false;
- }
-
- ipnetworkCollection = inc;
- return true;
- }
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static void InternalSubnet(bool trySubnet, IPNetwork network, byte cidr, out IPNetworkCollection ipnetworkCollection)
- {
-
- if (network == null)
- {
- if (trySubnet == false)
- {
- throw new ArgumentNullException(nameof(network));
- }
- ipnetworkCollection = null;
- return;
- }
-
- int maxCidr = network._family == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
- if (cidr > maxCidr)
- {
- if (trySubnet == false)
- {
- throw new ArgumentOutOfRangeException(nameof(cidr));
- }
- ipnetworkCollection = null;
- return;
- }
-
- if (cidr < network.Cidr)
- {
- if (trySubnet == false)
- {
- throw new ArgumentException("cidr");
- }
- ipnetworkCollection = null;
- return;
- }
-
- ipnetworkCollection = new IPNetworkCollection(network, cidr);
- return;
- }
-
-
-
- #endregion
-
- #region Supernet
-
- /// <summary>
- /// Supernet two consecutive cidr equal subnet into a single one
- /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
- /// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
- /// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24
- /// </summary>
- /// <param name="network2"></param>
- /// <returns></returns>
- public IPNetwork Supernet(IPNetwork network2)
- {
- IPNetwork supernet = null;
- IPNetwork.InternalSupernet(false, this, network2, out supernet);
- return supernet;
- }
-
- /// <summary>
- /// Try to supernet two consecutive cidr equal subnet into a single one
- /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
- /// 10.1.0.0/16 + 10.0.0.0/16 = 10.0.0.0/15
- /// 192.168.0.0/24 + 192.168.0.0/25 = 192.168.0.0/24
- /// </summary>
- /// <param name="network2"></param>
- /// <returns></returns>
- public bool TrySupernet(IPNetwork network2, out IPNetwork supernet)
- {
-
- IPNetwork outSupernet = null;
- IPNetwork.InternalSupernet(true, this, network2, out outSupernet);
- bool parsed = (outSupernet != null);
- supernet = outSupernet;
- return parsed;
- }
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static void InternalSupernet(bool trySupernet, IPNetwork network1, IPNetwork network2, out IPNetwork supernet)
- {
-
- if (network1 == null)
- {
- if (trySupernet == false)
- {
- throw new ArgumentNullException(nameof(network1));
- }
- supernet = null;
- return;
- }
-
- if (network2 == null)
- {
- if (trySupernet == false)
- {
- throw new ArgumentNullException(nameof(network2));
- }
- supernet = null;
- return;
- }
-
-
- if (network1.Contains(network2))
- {
- supernet = new IPNetwork(network1._network, network1._family, network1.Cidr);
- return;
- }
-
- if (network2.Contains(network1))
- {
- supernet = new IPNetwork(network2._network, network2._family, network2.Cidr);
- return;
- }
-
- if (network1._cidr != network2._cidr)
- {
- if (trySupernet == false)
- {
- throw new ArgumentException("cidr");
- }
- supernet = null;
- return;
- }
-
- var first = (network1._network < network2._network) ? network1 : network2;
- var last = (network1._network > network2._network) ? network1 : network2;
-
- /// Starting from here :
- /// network1 and network2 have the same cidr,
- /// network1 does not contain network2,
- /// network2 does not contain network1,
- /// first is the lower subnet
- /// last is the higher subnet
-
-
- if ((first._broadcast + 1) != last._network)
- {
- if (trySupernet == false)
- {
- throw new ArgumentOutOfRangeException(nameof(trySupernet), "TrySupernet was false while the first and last networks are not adjacent.");
- }
- supernet = null;
- return;
- }
-
- var uintSupernet = first._network;
- byte cidrSupernet = (byte)(first._cidr - 1);
-
- var networkSupernet = new IPNetwork(uintSupernet, first._family, cidrSupernet);
- if (networkSupernet._network != first._network)
- {
- if (trySupernet == false)
- {
- throw new ArgumentException("network");
- }
- supernet = null;
- return;
- }
- supernet = networkSupernet;
- return;
- }
-
- #endregion
-
- #region GetHashCode
-
- public override int GetHashCode()
- {
- return string.Format("{0}|{1}|{2}",
- this._ipaddress.GetHashCode(),
- this._network.GetHashCode(),
- this._cidr.GetHashCode()).GetHashCode();
- }
-
- #endregion
-
- #region SupernetArray
-
- /// <summary>
- /// Supernet a list of subnet
- /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
- /// 192.168.0.0/24 + 192.168.1.0/24 + 192.168.2.0/24 + 192.168.3.0/24 = 192.168.0.0/22
- /// </summary>
- /// <param name="ipnetworks">The IP networks</param>
- /// <returns></returns>
- public static IPNetwork[] Supernet(IPNetwork[] ipnetworks)
- {
- InternalSupernet(false, ipnetworks, out var supernet);
- return supernet;
- }
-
- /// <summary>
- /// Supernet a list of subnet
- /// 192.168.0.0/24 + 192.168.1.0/24 = 192.168.0.0/23
- /// 192.168.0.0/24 + 192.168.1.0/24 + 192.168.2.0/24 + 192.168.3.0/24 = 192.168.0.0/22
- /// </summary>
- /// <param name="ipnetworks"></param>
- /// <param name="supernet"></param>
- /// <returns></returns>
- public static bool TrySupernet(IPNetwork[] ipnetworks, out IPNetwork[] supernet)
- {
- bool supernetted = InternalSupernet(true, ipnetworks, out supernet);
- return supernetted;
-
- }
-
-#if TRAVISCI
- public
-#else
- internal
-#endif
- static bool InternalSupernet(bool trySupernet, IPNetwork[] ipnetworks, out IPNetwork[] supernet)
- {
-
- if (ipnetworks == null)
- {
- if (trySupernet == false)
- {
- throw new ArgumentNullException(nameof(ipnetworks));
- }
- supernet = null;
- return false;
- }
-
- if (ipnetworks.Length <= 0)
- {
- supernet = new IPNetwork[0];
- return true;
- }
-
- var supernetted = new List<IPNetwork>();
- var ipns = IPNetwork.Array2List(ipnetworks);
- var current = IPNetwork.List2Stack(ipns);
- int previousCount = 0;
- int currentCount = current.Count;
-
- while (previousCount != currentCount)
- {
-
- supernetted.Clear();
- while (current.Count > 1)
- {
- var ipn1 = current.Pop();
- var ipn2 = current.Peek();
-
- IPNetwork outNetwork = null;
- bool success = ipn1.TrySupernet(ipn2, out outNetwork);
- if (success)
- {
- current.Pop();
- current.Push(outNetwork);
- }
- else
- {
- supernetted.Add(ipn1);
- }
- }
- if (current.Count == 1)
- {
- supernetted.Add(current.Pop());
- }
-
- previousCount = currentCount;
- currentCount = supernetted.Count;
- current = IPNetwork.List2Stack(supernetted);
-
- }
- supernet = supernetted.ToArray();
- return true;
- }
-
- private static Stack<IPNetwork> List2Stack(List<IPNetwork> list)
- {
- var stack = new Stack<IPNetwork>();
- list.ForEach(new Action<IPNetwork>(
- delegate (IPNetwork ipn)
- {
- stack.Push(ipn);
- }
- ));
- return stack;
- }
-
- private static List<IPNetwork> Array2List(IPNetwork[] array)
- {
- var ipns = new List<IPNetwork>();
- ipns.AddRange(array);
- IPNetwork.RemoveNull(ipns);
- ipns.Sort(new Comparison<IPNetwork>(
- delegate (IPNetwork ipn1, IPNetwork ipn2)
- {
- int networkCompare = ipn1._network.CompareTo(ipn2._network);
- if (networkCompare == 0)
- {
- int cidrCompare = ipn1._cidr.CompareTo(ipn2._cidr);
- return cidrCompare;
- }
- return networkCompare;
- }
- ));
- ipns.Reverse();
-
- return ipns;
- }
-
- private static void RemoveNull(List<IPNetwork> ipns)
- {
- ipns.RemoveAll(new Predicate<IPNetwork>(
- delegate (IPNetwork ipn)
- {
- if (ipn == null)
- {
- return true;
- }
- return false;
- }
- ));
-
- }
-
- #endregion
-
- #region WideSubnet
-
- public static IPNetwork WideSubnet(string start, string end)
- {
-
- if (string.IsNullOrEmpty(start))
- {
- throw new ArgumentNullException(nameof(start));
- }
-
- if (string.IsNullOrEmpty(end))
- {
- throw new ArgumentNullException(nameof(end));
- }
-
- if (!IPAddress.TryParse(start, out var startIP))
- {
- throw new ArgumentException("start");
- }
-
- if (!IPAddress.TryParse(end, out var endIP))
- {
- throw new ArgumentException("end");
- }
-
- if (startIP.AddressFamily != endIP.AddressFamily)
- {
- throw new NotSupportedException("MixedAddressFamily");
- }
-
- var ipnetwork = new IPNetwork(0, startIP.AddressFamily, 0);
- for (byte cidr = 32; cidr >= 0; cidr--)
- {
- var wideSubnet = IPNetwork.Parse(start, cidr);
- if (wideSubnet.Contains(endIP))
- {
- ipnetwork = wideSubnet;
- break;
- }
- }
- return ipnetwork;
-
- }
-
- public static bool TryWideSubnet(IPNetwork[] ipnetworks, out IPNetwork ipnetwork)
- {
- IPNetwork ipn = null;
- IPNetwork.InternalWideSubnet(true, ipnetworks, out ipn);
- if (ipn == null)
- {
- ipnetwork = null;
- return false;
- }
- ipnetwork = ipn;
- return true;
- }
-
- public static IPNetwork WideSubnet(IPNetwork[] ipnetworks)
- {
- IPNetwork ipn = null;
- IPNetwork.InternalWideSubnet(false, ipnetworks, out ipn);
- return ipn;
- }
-
- internal static void InternalWideSubnet(bool tryWide, IPNetwork[] ipnetworks, out IPNetwork ipnetwork)
- {
-
- if (ipnetworks == null)
- {
- if (tryWide == false)
- {
- throw new ArgumentNullException(nameof(ipnetworks));
- }
- ipnetwork = null;
- return;
- }
-
-
- IPNetwork[] nnin = Array.FindAll(ipnetworks, new Predicate<IPNetwork>(
- delegate (IPNetwork ipnet)
- {
- return ipnet != null;
- }
- ));
-
- if (nnin.Length <= 0)
- {
- if (tryWide == false)
- {
- throw new ArgumentException("ipnetworks");
- }
- ipnetwork = null;
- return;
- }
-
- if (nnin.Length == 1)
- {
- var ipn0 = nnin[0];
- ipnetwork = ipn0;
- return;
- }
-
- Array.Sort(nnin);
- var nnin0 = nnin[0];
- var uintNnin0 = nnin0._ipaddress;
-
- var nninX = nnin[nnin.Length - 1];
- var ipaddressX = nninX.Broadcast;
-
- var family = ipnetworks[0]._family;
- foreach (var ipnx in ipnetworks)
- {
- if (ipnx._family != family)
- {
- throw new ArgumentException("MixedAddressFamily");
- }
- }
-
- var ipn = new IPNetwork(0, family, 0);
- for (byte cidr = nnin0._cidr; cidr >= 0; cidr--)
- {
- var wideSubnet = new IPNetwork(uintNnin0, family, cidr);
- if (wideSubnet.Contains(ipaddressX))
- {
- ipn = wideSubnet;
- break;
- }
- }
-
- ipnetwork = ipn;
- return;
- }
-
- #endregion
-
- #region Print
-
- /// <summary>
- /// Print an ipnetwork in a clear representation string
- /// </summary>
- /// <returns></returns>
- public string Print()
- {
-
- var sw = new StringWriter();
-
- sw.WriteLine("IPNetwork : {0}", ToString());
- sw.WriteLine("Network : {0}", Network);
- sw.WriteLine("Netmask : {0}", Netmask);
- sw.WriteLine("Cidr : {0}", Cidr);
- sw.WriteLine("Broadcast : {0}", Broadcast);
- sw.WriteLine("FirstUsable : {0}", FirstUsable);
- sw.WriteLine("LastUsable : {0}", LastUsable);
- sw.WriteLine("Usable : {0}", Usable);
-
- return sw.ToString();
- }
-
- #endregion
-
- #region TryGuessCidr
-
- /// <summary>
- ///
- /// Class Leading bits Default netmask
- /// A (CIDR /8) 00 255.0.0.0
- /// A (CIDR /8) 01 255.0.0.0
- /// B (CIDR /16) 10 255.255.0.0
- /// C (CIDR /24) 11 255.255.255.0
- ///
- /// </summary>
- /// <param name="ip"></param>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static bool TryGuessCidr(string ip, out byte cidr)
- {
-
- IPAddress ipaddress = null;
- bool parsed = IPAddress.TryParse(string.Format("{0}", ip), out ipaddress);
- if (parsed == false)
- {
- cidr = 0;
- return false;
- }
-
- if (ipaddress.AddressFamily == AddressFamily.InterNetworkV6)
- {
- cidr = 64;
- return true;
- }
- var uintIPAddress = IPNetwork.ToBigInteger(ipaddress);
- uintIPAddress = uintIPAddress >> 29;
- if (uintIPAddress <= 3)
- {
- cidr = 8;
- return true;
- }
- else if (uintIPAddress <= 5)
- {
- cidr = 16;
- return true;
- }
- else if (uintIPAddress <= 6)
- {
- cidr = 24;
- return true;
- }
-
- cidr = 0;
- return false;
-
- }
-
- /// <summary>
- /// Try to parse cidr. Have to be >= 0 and <= 32 or 128
- /// </summary>
- /// <param name="sidr"></param>
- /// <param name="cidr"></param>
- /// <returns></returns>
- public static bool TryParseCidr(string sidr, AddressFamily family, out byte? cidr)
- {
-
- byte b = 0;
- if (!byte.TryParse(sidr, out b))
- {
- cidr = null;
- return false;
- }
-
- IPAddress netmask = null;
- if (!IPNetwork.TryToNetmask(b, family, out netmask))
- {
- cidr = null;
- return false;
- }
-
- cidr = b;
- return true;
- }
-
- #endregion
-
- #region ListIPAddress
-
- public IPAddressCollection ListIPAddress()
- {
- return new IPAddressCollection(this);
- }
-
- #endregion
-
- /**
- * Need a better way to do it
- *
-#region TrySubstractNetwork
-
- public static bool TrySubstractNetwork(IPNetwork[] ipnetworks, IPNetwork substract, out IEnumerable<IPNetwork> result) {
-
- if (ipnetworks == null) {
- result = null;
- return false;
- }
- if (ipnetworks.Length <= 0) {
- result = null;
- return false;
- }
- if (substract == null) {
- result = null;
- return false;
- }
- var results = new List<IPNetwork>();
- foreach (var ipn in ipnetworks) {
- if (!Overlap(ipn, substract)) {
- results.Add(ipn);
- continue;
- }
-
- var collection = ipn.Subnet(substract.Cidr);
- var rtemp = new List<IPNetwork>();
- foreach(var subnet in collection) {
- if (subnet != substract) {
- rtemp.Add(subnet);
- }
- }
- var supernets = Supernet(rtemp.ToArray());
- results.AddRange(supernets);
- }
- result = results;
- return true;
- }
-#endregion
- * **/
-
- #region IComparable<IPNetwork> Members
-
- public static int Compare(IPNetwork left, IPNetwork right)
- {
- // two null IPNetworks are equal
- if (ReferenceEquals(left, null) && ReferenceEquals(right, null)) return 0;
-
- // two same IPNetworks are equal
- if (ReferenceEquals(left, right)) return 0;
-
- // null is always sorted first
- if (ReferenceEquals(left, null)) return -1;
- if (ReferenceEquals(right, null)) return 1;
-
- // first test the network
- var result = left._network.CompareTo(right._network);
- if (result != 0) return result;
-
- // then test the cidr
- result = left._cidr.CompareTo(right._cidr);
- return result;
- }
-
- public int CompareTo(IPNetwork other)
- {
- return Compare(this, other);
- }
-
- public int CompareTo(object obj)
- {
- // null is at less
- if (obj == null) return 1;
-
- // convert to a proper Cidr object
- var other = obj as IPNetwork;
-
- // type problem if null
- if (other == null)
- {
- throw new ArgumentException(
- "The supplied parameter is an invalid type. Please supply an IPNetwork type.",
- nameof(obj));
- }
-
- // perform the comparision
- return CompareTo(other);
- }
-
- #endregion
-
- #region IEquatable<IPNetwork> Members
-
- public static bool Equals(IPNetwork left, IPNetwork right)
- {
- return Compare(left, right) == 0;
- }
-
- public bool Equals(IPNetwork other)
- {
- return Equals(this, other);
- }
-
- public override bool Equals(object obj)
- {
- return Equals(this, obj as IPNetwork);
- }
-
- #endregion
-
- #region Operators
-
- public static bool operator ==(IPNetwork left, IPNetwork right)
- {
- return Equals(left, right);
- }
-
- public static bool operator !=(IPNetwork left, IPNetwork right)
- {
- return !Equals(left, right);
- }
-
- public static bool operator <(IPNetwork left, IPNetwork right)
- {
- return Compare(left, right) < 0;
- }
-
- public static bool operator >(IPNetwork left, IPNetwork right)
- {
- return Compare(left, right) > 0;
- }
-
- #endregion
-
- }
-}
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs b/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs
deleted file mode 100644
index 4cda421e5..000000000
--- a/Emby.Server.Implementations/Networking/IPNetwork/IPNetworkCollection.cs
+++ /dev/null
@@ -1,129 +0,0 @@
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Numerics;
-
-namespace Emby.Server.Implementations.Networking.IPNetwork
-{
- public class IPNetworkCollection : IEnumerable<IPNetwork>, IEnumerator<IPNetwork>
- {
-
- private BigInteger _enumerator;
- private byte _cidrSubnet;
- private IPNetwork _ipnetwork;
-
- private byte _cidr => this._ipnetwork.Cidr;
-
- private BigInteger _broadcast => IPNetwork.ToBigInteger(this._ipnetwork.Broadcast);
-
- private BigInteger _lastUsable => IPNetwork.ToBigInteger(this._ipnetwork.LastUsable);
- private BigInteger _network => IPNetwork.ToBigInteger(this._ipnetwork.Network);
-#if TRAVISCI
- public
-#else
- internal
-#endif
- IPNetworkCollection(IPNetwork ipnetwork, byte cidrSubnet)
- {
-
- int maxCidr = ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork ? 32 : 128;
- if (cidrSubnet > maxCidr)
- {
- throw new ArgumentOutOfRangeException(nameof(cidrSubnet));
- }
-
- if (cidrSubnet < ipnetwork.Cidr)
- {
- throw new ArgumentException("cidr");
- }
-
- this._cidrSubnet = cidrSubnet;
- this._ipnetwork = ipnetwork;
- this._enumerator = -1;
- }
-
- #region Count, Array, Enumerator
-
- public BigInteger Count
- {
- get
- {
- var count = BigInteger.Pow(2, this._cidrSubnet - this._cidr);
- return count;
- }
- }
-
- public IPNetwork this[BigInteger i]
- {
- get
- {
- if (i >= this.Count)
- {
- throw new ArgumentOutOfRangeException(nameof(i));
- }
-
- var last = this._ipnetwork.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6
- ? this._lastUsable : this._broadcast;
- var increment = (last - this._network) / this.Count;
- var uintNetwork = this._network + ((increment + 1) * i);
- var ipn = new IPNetwork(uintNetwork, this._ipnetwork.AddressFamily, this._cidrSubnet);
- return ipn;
- }
- }
-
- #endregion
-
- #region IEnumerable Members
-
- IEnumerator<IPNetwork> IEnumerable<IPNetwork>.GetEnumerator()
- {
- return this;
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return this;
- }
-
- #region IEnumerator<IPNetwork> Members
-
- public IPNetwork Current => this[this._enumerator];
-
- #endregion
-
- #region IDisposable Members
-
- public void Dispose()
- {
- // nothing to dispose
- return;
- }
-
- #endregion
-
- #region IEnumerator Members
-
- object IEnumerator.Current => this.Current;
-
- public bool MoveNext()
- {
- this._enumerator++;
- if (this._enumerator >= this.Count)
- {
- return false;
- }
- return true;
-
- }
-
- public void Reset()
- {
- this._enumerator = -1;
- }
-
- #endregion
-
- #endregion
-
- }
-}
diff --git a/Emby.Server.Implementations/Networking/IPNetwork/LICENSE.txt b/Emby.Server.Implementations/Networking/IPNetwork/LICENSE.txt
deleted file mode 100644
index 45d7392ac..000000000
--- a/Emby.Server.Implementations/Networking/IPNetwork/LICENSE.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Copyright (c) 2015, lduchosal
-All rights reserved.
-
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-* Redistributions of source code must retain the above copyright notice, this
- list of conditions and the following disclaimer.
-
-* Redistributions in binary form must reproduce the above copyright notice,
- this list of conditions and the following disclaimer in the documentation
- and/or other materials provided with the distribution.
-
-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
-OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
diff --git a/Emby.Server.Implementations/Networking/NetworkManager.cs b/Emby.Server.Implementations/Networking/NetworkManager.cs
index da06dc5c5..f613dc295 100644
--- a/Emby.Server.Implementations/Networking/NetworkManager.cs
+++ b/Emby.Server.Implementations/Networking/NetworkManager.cs
@@ -257,7 +257,7 @@ namespace Emby.Server.Implementations.Networking
if (normalizedSubnet.IndexOf('/') != -1)
{
- var ipnetwork = IPNetwork.IPNetwork.Parse(normalizedSubnet);
+ var ipnetwork = IPNetwork.Parse(normalizedSubnet);
if (ipnetwork.Contains(address))
{
return true;
diff --git a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
index 2984efec3..b9ccc93ef 100644
--- a/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
+++ b/MediaBrowser.Controller/MediaEncoding/EncodingHelper.cs
@@ -573,7 +573,9 @@ namespace MediaBrowser.Controller.MediaEncoding
}
// TODO: Perhaps also use original_size=1920x800 ??
- return string.Format("subtitles=filename='{0}'{1}{2}{3}",
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "subtitles=filename='{0}'{1}{2}",
_mediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
charsetParam,
// fallbackFontParam,
@@ -582,7 +584,9 @@ namespace MediaBrowser.Controller.MediaEncoding
var mediaPath = state.MediaPath ?? string.Empty;
- return string.Format("subtitles='{0}:si={1}'{2}",
+ return string.Format(
+ CultureInfo.InvariantCulture,
+ "subtitles='{0}:si={1}'{2}",
_mediaEncoder.EscapeSubtitleFilterPath(mediaPath),
state.InternalSubtitleStreamOffset.ToString(_usCulture),
// fallbackFontParam,
diff --git a/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs b/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs
index b40cc157a..bb80e6025 100644
--- a/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs
+++ b/MediaBrowser.Controller/Resolvers/IResolverIgnoreRule.cs
@@ -8,6 +8,12 @@ namespace MediaBrowser.Controller.Resolvers
/// </summary>
public interface IResolverIgnoreRule
{
+ /// <summary>
+ /// Checks whether or not the file should be ignored.
+ /// </summary>
+ /// <param name="fileInfo">The file information.</param>
+ /// <param name="parent">The parent BaseItem.</param>
+ /// <returns>True if the file should be ignored.</returns>
bool ShouldIgnore(FileSystemMetadata fileInfo, BaseItem parent);
}
}
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index 659abe84c..d7bf956bb 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -12,113 +12,133 @@ namespace MediaBrowser.Model.Net
public static class MimeTypes
{
/// <summary>
- /// Any extension in this list is considered a video file - can be added to at runtime for extensibility
+ /// Any extension in this list is considered a video file
/// </summary>
- private static readonly string[] VideoFileExtensions = new string[]
- {
- ".mkv",
- ".m2t",
- ".m2ts",
- ".img",
- ".iso",
- ".mk3d",
- ".ts",
- ".rmvb",
- ".mov",
- ".avi",
- ".mpg",
- ".mpeg",
- ".wmv",
- ".mp4",
- ".divx",
- ".dvr-ms",
- ".wtv",
- ".ogm",
- ".ogv",
- ".asf",
- ".m4v",
- ".flv",
- ".f4v",
- ".3gp",
- ".webm",
- ".mts",
- ".m2v",
- ".rec"
- };
-
- private static Dictionary<string, string> GetVideoFileExtensionsDictionary()
+ private static readonly HashSet<string> _videoFileExtensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
- var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
-
- foreach (string ext in VideoFileExtensions)
- {
- dict[ext] = ext;
- }
-
- return dict;
- }
-
- private static readonly Dictionary<string, string> VideoFileExtensionsDictionary = GetVideoFileExtensionsDictionary();
+ ".mkv",
+ ".m2t",
+ ".m2ts",
+ ".img",
+ ".iso",
+ ".mk3d",
+ ".ts",
+ ".rmvb",
+ ".mov",
+ ".avi",
+ ".mpg",
+ ".mpeg",
+ ".wmv",
+ ".mp4",
+ ".divx",
+ ".dvr-ms",
+ ".wtv",
+ ".ogm",
+ ".ogv",
+ ".asf",
+ ".m4v",
+ ".flv",
+ ".f4v",
+ ".3gp",
+ ".webm",
+ ".mts",
+ ".m2v",
+ ".rec"
+ };
// http://en.wikipedia.org/wiki/Internet_media_type
// Add more as needed
-
- private static Dictionary<string, string> GetMimeTypeLookup()
+ private static readonly Dictionary<string, string> _mimeTypeLookup = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase)
{
- var dict = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
+ // Type application
+ { ".cbz", "application/x-cbz" },
+ { ".cbr", "application/epub+zip" },
+ { ".eot", "application/vnd.ms-fontobject" },
+ { ".epub", "application/epub+zip" },
+ { ".js", "application/x-javascript" },
+ { ".json", "application/json" },
+ { ".map", "application/x-javascript" },
+ { ".pdf", "application/pdf" },
+ { ".ttml", "application/ttml+xml" },
+ { ".m3u8", "application/x-mpegURL" },
+ { ".mobi", "application/x-mobipocket-ebook" },
+ { ".xml", "application/xml" },
+
+ // Type image
+ { ".jpg", "image/jpeg" },
+ { ".jpeg", "image/jpeg" },
+ { ".tbn", "image/jpeg" },
+ { ".png", "image/png" },
+ { ".gif", "image/gif" },
+ { ".tiff", "image/tiff" },
+ { ".webp", "image/webp" },
+ { ".ico", "image/vnd.microsoft.icon" },
+ { ".svg", "image/svg+xml" },
+ { ".svgz", "image/svg+xml" },
+
+ // Type font
+ { ".ttf" , "font/ttf" },
+ { ".woff" , "font/woff" },
- dict.Add(".jpg", "image/jpeg");
- dict.Add(".jpeg", "image/jpeg");
- dict.Add(".tbn", "image/jpeg");
- dict.Add(".png", "image/png");
- dict.Add(".gif", "image/gif");
- dict.Add(".tiff", "image/tiff");
- dict.Add(".webp", "image/webp");
- dict.Add(".ico", "image/vnd.microsoft.icon");
- dict.Add(".mpg", "video/mpeg");
- dict.Add(".mpeg", "video/mpeg");
- dict.Add(".ogv", "video/ogg");
- dict.Add(".mov", "video/quicktime");
- dict.Add(".webm", "video/webm");
- dict.Add(".mkv", "video/x-matroska");
- dict.Add(".wmv", "video/x-ms-wmv");
- dict.Add(".flv", "video/x-flv");
- dict.Add(".avi", "video/x-msvideo");
- dict.Add(".asf", "video/x-ms-asf");
- dict.Add(".m4v", "video/x-m4v");
- dict.Add(".m4s", "video/mp4");
- dict.Add(".cbz", "application/x-cbz");
- dict.Add(".cbr", "application/epub+zip");
- dict.Add(".epub", "application/epub+zip");
- dict.Add(".pdf", "application/pdf");
- dict.Add(".mobi", "application/x-mobipocket-ebook");
-
- dict.Add(".ass", "text/x-ssa");
- dict.Add(".ssa", "text/x-ssa");
+ // Type text
+ { ".ass", "text/x-ssa" },
+ { ".ssa", "text/x-ssa" },
+ { ".css", "text/css" },
+ { ".csv", "text/csv" },
+ { ".txt", "text/plain" },
+ { ".vtt", "text/vtt" },
- return dict;
- }
+ // Type video
+ { ".mpg", "video/mpeg" },
+ { ".ogv", "video/ogg" },
+ { ".mov", "video/quicktime" },
+ { ".webm", "video/webm" },
+ { ".mkv", "video/x-matroska" },
+ { ".wmv", "video/x-ms-wmv" },
+ { ".flv", "video/x-flv" },
+ { ".avi", "video/x-msvideo" },
+ { ".asf", "video/x-ms-asf" },
+ { ".m4v", "video/x-m4v" },
+ { ".m4s", "video/mp4" },
+ { ".3gp", "video/3gpp" },
+ { ".3g2", "video/3gpp2" },
+ { ".mpd", "video/vnd.mpeg.dash.mpd" },
+ { ".ts", "video/mp2t" },
- private static readonly Dictionary<string, string> MimeTypeLookup = GetMimeTypeLookup();
+ // Type audio
+ { ".mp3", "audio/mpeg" },
+ { ".m4a", "audio/mp4" },
+ { ".aac", "audio/mp4" },
+ { ".webma", "audio/webm" },
+ { ".wav", "audio/wav" },
+ { ".wma", "audio/x-ms-wma" },
+ { ".ogg", "audio/ogg" },
+ { ".oga", "audio/ogg" },
+ { ".opus", "audio/ogg" },
+ { ".ac3", "audio/ac3" },
+ { ".dsf", "audio/dsf" },
+ { ".m4b", "audio/m4b" },
+ { ".xsp", "audio/xsp" },
+ { ".dsp", "audio/dsp" },
+ };
- private static readonly Dictionary<string, string> ExtensionLookup = CreateExtensionLookup();
+ private static readonly Dictionary<string, string> _extensionLookup = CreateExtensionLookup();
private static Dictionary<string, string> CreateExtensionLookup()
{
- var dict = MimeTypeLookup
+ var dict = _mimeTypeLookup
.GroupBy(i => i.Value)
.ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase);
dict["image/jpg"] = ".jpg";
dict["image/x-png"] = ".png";
+ dict["audio/x-aac"] = ".aac";
+
return dict;
}
- public static string GetMimeType(string path)
- {
- return GetMimeType(path, true);
- }
+ public static string GetMimeType(string path) => GetMimeType(path, true);
/// <summary>
/// Gets the type of the MIME.
@@ -130,137 +150,30 @@ namespace MediaBrowser.Model.Net
throw new ArgumentNullException(nameof(path));
}
- var ext = Path.GetExtension(path) ?? string.Empty;
+ var ext = Path.GetExtension(path);
- if (MimeTypeLookup.TryGetValue(ext, out string result))
+ if (_mimeTypeLookup.TryGetValue(ext, out string result))
{
return result;
}
- // Type video
- if (StringHelper.EqualsIgnoreCase(ext, ".3gp"))
- {
- return "video/3gpp";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".3g2"))
- {
- return "video/3gpp2";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".ts"))
- {
- return "video/mp2t";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".mpd"))
- {
- return "video/vnd.mpeg.dash.mpd";
- }
-
// Catch-all for all video types that don't require specific mime types
- if (VideoFileExtensionsDictionary.ContainsKey(ext))
+ if (_videoFileExtensions.Contains(ext))
{
- return "video/" + ext.TrimStart('.').ToLowerInvariant();
+ return "video/" + ext.Substring(1);
}
// Type text
- if (StringHelper.EqualsIgnoreCase(ext, ".css"))
- {
- return "text/css";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".csv"))
- {
- return "text/csv";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".html"))
+ if (StringHelper.EqualsIgnoreCase(ext, ".html")
+ || StringHelper.EqualsIgnoreCase(ext, ".htm"))
{
return "text/html; charset=UTF-8";
}
- if (StringHelper.EqualsIgnoreCase(ext, ".htm"))
- {
- return "text/html; charset=UTF-8";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".txt"))
- {
- return "text/plain";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".log"))
- {
- return "text/plain";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".xml"))
- {
- return "application/xml";
- }
- // Type audio
- if (StringHelper.EqualsIgnoreCase(ext, ".mp3"))
- {
- return "audio/mpeg";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".m4a"))
- {
- return "audio/mp4";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".aac"))
+ if (StringHelper.EqualsIgnoreCase(ext, ".log")
+ || StringHelper.EqualsIgnoreCase(ext, ".srt"))
{
- return "audio/mp4";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".webma"))
- {
- return "audio/webm";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".wav"))
- {
- return "audio/wav";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".wma"))
- {
- return "audio/x-ms-wma";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".flac"))
- {
- return "audio/flac";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".aac"))
- {
- return "audio/x-aac";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".ogg"))
- {
- return "audio/ogg";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".oga"))
- {
- return "audio/ogg";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".opus"))
- {
- return "audio/ogg";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".ac3"))
- {
- return "audio/ac3";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".dsf"))
- {
- return "audio/dsf";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".m4b"))
- {
- return "audio/m4b";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".xsp"))
- {
- return "audio/xsp";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".dsp"))
- {
- return "audio/dsp";
- }
-
- // Playlists
- if (StringHelper.EqualsIgnoreCase(ext, ".m3u8"))
- {
- return "application/x-mpegURL";
+ return "text/plain";
}
// Misc
@@ -269,63 +182,7 @@ namespace MediaBrowser.Model.Net
return "application/octet-stream";
}
- // Web
- if (StringHelper.EqualsIgnoreCase(ext, ".js"))
- {
- return "application/x-javascript";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".json"))
- {
- return "application/json";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".map"))
- {
- return "application/x-javascript";
- }
-
- if (StringHelper.EqualsIgnoreCase(ext, ".woff"))
- {
- return "font/woff";
- }
-
- if (StringHelper.EqualsIgnoreCase(ext, ".ttf"))
- {
- return "font/ttf";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".eot"))
- {
- return "application/vnd.ms-fontobject";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".svg"))
- {
- return "image/svg+xml";
- }
- if (StringHelper.EqualsIgnoreCase(ext, ".svgz"))
- {
- return "image/svg+xml";
- }
-
- if (StringHelper.EqualsIgnoreCase(ext, ".srt"))
- {
- return "text/plain";
- }
-
- if (StringHelper.EqualsIgnoreCase(ext, ".vtt"))
- {
- return "text/vtt";
- }
-
- if (StringHelper.EqualsIgnoreCase(ext, ".ttml"))
- {
- return "application/ttml+xml";
- }
-
- if (enableStreamDefault)
- {
- return "application/octet-stream";
- }
-
- return null;
+ return enableStreamDefault ? "application/octet-stream" : null;
}
public static string ToExtension(string mimeType)
@@ -338,10 +195,11 @@ namespace MediaBrowser.Model.Net
// handle text/html; charset=UTF-8
mimeType = mimeType.Split(';')[0];
- if (ExtensionLookup.TryGetValue(mimeType, out string result))
+ if (_extensionLookup.TryGetValue(mimeType, out string result))
{
return result;
}
+
return null;
}
}
diff --git a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
index 5ea73dfbf..c739f3f49 100644
--- a/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
+++ b/MediaBrowser.Providers/TV/TheTVDB/TvdbSeriesProvider.cs
@@ -355,7 +355,10 @@ namespace MediaBrowser.Providers.TV.TheTVDB
series.AddGenre(genre);
}
- series.AddStudio(tvdbSeries.Network);
+ if (!string.IsNullOrEmpty(tvdbSeries.Network))
+ {
+ series.AddStudio(tvdbSeries.Network);
+ }
if (result.Item.Status.HasValue && result.Item.Status.Value == SeriesStatus.Ended)
{
diff --git a/README.md b/README.md
index 643c59a73..8106b6e4e 100644
--- a/README.md
+++ b/README.md
@@ -13,6 +13,7 @@
<a href="https://hub.docker.com/r/jellyfin/jellyfin"><img alt="Docker Pull Count" src="https://img.shields.io/docker/pulls/jellyfin/jellyfin.svg"/></a>
</br>
<a href="https://opencollective.com/jellyfin"><img alt="Donate" src="https://img.shields.io/opencollective/all/jellyfin.svg?label=backers"/></a>
+<a href="https://features.jellyfin.org"/><img alt="Submit and vote on feature requests" src="https://img.shields.io/badge/fider-vote%20on%20features-success.svg"/></a>
<a href="https://forum.jellyfin.org"/><img alt="Discuss on our Forum" src="https://img.shields.io/discourse/https/forum.jellyfin.org/users.svg"/></a>
<a href="https://matrix.to/#/+jellyfin:matrix.org"><img alt="Chat on Matrix" src="https://img.shields.io/matrix/jellyfin:matrix.org.svg?logo=matrix"/></a>
<a href="https://www.reddit.com/r/jellyfin/"><img alt="Join our Subreddit" src="https://img.shields.io/badge/reddit-r%2Fjellyfin-%23FF5700.svg"/></a>