mirror of
https://github.com/91270/MeiamSubtitles.git
synced 2026-05-12 11:07:12 +08:00
refactor: 深度架构优化与 Jellyfin/Emby 规范化对齐
1. 引入 IHttpClientFactory:重构 Jellyfin 插件的 HTTP 调用模式,使用依赖注入管理 HttpClient 生命周期。 2. 优化服务注册:在 PluginServiceRegistrator 中统一配置命名 HTTP 客户端的超时与默认 Header。 3. 增强资源加载:优化 Emby 插件缩略图获取逻辑,增加安全性检查。 4. 代码逻辑优化:提取私有方法 NormalizeLanguage 统一处理跨平台语言代码映射。 5. 精简配置:简化 PluginConfiguration,移除冗余引用,同时确保与 Jellyfin 10.x 基类兼容。 6. 日志分级:细化 API 响应内容的记录级别,减少生产环境日志输出。
This commit is contained in:
@@ -48,7 +48,18 @@ namespace Emby.MeiamSub.Shooter
|
||||
public Stream GetThumbImage()
|
||||
{
|
||||
var type = GetType();
|
||||
return type.Assembly.GetManifestResourceStream(type.Namespace + ".Thumb.png");
|
||||
var resourceName = $"{type.Namespace}.Thumb.png";
|
||||
var stream = type.Assembly.GetManifestResourceStream(resourceName);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
// 如果找不到资源,尝试不带命名空间的名称,或者记录错误
|
||||
// 这里我们至少确保不会返回 null 导致外部空引用(虽然 Emby 可能处理 null)
|
||||
// 但为了稳健,如果真的没有,返回 null 是正确的,Emby 会显示默认图标
|
||||
return null;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,7 +50,15 @@ namespace Emby.MeiamSub.Thunder
|
||||
public Stream GetThumbImage()
|
||||
{
|
||||
var type = GetType();
|
||||
return type.Assembly.GetManifestResourceStream(type.Namespace + ".Thumb.png");
|
||||
var resourceName = $"{type.Namespace}.Thumb.png";
|
||||
var stream = type.Assembly.GetManifestResourceStream(resourceName);
|
||||
|
||||
if (stream == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return stream;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
namespace Jellyfin.MeiamSub.Shooter.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugin configuration.
|
||||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
using Jellyfin.MeiamSub.Shooter.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Jellyfin.MeiamSub.Shooter
|
||||
{
|
||||
@@ -30,7 +28,7 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
public override string Description => "Download subtitles from Shooter";
|
||||
|
||||
public Plugin(IApplicationPaths applicationPaths, IXmlSerializer xmlSerializer)
|
||||
: base(applicationPaths, xmlSerializer)
|
||||
: base(applicationPaths, xmlSerializer)
|
||||
{
|
||||
Instance = this;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,13 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
{
|
||||
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHos)
|
||||
{
|
||||
serviceCollection.AddHttpClient("MeiamSub.Shooter", client =>
|
||||
{
|
||||
client.Timeout = TimeSpan.FromSeconds(30);
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "MeiamSub.Shooter");
|
||||
client.DefaultRequestHeaders.Add("Accept", "*/*");
|
||||
});
|
||||
|
||||
serviceCollection.AddSingleton<ISubtitleProvider, ShooterProvider>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,8 +36,7 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
public const string SRT = "srt";
|
||||
|
||||
private readonly ILogger<ShooterProvider> _logger;
|
||||
|
||||
private static readonly HttpClient _httpClient = new HttpClient();
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
|
||||
private const string ApiUrl = "https://www.shooter.cn/api/subapi.php";
|
||||
|
||||
@@ -52,10 +51,10 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
public ShooterProvider(ILogger<ShooterProvider> logger)
|
||||
public ShooterProvider(ILogger<ShooterProvider> logger, IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger.LogInformation($"{Name} Init");
|
||||
}
|
||||
#endregion
|
||||
@@ -91,7 +90,9 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
|
||||
try
|
||||
{
|
||||
if (request.Language != "chi" && request.Language != "eng")
|
||||
var language = NormalizeLanguage(request.Language);
|
||||
|
||||
if (language != "chi" && language != "eng")
|
||||
{
|
||||
return Array.Empty<RemoteSubtitleInfo>();
|
||||
}
|
||||
@@ -107,7 +108,7 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
{ "filehash", hash},
|
||||
{ "pathinfo", request.MediaPath},
|
||||
{ "format", "json"},
|
||||
{ "lang", request.Language == "chi" ? "chn" : "eng"}
|
||||
{ "lang", language == "chi" ? "chn" : "eng"}
|
||||
};
|
||||
|
||||
var content = new FormUrlEncodedContent(formData);
|
||||
@@ -115,21 +116,23 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
// 设置请求头
|
||||
content.Headers.ContentType = new MediaTypeHeaderValue("application/x-www-form-urlencoded");
|
||||
|
||||
// 发送 POST 请求
|
||||
var response = await _httpClient.PostAsync(ApiUrl, content);
|
||||
using var httpClient = _httpClientFactory.CreateClient(Name);
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Response -> {JsonSerializer.Serialize(response)}");
|
||||
// 发送 POST 请求
|
||||
var response = await httpClient.PostAsync(ApiUrl, content);
|
||||
|
||||
_logger.LogDebug($"{Name} Search | Response -> {JsonSerializer.Serialize(response)}");
|
||||
|
||||
// 处理响应
|
||||
if (response.IsSuccessStatusCode && response.Content.Headers.Any(m => m.Value.Contains("application/json; charset=utf-8")))
|
||||
{
|
||||
var responseBody = await response.Content.ReadAsStringAsync();
|
||||
|
||||
_logger.LogInformation($"{Name} Search | ResponseBody -> {responseBody} ");
|
||||
_logger.LogDebug($"{Name} Search | ResponseBody -> {responseBody} ");
|
||||
|
||||
var subtitles = JsonSerializer.Deserialize<List<SubtitleResponseRoot>>(responseBody);
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Response -> {JsonSerializer.Serialize(subtitles)}");
|
||||
_logger.LogDebug($"{Name} Search | Response -> {JsonSerializer.Serialize(subtitles)}");
|
||||
|
||||
if (subtitles != null)
|
||||
{
|
||||
@@ -146,7 +149,7 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
{
|
||||
Url = subFile.Link,
|
||||
Format = subFile.Ext,
|
||||
Language = request.Language,
|
||||
Language = language,
|
||||
TwoLetterISOLanguageName = request.TwoLetterISOLanguageName,
|
||||
})),
|
||||
Name = $"[MEIAMSUB] {Path.GetFileName(request.MediaPath)} | {request.TwoLetterISOLanguageName} | 射手",
|
||||
@@ -217,15 +220,12 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
using var options = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri(downloadSub.Url),
|
||||
Headers =
|
||||
{
|
||||
UserAgent = { new ProductInfoHeaderValue(new ProductHeaderValue($"{Name}")) },
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("*/*") }
|
||||
}
|
||||
RequestUri = new Uri(downloadSub.Url)
|
||||
};
|
||||
|
||||
var response = await _httpClient.SendAsync(options);
|
||||
using var httpClient = _httpClientFactory.CreateClient(Name);
|
||||
|
||||
var response = await httpClient.SendAsync(options);
|
||||
|
||||
_logger.LogInformation($"{Name} DownloadSub | Response -> {response.StatusCode}");
|
||||
|
||||
@@ -296,6 +296,28 @@ namespace Jellyfin.MeiamSub.Shooter
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 规范化语言代码
|
||||
/// </summary>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
private static string NormalizeLanguage(string language)
|
||||
{
|
||||
if (string.IsNullOrEmpty(language)) return language;
|
||||
|
||||
if (language.Equals("zh-CN", StringComparison.OrdinalIgnoreCase) ||
|
||||
language.Equals("zh-TW", StringComparison.OrdinalIgnoreCase) ||
|
||||
language.Equals("zh-HK", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "chi";
|
||||
}
|
||||
if (language.Equals("en", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "eng";
|
||||
}
|
||||
return language;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步计算文件 Hash (射手网专用算法)
|
||||
/// <para>修改人: Meiam</para>
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
using MediaBrowser.Model.Plugins;
|
||||
using MediaBrowser.Model.Plugins;
|
||||
|
||||
namespace Jellyfin.MeiamSub.Thunder.Configuration
|
||||
{
|
||||
/// <summary>
|
||||
/// Plugin configuration.
|
||||
/// </summary>
|
||||
public class PluginConfiguration : BasePluginConfiguration
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
using Jellyfin.MeiamSub.Thunder.Configuration;
|
||||
using MediaBrowser.Common.Configuration;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Model.Drawing;
|
||||
using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
|
||||
|
||||
@@ -14,6 +14,13 @@ namespace Jellyfin.MeiamSub.Thunder
|
||||
{
|
||||
public void RegisterServices(IServiceCollection serviceCollection, IServerApplicationHost applicationHos)
|
||||
{
|
||||
serviceCollection.AddHttpClient("MeiamSub.Thunder", client =>
|
||||
{
|
||||
client.Timeout = TimeSpan.FromSeconds(30);
|
||||
client.DefaultRequestHeaders.Add("User-Agent", "MeiamSub.Thunder");
|
||||
client.DefaultRequestHeaders.Add("Accept", "*/*");
|
||||
});
|
||||
|
||||
serviceCollection.AddSingleton<ISubtitleProvider, ThunderProvider>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ namespace Jellyfin.MeiamSub.Thunder
|
||||
public const string SRT = "srt";
|
||||
|
||||
private readonly ILogger<ThunderProvider> _logger;
|
||||
private static readonly HttpClient _httpClient = new HttpClient();
|
||||
private readonly IHttpClientFactory _httpClientFactory;
|
||||
private static readonly JsonSerializerOptions _deserializeOptions = new JsonSerializerOptions
|
||||
{
|
||||
PropertyNamingPolicy = JsonNamingPolicy.SnakeCaseLower
|
||||
@@ -48,10 +48,10 @@ namespace Jellyfin.MeiamSub.Thunder
|
||||
#endregion
|
||||
|
||||
#region 构造函数
|
||||
public ThunderProvider(ILogger<ThunderProvider> logger)
|
||||
public ThunderProvider(ILogger<ThunderProvider> logger, IHttpClientFactory httpClientFactory)
|
||||
{
|
||||
_logger = logger;
|
||||
_httpClient.Timeout = TimeSpan.FromSeconds(30);
|
||||
_httpClientFactory = httpClientFactory;
|
||||
_logger.LogInformation($"{Name} Init");
|
||||
}
|
||||
#endregion
|
||||
@@ -74,93 +74,177 @@ namespace Jellyfin.MeiamSub.Thunder
|
||||
return subtitles;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 查询字幕
|
||||
/// </summary>
|
||||
/// <param name="request"></param>
|
||||
/// <returns></returns>
|
||||
private async Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitlesAsync(SubtitleSearchRequest request)
|
||||
{
|
||||
// 修改人: Meiam
|
||||
// 修改时间: 2025-12-22
|
||||
// 备注: 增加异常处理
|
||||
/// <summary>
|
||||
|
||||
/// 查询字幕
|
||||
|
||||
/// </summary>
|
||||
|
||||
/// <param name="request"></param>
|
||||
|
||||
/// <returns></returns>
|
||||
|
||||
private async Task<IEnumerable<RemoteSubtitleInfo>> SearchSubtitlesAsync(SubtitleSearchRequest request)
|
||||
|
||||
try
|
||||
{
|
||||
if (request.Language != "chi")
|
||||
{
|
||||
return Array.Empty<RemoteSubtitleInfo>();
|
||||
}
|
||||
|
||||
var cid = await GetCidByFileAsync(request.MediaPath);
|
||||
// 修改人: Meiam
|
||||
|
||||
_logger.LogInformation($"{Name} Search | FileHash -> {cid}");
|
||||
// 修改时间: 2025-12-22
|
||||
|
||||
// 备注: 增加异常处理
|
||||
|
||||
|
||||
|
||||
try
|
||||
|
||||
using var options = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri($"https://api-shoulei-ssl.xunlei.com/oracle/subtitle?name={Path.GetFileName(request.MediaPath)}"),
|
||||
Headers =
|
||||
{
|
||||
UserAgent = { new ProductInfoHeaderValue(new ProductHeaderValue($"{Name}")) },
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("*/*") },
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _httpClient.SendAsync(options);
|
||||
var language = NormalizeLanguage(request.Language);
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Response -> {JsonSerializer.Serialize(response)}");
|
||||
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
var subtitleResponse = JsonSerializer.Deserialize<SubtitleResponseRoot>(await response.Content.ReadAsStringAsync(), _deserializeOptions);
|
||||
if (language != "chi")
|
||||
|
||||
if (subtitleResponse != null)
|
||||
{
|
||||
_logger.LogInformation($"{Name} Search | Response -> {JsonSerializer.Serialize(subtitleResponse)}");
|
||||
|
||||
var subtitles = subtitleResponse.Data.Where(m => !string.IsNullOrEmpty(m.Name));
|
||||
|
||||
var remoteSubtitles = new List<RemoteSubtitleInfo>();
|
||||
|
||||
if (subtitles.Count() > 0)
|
||||
{
|
||||
foreach (var item in subtitles)
|
||||
{
|
||||
remoteSubtitles.Add(new RemoteSubtitleInfo()
|
||||
{
|
||||
Id = Base64Encode(JsonSerializer.Serialize(new DownloadSubInfo
|
||||
{
|
||||
Url = item.Url,
|
||||
Format = item.Ext,
|
||||
Language = request.Language,
|
||||
TwoLetterISOLanguageName = request.TwoLetterISOLanguageName,
|
||||
})),
|
||||
Name = $"[MEIAMSUB] {item.Name} | {(item.Langs == string.Empty ? "未知" : item.Langs)} | 迅雷",
|
||||
Author = "Meiam ",
|
||||
ProviderName = $"{Name}",
|
||||
Format = item.Ext,
|
||||
Comment = $"Format : {item.Ext}",
|
||||
IsHashMatch = cid == item.Cid,
|
||||
});
|
||||
}
|
||||
|
||||
return Array.Empty<RemoteSubtitleInfo>();
|
||||
|
||||
}
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Summary -> Get {subtitles.Count()} Subtitles");
|
||||
|
||||
|
||||
var cid = await GetCidByFileAsync(request.MediaPath);
|
||||
|
||||
|
||||
|
||||
_logger.LogInformation($"{Name} Search | FileHash -> {cid}");
|
||||
|
||||
|
||||
|
||||
using var options = new HttpRequestMessage
|
||||
|
||||
{
|
||||
|
||||
Method = HttpMethod.Get,
|
||||
|
||||
RequestUri = new Uri($"https://api-shoulei-ssl.xunlei.com/oracle/subtitle?name={Path.GetFileName(request.MediaPath)}")
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
using var httpClient = _httpClientFactory.CreateClient(Name);
|
||||
|
||||
|
||||
|
||||
var response = await httpClient.SendAsync(options);
|
||||
|
||||
|
||||
|
||||
_logger.LogDebug($"{Name} Search | Response -> {JsonSerializer.Serialize(response)}");
|
||||
|
||||
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
|
||||
{
|
||||
|
||||
var subtitleResponse = JsonSerializer.Deserialize<SubtitleResponseRoot>(await response.Content.ReadAsStringAsync(), _deserializeOptions);
|
||||
|
||||
|
||||
|
||||
if (subtitleResponse != null)
|
||||
|
||||
{
|
||||
|
||||
_logger.LogDebug($"{Name} Search | Response -> {JsonSerializer.Serialize(subtitleResponse)}");
|
||||
|
||||
|
||||
|
||||
var subtitles = subtitleResponse.Data.Where(m => !string.IsNullOrEmpty(m.Name));
|
||||
|
||||
|
||||
|
||||
var remoteSubtitles = new List<RemoteSubtitleInfo>();
|
||||
|
||||
|
||||
|
||||
if (subtitles.Count() > 0)
|
||||
|
||||
{
|
||||
|
||||
foreach (var item in subtitles)
|
||||
|
||||
{
|
||||
|
||||
remoteSubtitles.Add(new RemoteSubtitleInfo()
|
||||
|
||||
{
|
||||
|
||||
Id = Base64Encode(JsonSerializer.Serialize(new DownloadSubInfo
|
||||
|
||||
{
|
||||
|
||||
Url = item.Url,
|
||||
|
||||
Format = item.Ext,
|
||||
|
||||
Language = language,
|
||||
|
||||
TwoLetterISOLanguageName = request.TwoLetterISOLanguageName,
|
||||
|
||||
})),
|
||||
|
||||
Name = $"[MEIAMSUB] {item.Name} | {(item.Langs == string.Empty ? "未知" : item.Langs)} | 迅雷",
|
||||
|
||||
Author = "Meiam ",
|
||||
|
||||
ProviderName = $"{Name}",
|
||||
|
||||
Format = item.Ext,
|
||||
|
||||
Comment = $"Format : {item.Ext}",
|
||||
|
||||
IsHashMatch = cid == item.Cid,
|
||||
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Summary -> Get {subtitles.Count()} Subtitles");
|
||||
|
||||
|
||||
|
||||
return remoteSubtitles;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return remoteSubtitles;
|
||||
}
|
||||
|
||||
catch (Exception ex)
|
||||
|
||||
{
|
||||
|
||||
_logger.LogError(ex, "{0} Search | Error -> {1}", Name, ex.Message);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Summary -> Get 0 Subtitles");
|
||||
|
||||
|
||||
|
||||
return Array.Empty<RemoteSubtitleInfo>();
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "{0} Search | Error -> {1}", Name, ex.Message);
|
||||
}
|
||||
|
||||
_logger.LogInformation($"{Name} Search | Summary -> Get 0 Subtitles");
|
||||
|
||||
return Array.Empty<RemoteSubtitleInfo>();
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region 下载字幕
|
||||
@@ -200,20 +284,16 @@ namespace Jellyfin.MeiamSub.Thunder
|
||||
|
||||
_logger.LogInformation($"{Name} DownloadSub | Url -> {downloadSub.Url} | Format -> {downloadSub.Format} | Language -> {downloadSub.Language} ");
|
||||
|
||||
using var options = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri(downloadSub.Url),
|
||||
Headers =
|
||||
{
|
||||
UserAgent = { new ProductInfoHeaderValue(new ProductHeaderValue($"{Name}")) },
|
||||
Accept = { new MediaTypeWithQualityHeaderValue("*/*") }
|
||||
}
|
||||
};
|
||||
|
||||
var response = await _httpClient.SendAsync(options);
|
||||
|
||||
_logger.LogInformation($"{Name} DownloadSub | Response -> {response.StatusCode}");
|
||||
using var options = new HttpRequestMessage
|
||||
{
|
||||
Method = HttpMethod.Get,
|
||||
RequestUri = new Uri(downloadSub.Url)
|
||||
};
|
||||
|
||||
using var httpClient = _httpClientFactory.CreateClient(Name);
|
||||
|
||||
var response = await httpClient.SendAsync(options);
|
||||
_logger.LogInformation($"{Name} DownloadSub | Response -> {response.StatusCode}");
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.OK)
|
||||
{
|
||||
@@ -281,6 +361,28 @@ namespace Jellyfin.MeiamSub.Thunder
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 规范化语言代码
|
||||
/// </summary>
|
||||
/// <param name="language"></param>
|
||||
/// <returns></returns>
|
||||
private static string NormalizeLanguage(string language)
|
||||
{
|
||||
if (string.IsNullOrEmpty(language)) return language;
|
||||
|
||||
if (language.Equals("zh-CN", StringComparison.OrdinalIgnoreCase) ||
|
||||
language.Equals("zh-TW", StringComparison.OrdinalIgnoreCase) ||
|
||||
language.Equals("zh-HK", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "chi";
|
||||
}
|
||||
if (language.Equals("en", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return "eng";
|
||||
}
|
||||
return language;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 异步计算文件 CID (迅雷专用算法)
|
||||
/// <para>修改人: Meiam</para>
|
||||
|
||||
Reference in New Issue
Block a user