mirror of
https://github.com/lampame/lampac-ukraine.git
synced 2026-04-16 17:32:20 +00:00
Introduce a new configuration option `magic_apn` that allows automatic enabling of APN for Ashdi streams when using the inner player. The configuration is an object with an `ashdi` property that specifies the host to use for Ashdi APN. Changes include: - Add `TryGetMagicAshdiHost` method to parse `magic_apn` configuration - Add `NormalizeHost`
250 lines
8.1 KiB
C#
250 lines
8.1 KiB
C#
using Newtonsoft.Json.Linq;
|
|
using Shared;
|
|
using Shared.Engine;
|
|
using Shared.Models.Online.Settings;
|
|
using Shared.Models.Module;
|
|
using Shared.Models.Module.Interfaces;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Newtonsoft.Json;
|
|
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;
|
|
using Shared.Models.Events;
|
|
|
|
namespace KlonFUN
|
|
{
|
|
public class ModInit : IModuleLoaded
|
|
{
|
|
public static double Version => 2.0;
|
|
|
|
public static ModuleConfig KlonFUN;
|
|
public static bool ApnHostProvided;
|
|
public static string MagicApnAshdiHost;
|
|
|
|
public static ModuleConfig Settings
|
|
{
|
|
get => KlonFUN;
|
|
set => KlonFUN = value;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Модуль завантажено.
|
|
/// </summary>
|
|
public void Loaded(InitspaceModel initspace)
|
|
{
|
|
UpdateConfig();
|
|
EventListener.UpdateInitFile += UpdateConfig;
|
|
|
|
// Додаємо підтримку "уточнити пошук".
|
|
RegisterWithSearch("klonfun");
|
|
}
|
|
|
|
private void UpdateConfig()
|
|
{
|
|
KlonFUN = new ModuleConfig("KlonFUN", "https://klon.fun", streamproxy: false, useproxy: false)
|
|
{
|
|
displayname = "KlonFUN",
|
|
displayindex = 0,
|
|
proxy = new Shared.Models.Base.ProxySettings()
|
|
{
|
|
useAuth = true,
|
|
username = "",
|
|
password = "",
|
|
list = new string[] { "socks5://ip:port" }
|
|
}
|
|
};
|
|
|
|
var defaults = JObject.FromObject(KlonFUN);
|
|
defaults["magic_apn"] = new JObject()
|
|
{
|
|
["ashdi"] = ApnHelper.DefaultHost
|
|
};
|
|
|
|
var conf = ModuleInvoke.Init("KlonFUN", defaults) ?? defaults;
|
|
bool hasApn = ApnHelper.TryGetInitConf(conf, out bool apnEnabled, out string apnHost);
|
|
MagicApnAshdiHost = ApnHelper.TryGetMagicAshdiHost(conf);
|
|
conf.Remove("magic_apn");
|
|
conf.Remove("apn");
|
|
conf.Remove("apn_host");
|
|
KlonFUN = conf.ToObject<ModuleConfig>();
|
|
if (hasApn)
|
|
ApnHelper.ApplyInitConf(apnEnabled, apnHost, KlonFUN);
|
|
ApnHostProvided = ApnHelper.IsEnabled(KlonFUN);
|
|
|
|
if (ApnHostProvided)
|
|
{
|
|
KlonFUN.streamproxy = false;
|
|
}
|
|
else if (KlonFUN.streamproxy)
|
|
{
|
|
KlonFUN.apnstream = false;
|
|
KlonFUN.apn = null;
|
|
}
|
|
}
|
|
|
|
private static void RegisterWithSearch(string plugin)
|
|
{
|
|
try
|
|
{
|
|
var onlineType = Type.GetType("Online.ModInit");
|
|
if (onlineType == null)
|
|
{
|
|
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
|
|
{
|
|
onlineType = asm.GetType("Online.ModInit");
|
|
if (onlineType != null)
|
|
break;
|
|
}
|
|
}
|
|
var confField = onlineType?.GetField("conf", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
|
|
var conf = confField?.GetValue(null);
|
|
var withSearchProp = conf?.GetType().GetProperty("with_search", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance);
|
|
|
|
if (withSearchProp?.GetValue(conf) is System.Collections.IList list)
|
|
{
|
|
foreach (var item in list)
|
|
{
|
|
if (string.Equals(item?.ToString(), plugin, StringComparison.OrdinalIgnoreCase))
|
|
return;
|
|
}
|
|
|
|
list.Add(plugin);
|
|
}
|
|
}
|
|
catch
|
|
{
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
EventListener.UpdateInitFile -= UpdateConfig;
|
|
}
|
|
}
|
|
|
|
public static class UpdateService
|
|
{
|
|
private static readonly string _connectUrl = "https://lmcuk.lme.isroot.in/stats";
|
|
|
|
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<ConnectResponse>(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 bool IsDisconnected()
|
|
{
|
|
return _disconnectTime is not null
|
|
&& DateTime.UtcNow >= _disconnectTime;
|
|
}
|
|
|
|
public static ActionResult Validate(ActionResult result)
|
|
{
|
|
return IsDisconnected()
|
|
? throw new JsonReaderException($"Disconnect error: {Guid.CreateVersion7()}")
|
|
: result;
|
|
}
|
|
}
|
|
|
|
public record ConnectResponse(bool IsUpdateUnavailable, bool IsNoiseEnabled);
|
|
}
|