mirror of
https://github.com/lampame/lampac-ukraine.git
synced 2026-04-16 17:32:20 +00:00
The base64 entry "bGFtcGE=" (decoding to "lampa") was removed from all service configurations across multiple modules. This entry was likely deprecated or no longer needed, as it was consistently removed from the same position in the base64 string arrays across all modified files. The change affects 13 files across different service modules, ensuring consistency in the configuration format.
287 lines
12 KiB
C#
287 lines
12 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
using System.Threading.Tasks;
|
|
using System.Web;
|
|
using Shared;
|
|
using Shared.Engine;
|
|
using Shared.Models;
|
|
using Shared.Models.Online.Settings;
|
|
using StarLight.Models;
|
|
|
|
namespace StarLight
|
|
{
|
|
public class StarLightInvoke
|
|
{
|
|
private const string PlayerApi = "https://vcms-api2.starlight.digital/player-api";
|
|
private const string PlayerReferer = "https://teleportal.ua/";
|
|
private const string Language = "ua";
|
|
private static readonly HashSet<string> NotAllowedHosts =
|
|
new HashSet<string>(
|
|
new[]
|
|
{
|
|
"c3ZpdGFubW92aWU=",
|
|
"cG9ydGFsLXR2",
|
|
}
|
|
.Select(base64 => Encoding.UTF8.GetString(Convert.FromBase64String(base64))),
|
|
StringComparer.OrdinalIgnoreCase
|
|
);
|
|
private readonly OnlinesSettings _init;
|
|
private readonly HybridCache _hybridCache;
|
|
private readonly Action<string> _onLog;
|
|
private readonly ProxyManager _proxyManager;
|
|
|
|
public StarLightInvoke(OnlinesSettings init, HybridCache hybridCache, Action<string> onLog, ProxyManager proxyManager)
|
|
{
|
|
_init = init;
|
|
_hybridCache = hybridCache;
|
|
_onLog = onLog;
|
|
_proxyManager = proxyManager;
|
|
}
|
|
|
|
public async Task<List<SearchResult>> Search(string title, string original_title)
|
|
{
|
|
string query = !string.IsNullOrEmpty(title) ? title : original_title;
|
|
if (string.IsNullOrEmpty(query))
|
|
return null;
|
|
|
|
string memKey = $"StarLight:search:{query}";
|
|
if (_hybridCache.TryGetValue(memKey, out List<SearchResult> cached))
|
|
return cached;
|
|
|
|
string url = $"{_init.host}/{Language}/live-search?q={HttpUtility.UrlEncode(query)}";
|
|
if (IsNotAllowedHost(url))
|
|
return null;
|
|
|
|
var headers = new List<HeadersModel>()
|
|
{
|
|
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
new HeadersModel("Referer", _init.host)
|
|
};
|
|
|
|
try
|
|
{
|
|
_onLog?.Invoke($"StarLight search: {url}");
|
|
string payload = await Http.Get(url, headers: headers, proxy: _proxyManager.Get());
|
|
if (string.IsNullOrEmpty(payload))
|
|
return null;
|
|
|
|
var results = new List<SearchResult>();
|
|
using var document = JsonDocument.Parse(payload);
|
|
if (document.RootElement.ValueKind == JsonValueKind.Array)
|
|
{
|
|
foreach (var item in document.RootElement.EnumerateArray())
|
|
{
|
|
string typeSlug = item.TryGetProperty("typeSlug", out var typeProp) ? typeProp.GetString() : null;
|
|
string channelSlug = item.TryGetProperty("channelSlug", out var channelProp) ? channelProp.GetString() : null;
|
|
string projectSlug = item.TryGetProperty("projectSlug", out var projectProp) ? projectProp.GetString() : null;
|
|
if (string.IsNullOrEmpty(typeSlug) || string.IsNullOrEmpty(channelSlug) || string.IsNullOrEmpty(projectSlug))
|
|
continue;
|
|
|
|
string href = $"{_init.host}/{Language}/{typeSlug}/{channelSlug}/{projectSlug}";
|
|
results.Add(new SearchResult
|
|
{
|
|
Title = item.TryGetProperty("title", out var titleProp) ? titleProp.GetString() : null,
|
|
Type = typeSlug,
|
|
Href = href,
|
|
Channel = channelSlug,
|
|
Project = projectSlug
|
|
});
|
|
}
|
|
}
|
|
|
|
if (results.Count > 0)
|
|
_hybridCache.Set(memKey, results, cacheTime(15, init: _init));
|
|
|
|
return results;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_onLog?.Invoke($"StarLight search error: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task<ProjectInfo> GetProject(string href)
|
|
{
|
|
if (string.IsNullOrEmpty(href))
|
|
return null;
|
|
|
|
string memKey = $"StarLight:project:{href}";
|
|
if (_hybridCache.TryGetValue(memKey, out ProjectInfo cached))
|
|
return cached;
|
|
|
|
var headers = new List<HeadersModel>()
|
|
{
|
|
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
new HeadersModel("Referer", _init.host)
|
|
};
|
|
|
|
try
|
|
{
|
|
if (IsNotAllowedHost(href))
|
|
return null;
|
|
|
|
_onLog?.Invoke($"StarLight project: {href}");
|
|
string payload = await Http.Get(href, headers: headers, proxy: _proxyManager.Get());
|
|
if (string.IsNullOrEmpty(payload))
|
|
return null;
|
|
|
|
using var document = JsonDocument.Parse(payload);
|
|
var root = document.RootElement;
|
|
|
|
var project = new ProjectInfo
|
|
{
|
|
Title = root.TryGetProperty("title", out var titleProp) ? titleProp.GetString() : null,
|
|
Description = root.TryGetProperty("description", out var descProp) ? descProp.GetString() : null,
|
|
Poster = NormalizeImage(root.TryGetProperty("image", out var imageProp) ? imageProp.GetString() : null),
|
|
Hash = root.TryGetProperty("hash", out var hashProp) ? hashProp.GetString() : null,
|
|
Type = root.TryGetProperty("typeSlug", out var typeProp) ? typeProp.GetString() : null,
|
|
Channel = root.TryGetProperty("channelTitle", out var channelProp) ? channelProp.GetString() : null
|
|
};
|
|
|
|
if (root.TryGetProperty("seasonsGallery", out var seasonsProp) && seasonsProp.ValueKind == JsonValueKind.Array)
|
|
{
|
|
foreach (var season in seasonsProp.EnumerateArray())
|
|
{
|
|
string seasonTitle = season.TryGetProperty("title", out var sTitle) ? sTitle.GetString() : null;
|
|
string seasonSlug = season.TryGetProperty("seasonSlug", out var sSlug) ? sSlug.GetString() : null;
|
|
project.Seasons.Add(new SeasonInfo { Title = seasonTitle, Slug = seasonSlug });
|
|
|
|
if (season.TryGetProperty("items", out var itemsProp) && itemsProp.ValueKind == JsonValueKind.Array)
|
|
{
|
|
foreach (var item in itemsProp.EnumerateArray())
|
|
{
|
|
project.Episodes.Add(new EpisodeInfo
|
|
{
|
|
Title = item.TryGetProperty("title", out var eTitle) ? eTitle.GetString() : null,
|
|
Hash = item.TryGetProperty("hash", out var eHash) ? eHash.GetString() : null,
|
|
VideoSlug = item.TryGetProperty("videoSlug", out var eSlug) ? eSlug.GetString() : null,
|
|
Date = item.TryGetProperty("dateOfBroadcast", out var eDate) ? eDate.GetString() : (item.TryGetProperty("timeUploadVideo", out var eDate2) ? eDate2.GetString() : null),
|
|
SeasonSlug = seasonSlug
|
|
});
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
_hybridCache.Set(memKey, project, cacheTime(10, init: _init));
|
|
return project;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_onLog?.Invoke($"StarLight project error: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public List<EpisodeInfo> GetEpisodes(ProjectInfo project, string seasonSlug)
|
|
{
|
|
if (project == null || project.Seasons.Count == 0)
|
|
return new List<EpisodeInfo>();
|
|
|
|
if (string.IsNullOrEmpty(seasonSlug))
|
|
return project.Episodes;
|
|
|
|
return project.Episodes.Where(e => e.SeasonSlug == seasonSlug).ToList();
|
|
}
|
|
|
|
public async Task<StreamResult> ResolveStream(string hash)
|
|
{
|
|
if (string.IsNullOrEmpty(hash))
|
|
return null;
|
|
|
|
string url = $"{PlayerApi}/{hash}?referer={HttpUtility.UrlEncode(PlayerReferer)}&lang={Language}";
|
|
if (IsNotAllowedHost(url))
|
|
return null;
|
|
|
|
var headers = new List<HeadersModel>()
|
|
{
|
|
new HeadersModel("User-Agent", "Mozilla/5.0"),
|
|
new HeadersModel("Referer", PlayerReferer)
|
|
};
|
|
|
|
try
|
|
{
|
|
_onLog?.Invoke($"StarLight stream: {url}");
|
|
string payload = await Http.Get(url, headers: headers, proxy: _proxyManager.Get());
|
|
if (string.IsNullOrEmpty(payload))
|
|
return null;
|
|
|
|
using var document = JsonDocument.Parse(payload);
|
|
var root = document.RootElement;
|
|
|
|
string stream = null;
|
|
if (root.TryGetProperty("video", out var videoProp) && videoProp.ValueKind == JsonValueKind.Array)
|
|
{
|
|
var video = videoProp.EnumerateArray().FirstOrDefault();
|
|
if (video.ValueKind != JsonValueKind.Undefined)
|
|
{
|
|
if (video.TryGetProperty("mediaHlsNoAdv", out var hlsNoAdv))
|
|
stream = hlsNoAdv.GetString();
|
|
if (string.IsNullOrEmpty(stream) && video.TryGetProperty("mediaHls", out var hls))
|
|
stream = hls.GetString();
|
|
if (string.IsNullOrEmpty(stream) && video.TryGetProperty("media", out var mediaProp) && mediaProp.ValueKind == JsonValueKind.Array)
|
|
{
|
|
var media = mediaProp.EnumerateArray().FirstOrDefault();
|
|
if (media.TryGetProperty("url", out var mediaUrl))
|
|
stream = mediaUrl.GetString();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(stream))
|
|
return null;
|
|
|
|
return new StreamResult
|
|
{
|
|
Stream = stream,
|
|
Poster = root.TryGetProperty("poster", out var posterProp) ? posterProp.GetString() : null,
|
|
Name = root.TryGetProperty("name", out var nameProp) ? nameProp.GetString() : null
|
|
};
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
_onLog?.Invoke($"StarLight stream error: {ex.Message}");
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private string NormalizeImage(string path)
|
|
{
|
|
if (string.IsNullOrEmpty(path))
|
|
return string.Empty;
|
|
|
|
if (path.StartsWith("http", StringComparison.OrdinalIgnoreCase))
|
|
return IsNotAllowedHost(path) ? string.Empty : path;
|
|
|
|
return IsNotAllowedHost(_init.host) ? string.Empty : $"{_init.host}{path}";
|
|
}
|
|
|
|
private static bool IsNotAllowedHost(string url)
|
|
{
|
|
if (string.IsNullOrEmpty(url))
|
|
return false;
|
|
|
|
if (!Uri.TryCreate(url, UriKind.Absolute, out var uri))
|
|
return false;
|
|
|
|
return NotAllowedHosts.Contains(uri.Host);
|
|
}
|
|
|
|
public static TimeSpan cacheTime(int multiaccess, int home = 5, int mikrotik = 2, OnlinesSettings init = null, int rhub = -1)
|
|
{
|
|
if (init != null && init.rhub && rhub != -1)
|
|
return TimeSpan.FromMinutes(rhub);
|
|
|
|
int ctime = AppInit.conf.mikrotik ? mikrotik : AppInit.conf.multiaccess ? init != null && init.cache_time > 0 ? init.cache_time : multiaccess : home;
|
|
if (ctime > multiaccess)
|
|
ctime = multiaccess;
|
|
|
|
return TimeSpan.FromMinutes(ctime);
|
|
}
|
|
}
|
|
}
|