diff --git a/LME.AnimeON/ApnHelper.cs b/LME.AnimeON/ApnHelper.cs deleted file mode 100644 index 849850f..0000000 --- a/LME.AnimeON/ApnHelper.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static string TryGetMagicAshdiHost(JObject conf) - { - if (conf == null || !conf.TryGetValue("magic_apn", out var magicToken) || magicToken == null) - return null; - - if (magicToken.Type == JTokenType.Boolean) - return magicToken.Value() ? DefaultHost : null; - - if (magicToken.Type == JTokenType.String) - return NormalizeHost(magicToken.Value()); - - if (magicToken.Type != JTokenType.Object) - return null; - - return NormalizeHost(((JObject)magicToken).Value("ashdi")); - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - host = NormalizeHost(host); - if (host == null) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - - private static string NormalizeHost(string host) - { - if (string.IsNullOrWhiteSpace(host)) - return null; - - return host.Trim(); - } - } -} diff --git a/LME.AnimeON/GlobalUsings.cs b/LME.AnimeON/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.AnimeON/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.AnimeON/ModInit.cs b/LME.AnimeON/ModInit.cs index c4e6c2f..a061297 100644 --- a/LME.AnimeON/ModInit.cs +++ b/LME.AnimeON/ModInit.cs @@ -85,27 +85,7 @@ namespace LME.AnimeON } // Виводити "уточнити пошук" - RegisterWithSearch("lme_animeon"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_animeon"); } public void Dispose() @@ -115,120 +95,17 @@ namespace LME.AnimeON public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.AnimeON/manifest.json b/LME.AnimeON/manifest.json index 966262a..628bba4 100644 --- a/LME.AnimeON/manifest.json +++ b/LME.AnimeON/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.AnimeON.ModInit", - "online": "LME.AnimeON.OnlineApi" -} \ No newline at end of file + "online": "LME.AnimeON.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.Bamboo/ApnHelper.cs b/LME.Bamboo/ApnHelper.cs deleted file mode 100644 index 394a5bc..0000000 --- a/LME.Bamboo/ApnHelper.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (string.IsNullOrWhiteSpace(host)) - host = DefaultHost; - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - } -} diff --git a/LME.Bamboo/GlobalUsings.cs b/LME.Bamboo/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.Bamboo/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.Bamboo/ModInit.cs b/LME.Bamboo/ModInit.cs index 775677f..a47a6a9 100644 --- a/LME.Bamboo/ModInit.cs +++ b/LME.Bamboo/ModInit.cs @@ -63,7 +63,7 @@ namespace LME.Bamboo conf.Remove("apn_host"); Bamboo = conf.ToObject(); if (hasApn) - ApnHelper.ApplyInitConf(apnEnabled, apnHost, Bamboo); + ApnHelper.ApplyInitConf(apnEnabled, apnHost, Bamboo, useDefaultHostWhenEmpty: true); ApnHostProvided = hasApn && apnEnabled && !string.IsNullOrWhiteSpace(apnHost); if (hasApn && apnEnabled) { @@ -76,27 +76,7 @@ namespace LME.Bamboo } // Виводити "уточнити пошук" - RegisterWithSearch("lme_bamboo"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_bamboo"); } public void Dispose() @@ -106,120 +86,17 @@ namespace LME.Bamboo public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); -} \ No newline at end of file +} diff --git a/LME.Bamboo/manifest.json b/LME.Bamboo/manifest.json index 3d71f24..74d0900 100644 --- a/LME.Bamboo/manifest.json +++ b/LME.Bamboo/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.Bamboo.ModInit", - "online": "LME.Bamboo.OnlineApi" -} \ No newline at end of file + "online": "LME.Bamboo.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.JackTor/ModInit.cs b/LME.JackTor/ModInit.cs index e217e96..8f7cac6 100644 --- a/LME.JackTor/ModInit.cs +++ b/LME.JackTor/ModInit.cs @@ -1,4 +1,5 @@ using LME.JackTor.Models; +using Microsoft.AspNetCore.Mvc; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Shared; @@ -78,27 +79,7 @@ namespace LME.JackTor JackTor.host = JackTor.jackett; // Показувати «уточнити пошук». - RegisterWithSearch("lme_jacktor"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_jacktor"); } public void Dispose() @@ -108,110 +89,17 @@ namespace LME.JackTor public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; - - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - return; - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - return; - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } - } + => _service.IsDisconnected(); - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); + public static ActionResult Validate(ActionResult result) + => _service.Validate(result); + } } diff --git a/LME.JackTor/manifest.json b/LME.JackTor/manifest.json index a62000d..fa71984 100644 --- a/LME.JackTor/manifest.json +++ b/LME.JackTor/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.JackTor.ModInit", - "online": "LME.JackTor.OnlineApi" -} \ No newline at end of file + "online": "LME.JackTor.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.KlonFUN/ApnHelper.cs b/LME.KlonFUN/ApnHelper.cs deleted file mode 100644 index 12c5ad8..0000000 --- a/LME.KlonFUN/ApnHelper.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static string TryGetMagicAshdiHost(JObject conf) - { - if (conf == null || !conf.TryGetValue("magic_apn", out var magicToken) || magicToken == null) - return null; - - if (magicToken.Type == JTokenType.Boolean) - return magicToken.Value() ? DefaultHost : null; - - if (magicToken.Type == JTokenType.String) - return NormalizeHost(magicToken.Value()); - - if (magicToken.Type != JTokenType.Object) - return null; - - return NormalizeHost(((JObject)magicToken).Value("ashdi")); - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - host = NormalizeHost(host); - if (host == null) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) - && url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - - private static string NormalizeHost(string host) - { - if (string.IsNullOrWhiteSpace(host)) - return null; - - return host.Trim(); - } - } -} diff --git a/LME.KlonFUN/GlobalUsings.cs b/LME.KlonFUN/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.KlonFUN/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.KlonFUN/ModInit.cs b/LME.KlonFUN/ModInit.cs index 363ee1e..4f2d6d7 100644 --- a/LME.KlonFUN/ModInit.cs +++ b/LME.KlonFUN/ModInit.cs @@ -41,7 +41,7 @@ namespace LME.KlonFUN EventListener.UpdateInitFile += UpdateConfig; // Додаємо підтримку "уточнити пошук". - RegisterWithSearch("lme_klonfun"); + OnlineRegistry.RegisterWithSearch("lme_klonfun"); } private void UpdateConfig() @@ -88,26 +88,6 @@ namespace LME.KlonFUN } } - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } - } - public void Dispose() { EventListener.UpdateInitFile -= UpdateConfig; @@ -116,121 +96,17 @@ namespace LME.KlonFUN public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; - - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.KlonFUN/manifest.json b/LME.KlonFUN/manifest.json index 0e55b1a..76250c7 100644 --- a/LME.KlonFUN/manifest.json +++ b/LME.KlonFUN/manifest.json @@ -1,5 +1,11 @@ { "enable": true, "initspace": "LME.KlonFUN.ModInit", - "online": "LME.KlonFUN.OnlineApi" -} \ No newline at end of file + "online": "LME.KlonFUN.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.Makhno/GlobalUsings.cs b/LME.Makhno/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.Makhno/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.Makhno/ModInit.cs b/LME.Makhno/ModInit.cs index 90885d4..b86ee3e 100644 --- a/LME.Makhno/ModInit.cs +++ b/LME.Makhno/ModInit.cs @@ -84,27 +84,7 @@ namespace LME.Makhno } // Виводити "уточнити пошук" - RegisterWithSearch("lme_makhno"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_makhno"); } public void Dispose() @@ -114,120 +94,17 @@ namespace LME.Makhno public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.Makhno/manifest.json b/LME.Makhno/manifest.json index 8186830..e1f789a 100644 --- a/LME.Makhno/manifest.json +++ b/LME.Makhno/manifest.json @@ -1,5 +1,11 @@ { "enable": true, "initspace": "LME.Makhno.ModInit", - "online": "LME.Makhno.OnlineApi" -} \ No newline at end of file + "online": "LME.Makhno.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.Mikai/ApnHelper.cs b/LME.Mikai/ApnHelper.cs deleted file mode 100644 index 849850f..0000000 --- a/LME.Mikai/ApnHelper.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static string TryGetMagicAshdiHost(JObject conf) - { - if (conf == null || !conf.TryGetValue("magic_apn", out var magicToken) || magicToken == null) - return null; - - if (magicToken.Type == JTokenType.Boolean) - return magicToken.Value() ? DefaultHost : null; - - if (magicToken.Type == JTokenType.String) - return NormalizeHost(magicToken.Value()); - - if (magicToken.Type != JTokenType.Object) - return null; - - return NormalizeHost(((JObject)magicToken).Value("ashdi")); - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - host = NormalizeHost(host); - if (host == null) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - - private static string NormalizeHost(string host) - { - if (string.IsNullOrWhiteSpace(host)) - return null; - - return host.Trim(); - } - } -} diff --git a/LME.Mikai/GlobalUsings.cs b/LME.Mikai/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.Mikai/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.Mikai/ModInit.cs b/LME.Mikai/ModInit.cs index 8cce003..fff1740 100644 --- a/LME.Mikai/ModInit.cs +++ b/LME.Mikai/ModInit.cs @@ -86,27 +86,7 @@ namespace LME.Mikai } // Виводити "уточнити пошук" - RegisterWithSearch("lme_mikai"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_mikai"); } public void Dispose() @@ -116,120 +96,17 @@ namespace LME.Mikai public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.Mikai/manifest.json b/LME.Mikai/manifest.json index e04d316..8289c0b 100644 --- a/LME.Mikai/manifest.json +++ b/LME.Mikai/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.Mikai.ModInit", - "online": "LME.Mikai.OnlineApi" -} \ No newline at end of file + "online": "LME.Mikai.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.NMoonAnime/ApnHelper.cs b/LME.NMoonAnime/ApnHelper.cs deleted file mode 100644 index 394a5bc..0000000 --- a/LME.NMoonAnime/ApnHelper.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (string.IsNullOrWhiteSpace(host)) - host = DefaultHost; - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - } -} diff --git a/LME.NMoonAnime/GlobalUsings.cs b/LME.NMoonAnime/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.NMoonAnime/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.NMoonAnime/ModInit.cs b/LME.NMoonAnime/ModInit.cs index 3398322..094db50 100644 --- a/LME.NMoonAnime/ModInit.cs +++ b/LME.NMoonAnime/ModInit.cs @@ -58,7 +58,7 @@ namespace LME.NMoonAnime NMoonAnime = conf.ToObject(); if (hasApn) - ApnHelper.ApplyInitConf(apnEnabled, apnHost, NMoonAnime); + ApnHelper.ApplyInitConf(apnEnabled, apnHost, NMoonAnime, useDefaultHostWhenEmpty: true); ApnHostProvided = hasApn && apnEnabled && !string.IsNullOrWhiteSpace(apnHost); if (hasApn && apnEnabled) @@ -71,27 +71,7 @@ namespace LME.NMoonAnime NMoonAnime.apn = null; } - RegisterWithSearch("lme_nmoonanime"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_nmoonanime"); } public void Dispose() @@ -101,121 +81,17 @@ namespace LME.NMoonAnime public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; - - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.NMoonAnime/manifest.json b/LME.NMoonAnime/manifest.json index 3a8385e..bd32fdf 100644 --- a/LME.NMoonAnime/manifest.json +++ b/LME.NMoonAnime/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.NMoonAnime.ModInit", - "online": "LME.NMoonAnime.OnlineApi" -} \ No newline at end of file + "online": "LME.NMoonAnime.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.Makhno/ApnHelper.cs b/LME.Shared/Apn/ApnHelper.cs similarity index 95% rename from LME.Makhno/ApnHelper.cs rename to LME.Shared/Apn/ApnHelper.cs index a05dff1..7b1fb96 100644 --- a/LME.Makhno/ApnHelper.cs +++ b/LME.Shared/Apn/ApnHelper.cs @@ -54,7 +54,7 @@ namespace Shared.Engine return NormalizeHost(((JObject)magicToken).Value("ashdi")); } - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) + public static void ApplyInitConf(bool enabled, string host, BaseSettings init, bool useDefaultHostWhenEmpty = false) { if (init == null) return; @@ -67,6 +67,9 @@ namespace Shared.Engine } host = NormalizeHost(host); + if (host == null && useDefaultHostWhenEmpty) + host = DefaultHost; + if (host == null) { init.apnstream = false; diff --git a/LME.JackTor/GlobalUsings.cs b/LME.Shared/GlobalUsings.cs similarity index 68% rename from LME.JackTor/GlobalUsings.cs rename to LME.Shared/GlobalUsings.cs index 4c00409..c3d3cbf 100644 --- a/LME.JackTor/GlobalUsings.cs +++ b/LME.Shared/GlobalUsings.cs @@ -2,3 +2,5 @@ global using Shared.Services; global using Shared.Services.Hybrid; global using Shared.Models.Base; global using AppInit = Shared.CoreInit; +global using LME.Common.Online; +global using LME.Common.Update; diff --git a/LME.Shared/Online/OnlineRegistry.cs b/LME.Shared/Online/OnlineRegistry.cs new file mode 100644 index 0000000..d84073a --- /dev/null +++ b/LME.Shared/Online/OnlineRegistry.cs @@ -0,0 +1,28 @@ +using Shared; +using System; + +namespace LME.Common.Online +{ + public static class OnlineRegistry + { + public static void RegisterWithSearch(string plugin) + { + try + { + if (CoreInit.conf.online.with_search == null) + return; + + foreach (var item in CoreInit.conf.online.with_search) + { + if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) + return; + } + + CoreInit.conf.online.with_search.Add(plugin); + } + catch + { + } + } + } +} diff --git a/LME.Shared/Update/ModuleUpdateService.cs b/LME.Shared/Update/ModuleUpdateService.cs new file mode 100644 index 0000000..9721d91 --- /dev/null +++ b/LME.Shared/Update/ModuleUpdateService.cs @@ -0,0 +1,139 @@ +using Microsoft.AspNetCore.Mvc; +using Newtonsoft.Json; +using Newtonsoft.Json.Linq; +using System; +using System.Net.Http; +using System.Net.Mime; +using System.Net.Security; +using System.Security.Authentication; +using System.Text; +using System.Threading; +using System.Threading.Tasks; + +namespace LME.Common.Update +{ + public sealed class ModuleUpdateService + { + private const string ConnectUrl = "https://lmcuk.lme.isroot.in/stats"; + + private readonly Func _pluginResolver; + private readonly Func _versionResolver; + + private ConnectResponse? _connect; + private DateTime? _connectTime; + private DateTime? _disconnectTime; + + private static readonly TimeSpan ResetInterval = TimeSpan.FromHours(4); + private Timer? _resetTimer; + + private readonly object _lock = new(); + + public ModuleUpdateService(Func pluginResolver, Func versionResolver) + { + _pluginResolver = pluginResolver; + _versionResolver = versionResolver; + } + + public async Task ConnectAsync(string host, CancellationToken cancellationToken = default) + { + if (_connectTime is not null || _connect?.IsUpdateUnavailable == true) + return; + + lock (_lock) + { + if (_connectTime is not null || _connect?.IsUpdateUnavailable == true) + return; + + _connectTime = DateTime.UtcNow; + } + + try + { + using var handler = new SocketsHttpHandler + { + SslOptions = new SslClientAuthenticationOptions + { + RemoteCertificateValidationCallback = (_, _, _, _) => true, + EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 + } + }; + + using var client = new HttpClient(handler); + client.Timeout = TimeSpan.FromSeconds(15); + + var request = new + { + Host = host, + Module = _pluginResolver(), + Version = _versionResolver(), + }; + + var requestJson = JsonConvert.SerializeObject(request, Formatting.None); + var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); + + var response = await client + .PostAsync(ConnectUrl, requestContent, cancellationToken) + .ConfigureAwait(false); + + response.EnsureSuccessStatusCode(); + + if (response.Content.Headers.ContentLength > 0) + { + var responseText = await response.Content + .ReadAsStringAsync(cancellationToken) + .ConfigureAwait(false); + + _connect = JsonConvert.DeserializeObject(responseText); + } + + lock (_lock) + { + _resetTimer?.Dispose(); + _resetTimer = null; + + if (_connect?.IsUpdateUnavailable != true) + { + _resetTimer = new Timer(ResetConnectTime, null, ResetInterval, Timeout.InfiniteTimeSpan); + } + else + { + _disconnectTime = _connect?.IsNoiseEnabled == true + ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) + : DateTime.UtcNow; + } + } + } + catch + { + ResetConnectTime(null); + } + } + + public bool IsDisconnected() + { + return _disconnectTime is not null + && DateTime.UtcNow >= _disconnectTime; + } + + public ActionResult Validate(ActionResult result) + { + return IsDisconnected() + ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") + : result; + } + + private void ResetConnectTime(object? state) + { + lock (_lock) + { + _connectTime = null; + _connect = null; + + _resetTimer?.Dispose(); + _resetTimer = null; + } + } + + private record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); + } +} diff --git a/LME.StarLight/ApnHelper.cs b/LME.StarLight/ApnHelper.cs deleted file mode 100644 index 394a5bc..0000000 --- a/LME.StarLight/ApnHelper.cs +++ /dev/null @@ -1,86 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (string.IsNullOrWhiteSpace(host)) - host = DefaultHost; - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - } -} diff --git a/LME.StarLight/GlobalUsings.cs b/LME.StarLight/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.StarLight/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.StarLight/ModInit.cs b/LME.StarLight/ModInit.cs index c681a24..08eaec7 100644 --- a/LME.StarLight/ModInit.cs +++ b/LME.StarLight/ModInit.cs @@ -63,7 +63,7 @@ namespace LME.StarLight conf.Remove("apn_host"); StarLight = conf.ToObject(); if (hasApn) - ApnHelper.ApplyInitConf(apnEnabled, apnHost, StarLight); + ApnHelper.ApplyInitConf(apnEnabled, apnHost, StarLight, useDefaultHostWhenEmpty: true); ApnHostProvided = hasApn && apnEnabled && !string.IsNullOrWhiteSpace(apnHost); if (hasApn && apnEnabled) { @@ -76,27 +76,7 @@ namespace LME.StarLight } // Виводити "уточнити пошук" - RegisterWithSearch("lme_starlight"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_starlight"); } public void Dispose() @@ -106,120 +86,17 @@ namespace LME.StarLight public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); -} \ No newline at end of file +} diff --git a/LME.StarLight/manifest.json b/LME.StarLight/manifest.json index bff9e3b..087b37f 100644 --- a/LME.StarLight/manifest.json +++ b/LME.StarLight/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.StarLight.ModInit", - "online": "LME.StarLight.OnlineApi" -} \ No newline at end of file + "online": "LME.StarLight.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.UafilmME/ApnHelper.cs b/LME.UafilmME/ApnHelper.cs deleted file mode 100644 index 2274b2b..0000000 --- a/LME.UafilmME/ApnHelper.cs +++ /dev/null @@ -1,99 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - host = NormalizeHost(host); - if (host == null) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - - private static string NormalizeHost(string host) - { - if (string.IsNullOrWhiteSpace(host)) - return null; - - return host.Trim(); - } - } -} diff --git a/LME.UafilmME/GlobalUsings.cs b/LME.UafilmME/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.UafilmME/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.UafilmME/ModInit.cs b/LME.UafilmME/ModInit.cs index 9dd1589..e34de29 100644 --- a/LME.UafilmME/ModInit.cs +++ b/LME.UafilmME/ModInit.cs @@ -69,27 +69,7 @@ namespace LME.UafilmME UafilmME.apn = null; } - RegisterWithSearch("lme_uafilmme"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_uafilmme"); } public void Dispose() @@ -99,117 +79,17 @@ namespace LME.UafilmME public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; - - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - return; - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - return; - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.UafilmME/manifest.json b/LME.UafilmME/manifest.json index 2aa6412..1a71470 100644 --- a/LME.UafilmME/manifest.json +++ b/LME.UafilmME/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.UafilmME.ModInit", - "online": "LME.UafilmME.OnlineApi" -} \ No newline at end of file + "online": "LME.UafilmME.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.Uaflix/ApnHelper.cs b/LME.Uaflix/ApnHelper.cs deleted file mode 100644 index 849850f..0000000 --- a/LME.Uaflix/ApnHelper.cs +++ /dev/null @@ -1,116 +0,0 @@ -using Newtonsoft.Json.Linq; -using Shared.Models.Base; -using System; -using System.Web; - -namespace Shared.Engine -{ - public static class ApnHelper - { - public const string DefaultHost = "https://tut.im/proxy.php?url={encodeurl}"; - - public static bool TryGetInitConf(JObject conf, out bool enabled, out string host) - { - enabled = false; - host = null; - - if (conf == null) - return false; - - if (!conf.TryGetValue("apn", out var apnToken) || apnToken?.Type != JTokenType.Boolean) - return false; - - enabled = apnToken.Value(); - host = conf.Value("apn_host"); - return true; - } - - public static string TryGetMagicAshdiHost(JObject conf) - { - if (conf == null || !conf.TryGetValue("magic_apn", out var magicToken) || magicToken == null) - return null; - - if (magicToken.Type == JTokenType.Boolean) - return magicToken.Value() ? DefaultHost : null; - - if (magicToken.Type == JTokenType.String) - return NormalizeHost(magicToken.Value()); - - if (magicToken.Type != JTokenType.Object) - return null; - - return NormalizeHost(((JObject)magicToken).Value("ashdi")); - } - - public static void ApplyInitConf(bool enabled, string host, BaseSettings init) - { - if (init == null) - return; - - if (!enabled) - { - init.apnstream = false; - init.apn = null; - return; - } - - host = NormalizeHost(host); - if (host == null) - { - init.apnstream = false; - init.apn = null; - return; - } - - if (init.apn == null) - init.apn = new ApnConf(); - - init.apn.host = host; - init.apnstream = true; - } - - public static bool IsEnabled(BaseSettings init) - { - return init?.apnstream == true && !string.IsNullOrWhiteSpace(init?.apn?.host); - } - - public static bool IsAshdiUrl(string url) - { - return !string.IsNullOrEmpty(url) && - url.IndexOf("ashdi.vip", StringComparison.OrdinalIgnoreCase) >= 0; - } - - public static string WrapUrl(BaseSettings init, string url) - { - if (!IsEnabled(init)) - return url; - - return BuildUrl(init.apn.host, url); - } - - public static string BuildUrl(string host, string url) - { - if (string.IsNullOrEmpty(host) || string.IsNullOrEmpty(url)) - return url; - - if (host.Contains("{encodeurl}")) - return host.Replace("{encodeurl}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{encode_uri}")) - return host.Replace("{encode_uri}", HttpUtility.UrlEncode(url)); - - if (host.Contains("{uri}")) - return host.Replace("{uri}", url); - - return $"{host.TrimEnd('/')}/{url}"; - } - - private static string NormalizeHost(string host) - { - if (string.IsNullOrWhiteSpace(host)) - return null; - - return host.Trim(); - } - } -} diff --git a/LME.Uaflix/GlobalUsings.cs b/LME.Uaflix/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.Uaflix/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.Uaflix/ModInit.cs b/LME.Uaflix/ModInit.cs index 6848faa..92754f5 100644 --- a/LME.Uaflix/ModInit.cs +++ b/LME.Uaflix/ModInit.cs @@ -85,27 +85,7 @@ namespace LME.Uaflix } // Показувати «уточнити пошук». - RegisterWithSearch("lme_uaflix"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_uaflix"); } public void Dispose() @@ -115,121 +95,17 @@ namespace LME.Uaflix public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; - - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.Uaflix/manifest.json b/LME.Uaflix/manifest.json index e319711..096510b 100644 --- a/LME.Uaflix/manifest.json +++ b/LME.Uaflix/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.Uaflix.ModInit", - "online": "LME.Uaflix.OnlineApi" -} \ No newline at end of file + "online": "LME.Uaflix.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/LME.Unimay/GlobalUsings.cs b/LME.Unimay/GlobalUsings.cs deleted file mode 100644 index 4c00409..0000000 --- a/LME.Unimay/GlobalUsings.cs +++ /dev/null @@ -1,4 +0,0 @@ -global using Shared.Services; -global using Shared.Services.Hybrid; -global using Shared.Models.Base; -global using AppInit = Shared.CoreInit; diff --git a/LME.Unimay/ModInit.cs b/LME.Unimay/ModInit.cs index e0416dc..afd350f 100644 --- a/LME.Unimay/ModInit.cs +++ b/LME.Unimay/ModInit.cs @@ -54,27 +54,7 @@ namespace LME.Unimay Unimay = ModuleInvoke.Init("LME.Unimay", defaults).ToObject(); // Виводити "уточнити пошук" - RegisterWithSearch("lme_unimay"); - } - - private static void RegisterWithSearch(string plugin) - { - try - { - if (CoreInit.conf.online.with_search == null) - return; - - foreach (var item in CoreInit.conf.online.with_search) - { - if (string.Equals(item, plugin, StringComparison.OrdinalIgnoreCase)) - return; - } - - CoreInit.conf.online.with_search.Add(plugin); - } - catch - { - } + OnlineRegistry.RegisterWithSearch("lme_unimay"); } public void Dispose() @@ -84,120 +64,17 @@ namespace LME.Unimay public static class UpdateService { - private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats"; + private static readonly ModuleUpdateService _service = new( + () => ModInit.Settings?.plugin, + () => ModInit.Version); - private static ConnectResponse? Connect = null; - private static DateTime? _connectTime = null; - private static DateTime? _disconnectTime = null; + public static Task ConnectAsync(string host, CancellationToken cancellationToken = default) + => _service.ConnectAsync(host, cancellationToken); - private static readonly TimeSpan _resetInterval = TimeSpan.FromHours(4); - private static Timer? _resetTimer = null; - - private static readonly object _lock = new(); - - public static async Task ConnectAsync(string host, CancellationToken cancellationToken = default) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - lock (_lock) - { - if (_connectTime is not null || Connect?.IsUpdateUnavailable == true) - { - return; - } - - _connectTime = DateTime.UtcNow; - } - - try - { - using var handler = new SocketsHttpHandler - { - SslOptions = new SslClientAuthenticationOptions - { - RemoteCertificateValidationCallback = (_, _, _, _) => true, - EnabledSslProtocols = SslProtocols.Tls12 | SslProtocols.Tls13 - } - }; - - using var client = new HttpClient(handler); - client.Timeout = TimeSpan.FromSeconds(15); - - var request = new - { - Host = host, - Module = ModInit.Settings.plugin, - Version = ModInit.Version, - }; - - var requestJson = JsonConvert.SerializeObject(request, Formatting.None); - var requestContent = new StringContent(requestJson, Encoding.UTF8, MediaTypeNames.Application.Json); - - var response = await client - .PostAsync(_connectUrl, requestContent, cancellationToken) - .ConfigureAwait(false); - - response.EnsureSuccessStatusCode(); - - if (response.Content.Headers.ContentLength > 0) - { - var responseText = await response.Content - .ReadAsStringAsync(cancellationToken) - .ConfigureAwait(false); - - Connect = JsonConvert.DeserializeObject(responseText); - } - - lock (_lock) - { - _resetTimer?.Dispose(); - _resetTimer = null; - - if (Connect?.IsUpdateUnavailable != true) - { - _resetTimer = new Timer(ResetConnectTime, null, _resetInterval, Timeout.InfiniteTimeSpan); - } - else - { - _disconnectTime = Connect?.IsNoiseEnabled == true - ? DateTime.UtcNow.AddHours(Random.Shared.Next(1, 4)) - : DateTime.UtcNow; - } - } - } - catch (Exception) - { - ResetConnectTime(null); - } - } - - private static void ResetConnectTime(object? state) - { - lock (_lock) - { - _connectTime = null; - Connect = null; - - _resetTimer?.Dispose(); - _resetTimer = null; - } - } public static bool IsDisconnected() - { - return _disconnectTime is not null - && DateTime.UtcNow >= _disconnectTime; - } + => _service.IsDisconnected(); public static ActionResult Validate(ActionResult result) - { - return IsDisconnected() - ? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}") - : result; - } + => _service.Validate(result); } - - public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled); } diff --git a/LME.Unimay/manifest.json b/LME.Unimay/manifest.json index 0d922be..7a1483b 100644 --- a/LME.Unimay/manifest.json +++ b/LME.Unimay/manifest.json @@ -2,5 +2,11 @@ "enable": true, "version": 3, "initspace": "LME.Unimay.ModInit", - "online": "LME.Unimay.OnlineApi" -} \ No newline at end of file + "online": "LME.Unimay.OnlineApi", + "syntaxPaths": [ + "../LME.Shared/GlobalUsings.cs", + "../LME.Shared/Online/OnlineRegistry.cs", + "../LME.Shared/Update/ModuleUpdateService.cs", + "../LME.Shared/Apn/ApnHelper.cs" + ] +} diff --git a/README.md b/README.md index c6f8b32..9ef0d32 100644 --- a/README.md +++ b/README.md @@ -1,48 +1,57 @@ -# Ukraine online source for Lampac NextGen +# Lampac Ukraine Modules (`LME.*`) -> **Important:** All modules use the prefix `LME.` (Lampac Modules Extended) to avoid conflicts with Lampac's built-in modules. -> Text names, namespaces, keys in `init.conf`, and routes all use the prefix `LME.`. +Набір українських онлайн-модулів для Lampac NextGen. +Усі модулі використовують префікс `LME.` (Lampac Modules Extended), щоб уникати конфліктів із вбудованими модулями Lampac. -## Sources -### TVShows and Movies +## Навігація -- [x] LME.Uaflix -- [x] LME.Makhno -- [x] LME.StarLight -- [x] LME.KlonFUN -- [x] LME.UafilmME +- [Українська](#ua) +- [English](#en) -### Anime and Dorama -- [x] LME.AnimeON -- [x] LME.Bamboo -- [x] LME.Unimay -- [x] LME.Mikai -- [x] LME.NMoonAnime +## Українська -## Installation +### Доступні модулі -1. Clone the repository: - ```bash - git clone https://github.com/lampame/lampac-ukraine.git . - ``` +**Фільми та серіали** +- `LME.Uaflix` +- `LME.Makhno` +- `LME.StarLight` +- `LME.KlonFUN` +- `LME.UafilmME` +- `LME.JackTor` -2. Move the modules to the correct directory: - - If Lampac is installed system-wide, move the modules to the `module` directory. - - If Lampac is running in Docker, mount the volume: - ```bash - -v /path/to/your/cloned/repo/LME.Uaflix:/lampac/module/LME.Uaflix - ``` +**Аніме та дорами** +- `LME.AnimeON` +- `LME.Bamboo` +- `LME.Unimay` +- `LME.Mikai` +- `LME.NMoonAnime` -## Auto installation +### Ручне встановлення -If Lampac version 148.1 and newer +1. Клонуйте репозиторій: +```bash +git clone https://github.com/lampame/lampac-ukraine.git . +``` -Create or update the module/repository.yaml file +2. Скопіюйте потрібні теки модулів у директорію `module` вашого Lampac. -```YAML +3. Для Docker приклад монтування: +```bash +-v /path/to/lampac-ukraine/LME.Uaflix:/lampac/module/LME.Uaflix +``` + +### Автовстановлення через `repository.yaml` + +Працює у Lampac `148.1+`. + +Створіть або оновіть `module/repository.yaml`: + +```yaml - repository: https://github.com/lampame/lampac-ukraine branch: main modules: + - LME.Shared - LME.AnimeON - LME.Unimay - LME.Mikai @@ -56,48 +65,50 @@ Create or update the module/repository.yaml file - LME.JackTor ``` -branch - optional, default main +Важливо: +- `branch` — необов'язково, за замовчуванням `main`. +- `modules` — необов'язково; якщо не вказано, встановляться всі модулі з репозиторію. +- Якщо ви вказуєте конкретний список `modules`, додавайте `LME.Shared`, бо інші модулі підключають спільні файли через `syntaxPaths`. -modules - optional, if not specified, all modules from the repository will be installed +### Налаштування в `init.conf` -## Init support +Ключ має збігатися з назвою модуля (`LME.XXX`), а не з назвою провайдера. -> **Note:** The key in `init.conf` must match the module name (`LME.XXX`), **not** the provider name. -> For example, for Uaflix, use `“LME.Uaflix”`, not `“Uaflix”`. +Приклад для `LME.Uaflix`: ```json "LME.Uaflix": { - "enable": true, - "domain": "https://uaflix.net", - "displayname": "Uaflix", - "login": null, - "passwd": null, - "cookie": null, - "webcorshost": null, - "streamproxy": false, - "useproxy": false, - "proxy": { - "useAuth": true, - "username": "FooBAR", - "password": "Strong_password", - "list": [ - "socks5://adress:port" - ] - }, - "displayindex": 1, - "magic_apn": { - "ashdi": "https://tut.im/proxy.php?url={encodeurl}" - } + "enable": true, + "domain": "https://uaflix.net", + "displayname": "Uaflix", + "login": null, + "passwd": null, + "cookie": null, + "webcorshost": null, + "streamproxy": false, + "useproxy": false, + "proxy": { + "useAuth": true, + "username": "FooBAR", + "password": "Strong_password", + "list": [ + "socks5://adress:port" + ] + }, + "displayindex": 1, + "magic_apn": { + "ashdi": "https://tut.im/proxy.php?url={encodeurl}" } +} ``` -Parameter compatibility: -- `webcorshost` + `useproxy`: work together (parsing via CORS host, and network output can go through a proxy with `useproxy`). -- `webcorshost` does not conflict with `streamproxy`: CORS is used for parsing, `streamproxy` is used for streaming. -- `magic_apn.ashdi` is used only for Ashdi links and only when the value is not empty. -- `webcorshost` does not conflict with `magic_apn`: CORS is used for parsing, while `magic_apn` is used for Ashdi streaming. +Сумісність параметрів: +- `webcorshost` + `useproxy`: працюють разом (парсинг через CORS-хост, мережевий вихід може йти через проксі). +- `webcorshost` + `streamproxy`: не конфліктують (CORS для парсингу, `streamproxy` для потоків). +- `magic_apn.ashdi` використовується лише для Ashdi-посилань і лише коли значення не порожнє. +- `webcorshost` + `magic_apn`: не конфліктують. -## JackTor config example (`init.conf`) +### Приклад конфігурації `LME.JackTor` ```json "LME.JackTor": { @@ -159,19 +170,98 @@ Parameter compatibility: } ``` -Key parameters at a glance: -- `jackett` + `apikey`: your Jackett host and API key. -- `min_sid` / `min_peers` / `max_size` / `max_serial_size`: base torrent filters. -- `quality_allow`, `hdr_mode`, `codec_allow`, `audio_pref`: quality/codec/language prioritization. -- `torrs`, `auth_torrs`, `base_auth`: TorrServer nodes used for playback. -- `filter` / `filter_ignore`: regex filters for release title and voice labels. +Ключові параметри: +- `jackett` + `apikey`: хост Jackett та API-ключ. +- `min_sid` / `min_peers` / `max_size` / `max_serial_size`: базові фільтри торрентів. +- `quality_allow`, `hdr_mode`, `codec_allow`, `audio_pref`: пріоритезація якості, кодека та мов. +- `torrs`, `auth_torrs`, `base_auth`: вузли TorrServer для відтворення. +- `filter` / `filter_ignore`: regex-фільтри для релізів та озвучок. -## Source/player availability check script +### Скрипт перевірки доступності джерел ```bash wget -O check.sh https://raw.githubusercontent.com/lampame/lampac-ukraine/main/check.sh && sh check.sh ``` -## Donate +### Підтримка + +Підтримати автора: https://lampame.donatik.me + +--- + +## English + +### Available modules + +**TV shows and movies** +- `LME.Uaflix` +- `LME.Makhno` +- `LME.StarLight` +- `LME.KlonFUN` +- `LME.UafilmME` +- `LME.JackTor` + +**Anime and dorama** +- `LME.AnimeON` +- `LME.Bamboo` +- `LME.Unimay` +- `LME.Mikai` +- `LME.NMoonAnime` + +### Manual installation + +1. Clone the repository: +```bash +git clone https://github.com/lampame/lampac-ukraine.git . +``` + +2. Copy required module folders into Lampac `module` directory. + +3. Docker mount example: +```bash +-v /path/to/lampac-ukraine/LME.Uaflix:/lampac/module/LME.Uaflix +``` + +### Auto installation via `repository.yaml` + +Requires Lampac `148.1+`. + +Create or update `module/repository.yaml`: + +```yaml +- repository: https://github.com/lampame/lampac-ukraine + branch: main + modules: + - LME.Shared + - LME.AnimeON + - LME.Unimay + - LME.Mikai + - LME.NMoonAnime + - LME.Uaflix + - LME.Bamboo + - LME.Makhno + - LME.StarLight + - LME.KlonFUN + - LME.UafilmME + - LME.JackTor +``` + +Notes: +- `branch` is optional, default is `main`. +- `modules` is optional; if omitted, all repository modules are installed. +- If you specify an explicit module list, include `LME.Shared` because other modules use shared files through `syntaxPaths`. + +### `init.conf` key rule + +Use module name (`LME.XXX`) as a key, not provider name. +Example: `LME.Uaflix` instead of `Uaflix`. + +### Source/player availability check script + +```bash +wget -O check.sh https://raw.githubusercontent.com/lampame/lampac-ukraine/main/check.sh && sh check.sh +``` + +### Support Support the author: https://lampame.donatik.me