Additions for Astra's SGT.
This commit is contained in:
parent
bc4562cd52
commit
58e6dc00d2
1
.gitignore
vendored
1
.gitignore
vendored
@ -108,3 +108,4 @@ imgui.ini
|
||||
/skyscraper8/obj
|
||||
/GUIs/skyscraper8.UI.ImGui/bin/Debug/net8.0/skyscraper5.ini
|
||||
/.vs/skyscraper8/CopilotIndices/17.14.698.11175
|
||||
/GUIs/skyscraper8.UI.ImGui/bin/Debug/net8.0
|
||||
|
||||
@ -18,9 +18,13 @@ namespace skyscraper5.Ard
|
||||
public ArdVpsDescriptor(byte[] buffer)
|
||||
{
|
||||
if (buffer.Length != 13)
|
||||
{
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
VpsString = Encoding.UTF8.GetString(buffer);
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
public string VpsString { get; private set; }
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Skyscraper.IO;
|
||||
using skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants;
|
||||
using skyscraper8.Ses;
|
||||
using skyscraper8.Tests.ClassDependencies.AsraBarkerTransponderTests;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
@ -13,7 +14,7 @@ namespace skyscraper8.Tests
|
||||
{
|
||||
public class AstraBarkerTransponderTests
|
||||
{
|
||||
private const string BARKER_TRANSPONDER_FILE_PATH = "Z:\\Freebies\\Datasets\\SkyscraperLibrarian\\DVB-S Mai 2025\\sgt-000000.ts";
|
||||
private const string BARKER_TRANSPONDER_FILE_PATH = "C:\\Temp\\Astra1_12604_v_SGT-000000.ts";
|
||||
private Stream GetBarkerTransponder()
|
||||
{
|
||||
FileInfo fi = new FileInfo(BARKER_TRANSPONDER_FILE_PATH);
|
||||
@ -39,7 +40,6 @@ namespace skyscraper8.Tests
|
||||
{
|
||||
descriptorUnpacker.SetUserDefined(i, true);
|
||||
}
|
||||
|
||||
descriptorUnpacker.SetUserDefined(0xfe, true);
|
||||
|
||||
TsContext tsContext = new TsContext();
|
||||
@ -57,5 +57,46 @@ namespace skyscraper8.Tests
|
||||
}
|
||||
stream.Close();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void TestAstraLcn()
|
||||
{
|
||||
Stream stream = GetBarkerTransponder();
|
||||
if (stream == null)
|
||||
return;
|
||||
|
||||
SgtCandidate contestant = new SgtCandidate(0x0777);
|
||||
SgtCandidate contestant2 = new SgtCandidate(0x0776);
|
||||
|
||||
TsDescriptorUnpacker descriptorUnpacker = TsDescriptorUnpacker.GetInstance();
|
||||
for (byte i = 0x80; i < 0xfe; i++)
|
||||
{
|
||||
descriptorUnpacker.SetUserDefined(i, true);
|
||||
}
|
||||
descriptorUnpacker.SetUserDefined(0xfe, true);
|
||||
|
||||
TsContext tsContext = new TsContext();
|
||||
tsContext.FilterChain = new List<skyscraper5.src.Mpeg2.PacketFilter.IPacketFilter>();
|
||||
tsContext.FilterChain.Add(new DummyFilter());
|
||||
tsContext.RegisterPacketProcessor(0x0777, contestant.PacketProcessor);
|
||||
tsContext.RegisterPacketProcessor(0x0776, contestant2.PacketProcessor);
|
||||
|
||||
byte[] buffer = new byte[188];
|
||||
while (stream.GetAvailableBytes() >= 188)
|
||||
{
|
||||
stream.Read(buffer, 0, 188);
|
||||
tsContext.PushPacket(buffer);
|
||||
bool winnerA = contestant.Score >= 10;
|
||||
bool winnerB = contestant2.Score >= 10;
|
||||
if (winnerA)
|
||||
{
|
||||
if (winnerB)
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
stream.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ using skyscraper5.Mpeg2.Psi.Model;
|
||||
using skyscraper5.Skyscraper.IO;
|
||||
using skyscraper5.Skyscraper.Scraper;
|
||||
using skyscraper5.Skyscraper.Scraper.Utils;
|
||||
using Tsubasa.IO;
|
||||
|
||||
namespace skyscraper5.Dvb.DataBroadcasting
|
||||
{
|
||||
@ -210,7 +211,10 @@ namespace skyscraper5.Dvb.DataBroadcasting
|
||||
vfs.DirectoriesCreated = 0;
|
||||
ObjectCarouselUtilities.ExtractBiopModule(module, assembledStream, vfs);
|
||||
if (vfs.DirectoriesCreated != 0)
|
||||
{
|
||||
eventHandler.PreventDsmCcModuleRepetition(programMappingStream.ElementaryPid, module.ModuleId, module.ModuleVersion);
|
||||
eventHandler.ProcessVirtualFilesystem((IFilesystem)vfs, programMappingStream);
|
||||
}
|
||||
return;
|
||||
}
|
||||
eventHandler.NotifyDownloadComplete(programMappingStream.ElementaryPid, module.ModuleId, module.ModuleVersion, assembledStream, isObjectCarousel);
|
||||
|
||||
@ -6,7 +6,9 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using skyscraper5.DsmCc.Descriptors;
|
||||
using skyscraper5.DsmCc.Message;
|
||||
using skyscraper5.Dvb.DataBroadcasting.Biop;
|
||||
using skyscraper5.Mpeg2.Psi.Model;
|
||||
using Tsubasa.IO;
|
||||
|
||||
namespace skyscraper5.Dvb.DataBroadcasting
|
||||
{
|
||||
@ -19,5 +21,6 @@ namespace skyscraper5.Dvb.DataBroadcasting
|
||||
void NotifyDownloadComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion, Stream result, bool isObjectCarousel);
|
||||
void DsmCcDoItNowEvent(ProgramMapping programMapping, StreamEventDescriptor descriptorListStreamEventDescriptor, int sourcePid);
|
||||
void PreventDsmCcModuleRepetition(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion);
|
||||
void ProcessVirtualFilesystem(IFilesystem vfs, ProgramMappingStream programMappingStream);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,10 +4,11 @@ using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using skyscraper5.Mpeg2.Psi.Model;
|
||||
using Tsubasa.IO;
|
||||
|
||||
namespace skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs
|
||||
{
|
||||
class ObjectCarouselMetadata
|
||||
class ObjectCarouselMetadata : IFilesystem
|
||||
{
|
||||
public ObjectCarouselMetadata(ObjectCarouselEventHandler eventHandler, int sourcePid, ProgramMapping programMapping)
|
||||
{
|
||||
@ -28,5 +29,53 @@ namespace skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs
|
||||
public ProgramMapping ProgramMapping { get; private set; }
|
||||
public int LastExtractions { get; set; }
|
||||
public int DirectoriesCreated { get; set; }
|
||||
|
||||
#region yo3explorer Driver
|
||||
private string[] _wrappedFileList;
|
||||
public string[] FileList
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_wrappedFileList == null)
|
||||
{
|
||||
_wrappedFileList = vfsFiles.Select(x => x.ToString()).ToArray();
|
||||
}
|
||||
return _wrappedFileList;
|
||||
}
|
||||
}
|
||||
|
||||
public string FilesystemName
|
||||
{
|
||||
get
|
||||
{
|
||||
return string.Format("DSM-CC Object Carousel;{0};", SourcePid);
|
||||
}
|
||||
}
|
||||
|
||||
public bool FileExists(string filename)
|
||||
{
|
||||
foreach (VfsFile file in vfsFiles)
|
||||
{
|
||||
if (file.ToString().Equals(filename))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public byte[] GetFile(string filename)
|
||||
{
|
||||
foreach (VfsFile file in vfsFiles)
|
||||
{
|
||||
if (file.ToString().Equals(filename))
|
||||
return file.FileContent;
|
||||
}
|
||||
throw new FileNotFoundException(filename);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,7 @@ using skyscraper5.Skyscraper.Text;
|
||||
namespace skyscraper5.Dvb.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[TsDescriptor(0x48,"SDT")]
|
||||
[TsDescriptor(0x48,"SDT","Astra SGT")]
|
||||
[BannedTable("TSDT","PMT")]
|
||||
public class ServiceDescriptor : TsDescriptor
|
||||
{
|
||||
@ -68,6 +68,8 @@ namespace skyscraper5.Dvb.Descriptors
|
||||
H264StereoscopicHdNvodRefence = 0x1e,
|
||||
TV_HEVC = 0x1f,
|
||||
_4KTV_HEVC = 0x20,
|
||||
VVC = 0x21,
|
||||
AVS3 = 0x22
|
||||
}
|
||||
|
||||
public override byte[] Serialize()
|
||||
|
||||
@ -10,9 +10,9 @@ using skyscraper5.Skyscraper.Plugins;
|
||||
namespace skyscraper5.Dvb.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[TsDescriptor(0x49,"BAT","SDT")]
|
||||
[TsDescriptor(0x49,"BAT","SDT","Astra SGT")]
|
||||
[BannedTable("PMT","TSDT")]
|
||||
class CountryAvailabilityDescriptor : TsDescriptor
|
||||
public class CountryAvailabilityDescriptor : TsDescriptor
|
||||
{
|
||||
public CountryAvailabilityDescriptor(byte[] buffer)
|
||||
{
|
||||
|
||||
@ -11,7 +11,7 @@ using skyscraper5.Skyscraper.Plugins;
|
||||
namespace skyscraper5.Dvb.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[TsDescriptor(0x53,"BAT","SDT","EIT")]
|
||||
[TsDescriptor(0x53,"BAT","SDT","EIT","Astra SGT")]
|
||||
[BannedTable("TSDT")]
|
||||
class CaIdentifierDescriptor : TsDescriptor
|
||||
{
|
||||
|
||||
@ -9,7 +9,7 @@ using skyscraper5.Skyscraper.Plugins;
|
||||
namespace skyscraper5.Dvb.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[TsDescriptor(0x5f,"NIT","BAT","SDT","EIT","PMT")]
|
||||
[TsDescriptor(0x5f,"NIT","BAT","SDT","EIT","PMT", "Astra SGT")]
|
||||
[BannedTable("CAT")] // <-- Scientific Atlanta is known to put private_data_specifier_descriptors into the CAT, however this is a private extension.
|
||||
public class PrivateDataSpecifierDescriptor : TsDescriptor
|
||||
{
|
||||
|
||||
@ -49,7 +49,7 @@ namespace skyscraper5.Dvb
|
||||
|
||||
private IReadOnlyDictionary<UserDefinedDescriptorAttribute, ConstructorInfo> constructors;
|
||||
|
||||
public TsDescriptor UnpackUserDefinedDescriptor(UserDefinedDescriptor userDefinedDescriptor, uint privateDataSpecifier, string lookupTable)
|
||||
public TsDescriptor UnpackUserDefinedDescriptor(UserDefinedDescriptor userDefinedDescriptor, uint privateDataSpecifier, string lookupTable, bool crashOnMissingDescriptor = false)
|
||||
{
|
||||
if (constructors == null)
|
||||
constructors = PluginManager.GetInstance().GetUserDefinedDescriptors();
|
||||
@ -69,6 +69,10 @@ namespace skyscraper5.Dvb
|
||||
return (TsDescriptor)constructorInfo.Invoke(new object[] { userDefinedDescriptor.Data });
|
||||
}
|
||||
WarnMissingDescriptor(userDefinedDescriptor.DescriptorTag, privateDataSpecifier);
|
||||
if (crashOnMissingDescriptor)
|
||||
{
|
||||
throw new NotImplementedException(String.Format("Missing Descriptor 0x{0:X2} from private data specifier 0x{1:X8} in {2}", userDefinedDescriptor.DescriptorTag, privateDataSpecifier, lookupTable));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
37
skyscraper8/DvbI/DvbIFilesystemProcessor.cs
Normal file
37
skyscraper8/DvbI/DvbIFilesystemProcessor.cs
Normal file
@ -0,0 +1,37 @@
|
||||
using skyscraper5.Skyscraper.Plugins;
|
||||
using skyscraper8.yo3explorer;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
using Tsubasa.IO;
|
||||
using moe.yo3explorer.skyscraper8.DVBI.Model;
|
||||
|
||||
namespace skyscraper8.DvbI
|
||||
{
|
||||
/// <summary>
|
||||
/// See https://www.tara-systems.de/wp-content/uploads/2024/08/DVB-I_Instant_Channel_List_Setup_IBC2024.pdf
|
||||
/// There is no official specification for this.
|
||||
/// This is a best guess reverse engineering of the DVB-I link found on 12,604/H on Astra 19,2°
|
||||
/// </summary>
|
||||
[SkyscraperPlugin]
|
||||
internal class DvbIFilesystemProcessor : FilesystemProcessorPlugin
|
||||
{
|
||||
private const string INDEX_FILENAME = "\\DVB-I_slep.xml";
|
||||
|
||||
private XmlSerializer serviceListEntryPointSerializer;
|
||||
|
||||
public void ProcessFilesystem(IFilesystem vfs, yo3explorerToSkyscraperContextBridge context, yo3explorerState state)
|
||||
{
|
||||
if (!vfs.FileExists(INDEX_FILENAME))
|
||||
return;
|
||||
|
||||
byte[] slepBytes = vfs.GetFile(INDEX_FILENAME);
|
||||
ServiceListEntryPoints serviceListEntryPoints = DvbIUtils.UnpackServiceListEntryPoints(slepBytes);
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
28
skyscraper8/DvbI/DvbIUtils.cs
Normal file
28
skyscraper8/DvbI/DvbIUtils.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using moe.yo3explorer.skyscraper8.DVBI.Model;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace skyscraper8.DvbI
|
||||
{
|
||||
internal class DvbIUtils
|
||||
{
|
||||
private DvbIUtils() { }
|
||||
|
||||
private static XmlSerializer serviceListEntryPointSerializer;
|
||||
|
||||
public static ServiceListEntryPoints UnpackServiceListEntryPoints(byte[] buffer)
|
||||
{
|
||||
if (serviceListEntryPointSerializer == null)
|
||||
serviceListEntryPointSerializer = new XmlSerializer(typeof(ServiceListEntryPoints));
|
||||
|
||||
MemoryStream slepStream = new MemoryStream(buffer, false);
|
||||
object slepWrapped = serviceListEntryPointSerializer.Deserialize(slepStream);
|
||||
ServiceListEntryPoints serviceListEntryPoint = (ServiceListEntryPoints)slepWrapped;
|
||||
return serviceListEntryPoint;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,446 @@
|
||||
//------------------------------------------------------------------------------
|
||||
// <auto-generated>
|
||||
// This code was generated by a tool.
|
||||
// Runtime Version:4.0.30319.42000
|
||||
//
|
||||
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
// the code is regenerated.
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// This source code was auto-generated by xsd, Version=4.8.9037.0.
|
||||
//
|
||||
namespace moe.yo3explorer.skyscraper8.DVBI.Model {
|
||||
using System.Xml.Serialization;
|
||||
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:dvb:metadata:servicelistdiscovery:2024", IsNullable=false)]
|
||||
public partial class ServiceListEntryPoints {
|
||||
|
||||
private ServiceListEntryPointsServiceListRegistryEntity[] serviceListRegistryEntityField;
|
||||
|
||||
private ServiceListEntryPointsProviderOffering[] providerOfferingField;
|
||||
|
||||
private string langField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("ServiceListRegistryEntity")]
|
||||
public ServiceListEntryPointsServiceListRegistryEntity[] ServiceListRegistryEntity {
|
||||
get {
|
||||
return this.serviceListRegistryEntityField;
|
||||
}
|
||||
set {
|
||||
this.serviceListRegistryEntityField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("ProviderOffering")]
|
||||
public ServiceListEntryPointsProviderOffering[] ProviderOffering {
|
||||
get {
|
||||
return this.providerOfferingField;
|
||||
}
|
||||
set {
|
||||
this.providerOfferingField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttributeAttribute(Form=System.Xml.Schema.XmlSchemaForm.Qualified, Namespace="http://www.w3.org/XML/1998/namespace")]
|
||||
public string lang {
|
||||
get {
|
||||
return this.langField;
|
||||
}
|
||||
set {
|
||||
this.langField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsServiceListRegistryEntity {
|
||||
|
||||
private string nameField;
|
||||
|
||||
/// <remarks/>
|
||||
public string Name {
|
||||
get {
|
||||
return this.nameField;
|
||||
}
|
||||
set {
|
||||
this.nameField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsProviderOffering {
|
||||
|
||||
private ServiceListEntryPointsProviderOfferingProvider[] providerField;
|
||||
|
||||
private ServiceListEntryPointsProviderOfferingServiceListOffering[] serviceListOfferingField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("Provider")]
|
||||
public ServiceListEntryPointsProviderOfferingProvider[] Provider {
|
||||
get {
|
||||
return this.providerField;
|
||||
}
|
||||
set {
|
||||
this.providerField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("ServiceListOffering")]
|
||||
public ServiceListEntryPointsProviderOfferingServiceListOffering[] ServiceListOffering {
|
||||
get {
|
||||
return this.serviceListOfferingField;
|
||||
}
|
||||
set {
|
||||
this.serviceListOfferingField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsProviderOfferingProvider {
|
||||
|
||||
private string nameField;
|
||||
|
||||
/// <remarks/>
|
||||
public string Name {
|
||||
get {
|
||||
return this.nameField;
|
||||
}
|
||||
set {
|
||||
this.nameField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsProviderOfferingServiceListOffering {
|
||||
|
||||
private string serviceListNameField;
|
||||
|
||||
private string serviceListIdField;
|
||||
|
||||
private ServiceListEntryPointsProviderOfferingServiceListOfferingServiceListURI[] serviceListURIField;
|
||||
|
||||
private ServiceListEntryPointsProviderOfferingServiceListOfferingDelivery[] deliveryField;
|
||||
|
||||
private RelatedMaterial relatedMaterialField;
|
||||
|
||||
/// <remarks/>
|
||||
public string ServiceListName {
|
||||
get {
|
||||
return this.serviceListNameField;
|
||||
}
|
||||
set {
|
||||
this.serviceListNameField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
public string ServiceListId {
|
||||
get {
|
||||
return this.serviceListIdField;
|
||||
}
|
||||
set {
|
||||
this.serviceListIdField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("ServiceListURI")]
|
||||
public ServiceListEntryPointsProviderOfferingServiceListOfferingServiceListURI[] ServiceListURI {
|
||||
get {
|
||||
return this.serviceListURIField;
|
||||
}
|
||||
set {
|
||||
this.serviceListURIField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("Delivery")]
|
||||
public ServiceListEntryPointsProviderOfferingServiceListOfferingDelivery[] Delivery {
|
||||
get {
|
||||
return this.deliveryField;
|
||||
}
|
||||
set {
|
||||
this.deliveryField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute(Namespace="urn:dvb:metadata:servicediscovery-types:2023")]
|
||||
public RelatedMaterial RelatedMaterial {
|
||||
get {
|
||||
return this.relatedMaterialField;
|
||||
}
|
||||
set {
|
||||
this.relatedMaterialField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsProviderOfferingServiceListOfferingServiceListURI {
|
||||
|
||||
private string uRIField;
|
||||
|
||||
private string contentTypeField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute(Namespace="urn:dvb:metadata:servicediscovery-types:2023")]
|
||||
public string URI {
|
||||
get {
|
||||
return this.uRIField;
|
||||
}
|
||||
set {
|
||||
this.uRIField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttributeAttribute()]
|
||||
public string contentType {
|
||||
get {
|
||||
return this.contentTypeField;
|
||||
}
|
||||
set {
|
||||
this.contentTypeField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsProviderOfferingServiceListOfferingDelivery {
|
||||
|
||||
private string dASHDeliveryField;
|
||||
|
||||
private ServiceListEntryPointsProviderOfferingServiceListOfferingDeliveryDVBSDelivery[] dVBSDeliveryField;
|
||||
|
||||
/// <remarks/>
|
||||
public string DASHDelivery {
|
||||
get {
|
||||
return this.dASHDeliveryField;
|
||||
}
|
||||
set {
|
||||
this.dASHDeliveryField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("DVBSDelivery")]
|
||||
public ServiceListEntryPointsProviderOfferingServiceListOfferingDeliveryDVBSDelivery[] DVBSDelivery {
|
||||
get {
|
||||
return this.dVBSDeliveryField;
|
||||
}
|
||||
set {
|
||||
this.dVBSDeliveryField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
public partial class ServiceListEntryPointsProviderOfferingServiceListOfferingDeliveryDVBSDelivery {
|
||||
|
||||
private string orbitalPositionField;
|
||||
|
||||
/// <remarks/>
|
||||
public string OrbitalPosition {
|
||||
get {
|
||||
return this.orbitalPositionField;
|
||||
}
|
||||
set {
|
||||
this.orbitalPositionField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicediscovery-types:2023")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:dvb:metadata:servicediscovery-types:2023", IsNullable=false)]
|
||||
public partial class RelatedMaterial {
|
||||
|
||||
private HowRelated howRelatedField;
|
||||
|
||||
private MediaLocatorMediaUri[] mediaLocatorField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute(Namespace="urn:tva:metadata:2024")]
|
||||
public HowRelated HowRelated {
|
||||
get {
|
||||
return this.howRelatedField;
|
||||
}
|
||||
set {
|
||||
this.howRelatedField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlArrayAttribute(Namespace="urn:tva:metadata:2024")]
|
||||
[System.Xml.Serialization.XmlArrayItemAttribute("MediaUri")]
|
||||
public MediaLocatorMediaUri[] MediaLocator {
|
||||
get {
|
||||
return this.mediaLocatorField;
|
||||
}
|
||||
set {
|
||||
this.mediaLocatorField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:tva:metadata:2024")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:tva:metadata:2024", IsNullable=false)]
|
||||
public partial class HowRelated {
|
||||
|
||||
private string hrefField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttributeAttribute()]
|
||||
public string href {
|
||||
get {
|
||||
return this.hrefField;
|
||||
}
|
||||
set {
|
||||
this.hrefField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:tva:metadata:2024")]
|
||||
public partial class MediaLocatorMediaUri {
|
||||
|
||||
private string contentTypeField;
|
||||
|
||||
private string valueField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlAttributeAttribute()]
|
||||
public string contentType {
|
||||
get {
|
||||
return this.contentTypeField;
|
||||
}
|
||||
set {
|
||||
this.contentTypeField = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlTextAttribute()]
|
||||
public string Value {
|
||||
get {
|
||||
return this.valueField;
|
||||
}
|
||||
set {
|
||||
this.valueField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:dvb:metadata:servicelistdiscovery:2024")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:dvb:metadata:servicelistdiscovery:2024", IsNullable=false)]
|
||||
public partial class NewDataSet {
|
||||
|
||||
private ServiceListEntryPoints[] itemsField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("ServiceListEntryPoints")]
|
||||
public ServiceListEntryPoints[] Items {
|
||||
get {
|
||||
return this.itemsField;
|
||||
}
|
||||
set {
|
||||
this.itemsField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <remarks/>
|
||||
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "4.8.9037.0")]
|
||||
[System.SerializableAttribute()]
|
||||
[System.Diagnostics.DebuggerStepThroughAttribute()]
|
||||
[System.ComponentModel.DesignerCategoryAttribute("code")]
|
||||
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="urn:tva:metadata:2024")]
|
||||
[System.Xml.Serialization.XmlRootAttribute(Namespace="urn:tva:metadata:2024", IsNullable=false)]
|
||||
public partial class MediaLocator {
|
||||
|
||||
private MediaLocatorMediaUri[] mediaUriField;
|
||||
|
||||
/// <remarks/>
|
||||
[System.Xml.Serialization.XmlElementAttribute("MediaUri", IsNullable=true)]
|
||||
public MediaLocatorMediaUri[] MediaUri {
|
||||
get {
|
||||
return this.mediaUriField;
|
||||
}
|
||||
set {
|
||||
this.mediaUriField = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
"profiles": {
|
||||
"skyscraper8": {
|
||||
"commandName": "Project",
|
||||
"commandLineArgs": "\"Z:\\Freebies\\Datasets\\SkyscraperLibrarian\\DVB-S Mai 2025\\sgt-000000.ts\"",
|
||||
"commandLineArgs": "\"C:\\Temp\\Astra1_12604_v_SGT-000000.ts\"",
|
||||
"remoteDebugEnabled": false
|
||||
},
|
||||
"Container (Dockerfile)": {
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
using skyscraper5.Dvb;
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Skyscraper.Plugins;
|
||||
using skyscraper5.Skyscraper.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[UserDefinedDescriptor(0x01, 0x88, "Astra SGT")]
|
||||
internal class _0x88_ServiceListNameDescriptor : TsDescriptor
|
||||
{
|
||||
public _0x88_ServiceListNameDescriptor(byte[] buffer)
|
||||
{
|
||||
LanguageCode = Encoding.ASCII.GetString(buffer, 0, 3);
|
||||
TextualDescription = En300468AnnexATextDecoder.GetInstance().Decode(buffer, 3, buffer.Length - 3);
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
public string LanguageCode { get; }
|
||||
public string TextualDescription { get; }
|
||||
}
|
||||
}
|
||||
46
skyscraper8/Ses/Descriptors/0x93_BouquetListDescriptor.cs
Normal file
46
skyscraper8/Ses/Descriptors/0x93_BouquetListDescriptor.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using skyscraper5.Dvb;
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Skyscraper.IO;
|
||||
using skyscraper5.Skyscraper.Plugins;
|
||||
using skyscraper5.Skyscraper.Text;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[UserDefinedDescriptor(0x01, 0x93, "Astra SGT")]
|
||||
internal class _0x93_BouquetListDescriptor : TsDescriptor
|
||||
{
|
||||
public _0x93_BouquetListDescriptor(byte[] buffer)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream(buffer, false);
|
||||
while (ms.GetAvailableBytes() >= 1)
|
||||
{
|
||||
byte bouquetNameLength = ms.ReadUInt8();
|
||||
if (bouquetNameLength != 0)
|
||||
{
|
||||
byte[] chars = ms.ReadBytes(bouquetNameLength);
|
||||
string chars2 = En300468AnnexATextDecoder.GetInstance().Decode(chars);
|
||||
if (!string.IsNullOrEmpty(chars2))
|
||||
{
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
{
|
||||
Name = chars2;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new NotImplementedException("multiple bouquet names");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
public string Name { get; private set; }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,31 @@
|
||||
using skyscraper5.Dvb;
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Skyscraper.Plugins;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses.Descriptors
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
[UserDefinedDescriptor(0x01, 0xD1, "Astra SGT")]
|
||||
internal class _0xD1_VirtualServiceIdDescriptor : TsDescriptor
|
||||
{
|
||||
public _0xD1_VirtualServiceIdDescriptor(byte[] buffer)
|
||||
{
|
||||
if (buffer.Length < 2)
|
||||
{
|
||||
Valid = false;
|
||||
return;
|
||||
}
|
||||
|
||||
(buffer[1], buffer[0]) = (buffer[0], buffer[1]);
|
||||
VirtualServiceId = BitConverter.ToUInt16(buffer, 0);
|
||||
Valid = true;
|
||||
}
|
||||
|
||||
public ushort VirtualServiceId { get; }
|
||||
}
|
||||
}
|
||||
48
skyscraper8/Ses/SgtCandidate.cs
Normal file
48
skyscraper8/Ses/SgtCandidate.cs
Normal file
@ -0,0 +1,48 @@
|
||||
using skyscraper5.Mhp.Si;
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Skyscraper.Plugins;
|
||||
using skyscraper5.Skyscraper.Scraper;
|
||||
using skyscraper5.Skyscraper.Scraper.StreamAutodetection;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses
|
||||
{
|
||||
[SkyscraperPlugin]
|
||||
public class SgtCandidate : Contestant, SgtEventHandler, IDisposable
|
||||
{
|
||||
public SgtCandidate(int pid)
|
||||
: base("Asta SGT",pid)
|
||||
{
|
||||
PacketProcessor = new PsiDecoder(pid, new SgtParser(this));
|
||||
}
|
||||
|
||||
public override void DeclareWinner(SkyscraperContext skyscraperContext, int pid, ProgramContext programContext)
|
||||
{
|
||||
skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new SgtParser(skyscraperContext)));
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
}
|
||||
|
||||
void SgtEventHandler.AnnounceSgtList(SgtList list)
|
||||
{
|
||||
if (list.CountryAvailabilities.Count > 0 || list.Names != null || list.PrivateDataSpecifier != 0x01)
|
||||
Score++;
|
||||
}
|
||||
|
||||
void SgtEventHandler.OnSgtError(SgtError invalidTableId)
|
||||
{
|
||||
Score--;
|
||||
}
|
||||
|
||||
void SgtEventHandler.OnSgtService(SgtService child)
|
||||
{
|
||||
Score++;
|
||||
}
|
||||
}
|
||||
}
|
||||
14
skyscraper8/Ses/SgtError.cs
Normal file
14
skyscraper8/Ses/SgtError.cs
Normal file
@ -0,0 +1,14 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses
|
||||
{
|
||||
internal enum SgtError
|
||||
{
|
||||
InvalidTableId,
|
||||
NoSectionSyntax
|
||||
}
|
||||
}
|
||||
15
skyscraper8/Ses/SgtEventHandler.cs
Normal file
15
skyscraper8/Ses/SgtEventHandler.cs
Normal file
@ -0,0 +1,15 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses
|
||||
{
|
||||
internal interface SgtEventHandler
|
||||
{
|
||||
void AnnounceSgtList(SgtList list);
|
||||
void OnSgtError(SgtError invalidTableId);
|
||||
void OnSgtService(SgtService child);
|
||||
}
|
||||
}
|
||||
46
skyscraper8/Ses/SgtList.cs
Normal file
46
skyscraper8/Ses/SgtList.cs
Normal file
@ -0,0 +1,46 @@
|
||||
using skyscraper5.Dvb.Descriptors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses
|
||||
{
|
||||
public class SgtList
|
||||
{
|
||||
public SgtList(ushort serviceListId, uint v)
|
||||
{
|
||||
ServiceListId = serviceListId;
|
||||
PrivateDataSpecifier = v;
|
||||
CountryAvailabilities = new Dictionary<string, bool>();
|
||||
}
|
||||
|
||||
public ushort ServiceListId { get; }
|
||||
public uint PrivateDataSpecifier { get; internal set; }
|
||||
|
||||
public Dictionary<string,string> Names { get; internal set; }
|
||||
public Dictionary<string,bool> CountryAvailabilities { get; internal set; }
|
||||
|
||||
public string GetName()
|
||||
{
|
||||
if (Names == null)
|
||||
return "???";
|
||||
|
||||
if (Names.Count == 0)
|
||||
return "???";
|
||||
|
||||
foreach (KeyValuePair<string,string> name in Names)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(name.Value))
|
||||
{
|
||||
return name.Value;
|
||||
}
|
||||
}
|
||||
return "???";
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
184
skyscraper8/Ses/SgtParser.cs
Normal file
184
skyscraper8/Ses/SgtParser.cs
Normal file
@ -0,0 +1,184 @@
|
||||
using skyscraper5.Dvb;
|
||||
using skyscraper5.Dvb.Descriptors;
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Mpeg2.Descriptors;
|
||||
using skyscraper5.Skyscraper.IO;
|
||||
using skyscraper8.Ses.Descriptors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using static skyscraper5.Dvb.Descriptors.ContentIdentifierDescriptor;
|
||||
|
||||
namespace skyscraper8.Ses
|
||||
{
|
||||
internal class SgtParser : IPsiProcessor
|
||||
{
|
||||
public SgtParser(SgtEventHandler eventHandler)
|
||||
{
|
||||
this.EventHandler = eventHandler;
|
||||
}
|
||||
|
||||
public SgtEventHandler EventHandler { get; }
|
||||
|
||||
public void GatherPsi(PsiSection section, int sourcePid)
|
||||
{
|
||||
byte[] buffer = section.GetData();
|
||||
MemoryStream ms = new MemoryStream(buffer, false);
|
||||
|
||||
byte table_id = ms.ReadUInt8();
|
||||
if (table_id != 0x91)
|
||||
{
|
||||
EventHandler.OnSgtError(SgtError.InvalidTableId);
|
||||
return;
|
||||
}
|
||||
|
||||
byte byteA = ms.ReadUInt8();
|
||||
bool sectionSyntaxIndicator = (byteA & 0x80) != 0;
|
||||
if (!sectionSyntaxIndicator)
|
||||
{
|
||||
EventHandler.OnSgtError(SgtError.NoSectionSyntax);
|
||||
return;
|
||||
}
|
||||
bool reservedFutureUse = (byteA & 0x40) != 0;
|
||||
int reserved = (byteA & 0x30) >> 4;
|
||||
int sectionLength = (byteA & 0x0f);
|
||||
sectionLength <<= 4;
|
||||
sectionLength += ms.ReadUInt8();
|
||||
|
||||
ushort serviceListId = ms.ReadUInt16BE();
|
||||
|
||||
byte byteB = ms.ReadUInt8();
|
||||
int reservedB = (byteA & 0xc0) >> 6;
|
||||
int versionNumber = (byteA & 0x3e) >> 1;
|
||||
bool currentNextIndicator = (byteB & 0x01) != 0;
|
||||
|
||||
byte sectionNumber = ms.ReadUInt8();
|
||||
byte lastSectionNumber = ms.ReadUInt8();
|
||||
ushort ReservedC = ms.ReadUInt16BE();
|
||||
|
||||
ushort uint16 = ms.ReadUInt16BE();
|
||||
int reservedFutureUseB = (uint16 & 0xf000) >> 12;
|
||||
int serviceListDescriptorsLength = (uint16 & 0x0fff);
|
||||
byte[] descriptorBuffer = ms.ReadBytes(serviceListDescriptorsLength);
|
||||
IEnumerable<TsDescriptor> descriptors = TsDescriptorUnpacker.GetInstance().UnpackDescriptors(descriptorBuffer, "Astra SGT");
|
||||
|
||||
SgtList list = new SgtList(serviceListId, 0x01);
|
||||
|
||||
foreach (TsDescriptor rawDescriptor in descriptors)
|
||||
{
|
||||
switch (rawDescriptor.GetType().Name)
|
||||
{
|
||||
case nameof(PrivateDataSpecifierDescriptor):
|
||||
PrivateDataSpecifierDescriptor pdsd = (PrivateDataSpecifierDescriptor)rawDescriptor;
|
||||
list.PrivateDataSpecifier = pdsd.PrivateDataSpecifier;
|
||||
break;
|
||||
case nameof(UserDefinedDescriptor):
|
||||
TsDescriptor userDefinedDescriptor = UserDefinedDescriptorUnpacker.GetInstance().UnpackUserDefinedDescriptor((UserDefinedDescriptor)rawDescriptor, list.PrivateDataSpecifier, "Astra SGT", true);
|
||||
switch (userDefinedDescriptor.GetType().Name)
|
||||
{
|
||||
case nameof(_0x88_ServiceListNameDescriptor):
|
||||
_0x88_ServiceListNameDescriptor slnd = (_0x88_ServiceListNameDescriptor)userDefinedDescriptor;
|
||||
if (list.Names == null)
|
||||
list.Names = new Dictionary<string, string>();
|
||||
list.Names.Add(slnd.LanguageCode, slnd.TextualDescription);
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException(rawDescriptor.GetType().Name);
|
||||
}
|
||||
continue;
|
||||
case nameof(CountryAvailabilityDescriptor):
|
||||
CountryAvailabilityDescriptor cad = (CountryAvailabilityDescriptor)rawDescriptor;
|
||||
foreach(string countryFlag in cad.CountryCodes)
|
||||
{
|
||||
list.CountryAvailabilities.Add(countryFlag, cad.CountryAvailabilityFlag);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new NotImplementedException(rawDescriptor.GetType().Name);
|
||||
}
|
||||
}
|
||||
EventHandler.AnnounceSgtList(list);
|
||||
|
||||
ushort uint16b = ms.ReadUInt16BE();
|
||||
int reservedFutureUseC = (uint16b & 0xf000) >> 12;
|
||||
int serviceLoopLength = (uint16b & 0x0fff);
|
||||
byte[] serviceLoopBuffer = ms.ReadBytes(serviceLoopLength);
|
||||
ParseServiceLoop(serviceListId, serviceLoopBuffer,list.PrivateDataSpecifier);
|
||||
|
||||
uint crc32 = ms.ReadUInt32BE();
|
||||
}
|
||||
|
||||
private void ParseServiceLoop(ushort serviceListId, byte[] serviceLoopBuffer, uint? privateDataSpecifier)
|
||||
{
|
||||
MemoryStream ms = new MemoryStream(serviceLoopBuffer, false);
|
||||
while (ms.GetAvailableBytes() > 6)
|
||||
{
|
||||
SgtService child = new SgtService(serviceListId);
|
||||
child.ServiceId = ms.ReadUInt16BE();
|
||||
child.TransportStreamId = ms.ReadUInt16BE();
|
||||
child.OriginalNetworkId = ms.ReadUInt16BE();
|
||||
|
||||
ushort ushortA = ms.ReadUInt16BE();
|
||||
child.Lcn = (ushortA & 0xfc) >> 2;
|
||||
child.VisibleServiceFlag = (ushortA & 0x02) != 0;
|
||||
child.NewServiceFlag = (ushortA & 0x01) != 0;
|
||||
child.GenreCode = ms.ReadUInt16BE();
|
||||
|
||||
ushort ushortB = ms.ReadUInt16BE();
|
||||
int reservedFutureUseB = (ushortB & 0xf000) >> 12;
|
||||
int serviceListDescriptorsLength = (ushortB & 0x0fff);
|
||||
byte[] descriptorBuffer = ms.ReadBytes(serviceListDescriptorsLength);
|
||||
IEnumerable<TsDescriptor> descriptors = TsDescriptorUnpacker.GetInstance().UnpackDescriptors(descriptorBuffer, "Astra SGT");
|
||||
child.PrivateDataSpecifier = privateDataSpecifier != null ? privateDataSpecifier.Value : 0x01;
|
||||
foreach (TsDescriptor rawDescriptor in descriptors)
|
||||
{
|
||||
switch (rawDescriptor.GetType().Name)
|
||||
{
|
||||
case nameof(CaIdentifierDescriptor):
|
||||
CaIdentifierDescriptor cid = (CaIdentifierDescriptor)rawDescriptor;
|
||||
if (child.CaSystemIds != null)
|
||||
throw new NotImplementedException("Multiple CA Identifier descriptors");
|
||||
child.CaSystemIds = cid.CaSystemIds;
|
||||
continue;
|
||||
case nameof(ServiceDescriptor):
|
||||
ServiceDescriptor sd = (ServiceDescriptor)rawDescriptor;
|
||||
if (child.ServiceDescriptor != null)
|
||||
throw new NotImplementedException("Multiple Service descriptors");
|
||||
child.ServiceDescriptor = sd;
|
||||
continue;
|
||||
case nameof(UserDefinedDescriptor):
|
||||
TsDescriptor userDefinedDescriptor = UserDefinedDescriptorUnpacker.GetInstance().UnpackUserDefinedDescriptor((UserDefinedDescriptor)rawDescriptor, child.PrivateDataSpecifier, "Astra SGT", true);
|
||||
switch(userDefinedDescriptor.GetType().Name)
|
||||
{
|
||||
case nameof(_0xD1_VirtualServiceIdDescriptor):
|
||||
_0xD1_VirtualServiceIdDescriptor vsid = (_0xD1_VirtualServiceIdDescriptor)userDefinedDescriptor;
|
||||
if (child.VirtualServiceIds == null)
|
||||
child.VirtualServiceIds = new List<uint>();
|
||||
child.VirtualServiceIds.Add(vsid.VirtualServiceId);
|
||||
continue;
|
||||
case nameof(_0x93_BouquetListDescriptor):
|
||||
_0x93_BouquetListDescriptor bld = (_0x93_BouquetListDescriptor)userDefinedDescriptor;
|
||||
if (!string.IsNullOrEmpty(child.BouquetList))
|
||||
throw new NotImplementedException("Multiple bouquets in child.");
|
||||
child.BouquetList = bld.Name;
|
||||
continue;
|
||||
default:
|
||||
throw new NotImplementedException(rawDescriptor.GetType().Name);
|
||||
}
|
||||
continue;
|
||||
case nameof(PrivateDataSpecifierDescriptor):
|
||||
PrivateDataSpecifierDescriptor pds = (PrivateDataSpecifierDescriptor)rawDescriptor;
|
||||
if (pds.PrivateDataSpecifier != child.PrivateDataSpecifier)
|
||||
throw new NotImplementedException("Multiple private data specifiers?");
|
||||
continue;
|
||||
default:
|
||||
throw new NotImplementedException(rawDescriptor.GetType().Name);
|
||||
}
|
||||
}
|
||||
EventHandler.OnSgtService(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
57
skyscraper8/Ses/SgtService.cs
Normal file
57
skyscraper8/Ses/SgtService.cs
Normal file
@ -0,0 +1,57 @@
|
||||
using skyscraper5.Dvb.Descriptors;
|
||||
using skyscraper8.Ses.Descriptors;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Ses
|
||||
{
|
||||
public class SgtService
|
||||
{
|
||||
public SgtService(ushort serviceListId)
|
||||
{
|
||||
ServiceListId = serviceListId;
|
||||
}
|
||||
|
||||
public ushort ServiceListId { get; }
|
||||
|
||||
public ushort ServiceId { get; internal set; }
|
||||
public ushort TransportStreamId { get; internal set; }
|
||||
public ushort OriginalNetworkId { get; internal set; }
|
||||
public int Lcn { get; internal set; }
|
||||
public bool VisibleServiceFlag { get; internal set; }
|
||||
public bool NewServiceFlag { get; internal set; }
|
||||
public ushort GenreCode { get; internal set; }
|
||||
|
||||
//In SGT this is mandatory and defaults to 0x01
|
||||
public uint PrivateDataSpecifier { get; internal set; }
|
||||
public ushort[] CaSystemIds { get; internal set; }
|
||||
public ServiceDescriptor ServiceDescriptor { get; internal set; }
|
||||
public List<uint> VirtualServiceIds { get; internal set; }
|
||||
public string? BouquetList { get; internal set; }
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is SgtService service &&
|
||||
ServiceListId == service.ServiceListId &&
|
||||
ServiceId == service.ServiceId &&
|
||||
TransportStreamId == service.TransportStreamId &&
|
||||
OriginalNetworkId == service.OriginalNetworkId;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(ServiceListId, ServiceId, TransportStreamId, OriginalNetworkId);
|
||||
}
|
||||
|
||||
internal string GetName()
|
||||
{
|
||||
if (ServiceDescriptor == null)
|
||||
return "???";
|
||||
|
||||
return ServiceDescriptor.ServiceName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -15,6 +15,7 @@ using skyscraper5.Skyscraper.Scraper.Storage;
|
||||
using skyscraper5.Skyscraper.Scraper.StreamAutodetection;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Dns;
|
||||
using skyscraper5.T2MI;
|
||||
using skyscraper8.yo3explorer;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Plugins
|
||||
{
|
||||
@ -150,6 +151,7 @@ namespace skyscraper5.Skyscraper.Plugins
|
||||
private Type mpePluginType = typeof(ISkyscraperMpePlugin);
|
||||
private Type gpsReceiverFactoryType = typeof(IGpsReceiverFactory);
|
||||
private Type streamTypeAutodetectionContestantType = typeof(Contestant);
|
||||
private Type filesystemProcessorType = typeof(FilesystemProcessorPlugin);
|
||||
private PluginPrioritySorter sorter = new PluginPrioritySorter();
|
||||
|
||||
private List<IDnsParser> _dnsParsers;
|
||||
@ -249,6 +251,11 @@ namespace skyscraper5.Skyscraper.Plugins
|
||||
HandleDnsParser(type);
|
||||
continue;
|
||||
}
|
||||
else if (type.IsAssignableTo(filesystemProcessorType))
|
||||
{
|
||||
HandleFilesystemProcessor(type);
|
||||
continue;
|
||||
}
|
||||
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
@ -476,9 +483,30 @@ namespace skyscraper5.Skyscraper.Plugins
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region yo3explorers
|
||||
|
||||
private List<FilesystemProcessorPlugin> filesystemProcessorPlugins;
|
||||
private void HandleFilesystemProcessor(Type t)
|
||||
{
|
||||
if (filesystemProcessorPlugins == null)
|
||||
filesystemProcessorPlugins = new List<FilesystemProcessorPlugin>();
|
||||
|
||||
FilesystemProcessorPlugin child = (FilesystemProcessorPlugin)Activator.CreateInstance(t);
|
||||
filesystemProcessorPlugins.Add(child);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
public Ini Ini { get; private set; }
|
||||
|
||||
public IReadOnlyList<FilesystemProcessorPlugin> GetFilesystemProcessors()
|
||||
{
|
||||
if (filesystemProcessorPlugins == null)
|
||||
return new List<FilesystemProcessorPlugin>();
|
||||
|
||||
return filesystemProcessorPlugins.AsReadOnly();
|
||||
}
|
||||
|
||||
public IReadOnlyList<IDnsParser> GetDnsParsers()
|
||||
{
|
||||
if (_dnsParsers == null)
|
||||
|
||||
@ -64,6 +64,9 @@ using skyscraper5.T2MI.Packets.AdressingFunctions;
|
||||
using skyscraper5.Teletext;
|
||||
using skyscraper5.Teletext.Vps;
|
||||
using skyscraper5.Teletext.Wss;
|
||||
using skyscraper8.Ses;
|
||||
using skyscraper8.yo3explorer;
|
||||
using Tsubasa.IO;
|
||||
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
|
||||
using RntParser = skyscraper5.Dvb.TvAnytime.RntParser;
|
||||
|
||||
@ -75,7 +78,7 @@ namespace skyscraper5.Skyscraper.Scraper
|
||||
UpdateNotificationEventHandler, DataCarouselEventHandler, RdsEventHandler, IScte35EventHandler,
|
||||
IAutodetectionEventHandler, IRstEventHandler, IRntEventHandler, IMultiprotocolEncapsulationEventHandler, ObjectCarouselEventHandler, T2MIEventHandler,
|
||||
IDisposable, IFrameGrabberEventHandler, IntEventHandler, IRctEventHandler, IGsEventHandler, ISkyscraperContext, IDocsisEventHandler, AbertisDecoderEventHandler, Id3Handler,
|
||||
InteractionChannelHandler
|
||||
InteractionChannelHandler, SgtEventHandler
|
||||
{
|
||||
public const bool ALLOW_STREAM_TYPE_AUTODETECTION = true;
|
||||
public const bool ALLOW_FFMPEG_FRAMEGRABBER = true;
|
||||
@ -2389,5 +2392,43 @@ namespace skyscraper5.Skyscraper.Scraper
|
||||
{
|
||||
LogEvent(SkyscraperContextEvent.StreamTypeAutodetection, String.Format("PID 0x{0:X4} probably isn't a {1}", pid, contestant.Tag));
|
||||
}
|
||||
|
||||
void SgtEventHandler.AnnounceSgtList(SgtList list)
|
||||
{
|
||||
if (!ScraperStorage.TestForSgtList(list))
|
||||
{
|
||||
LogEvent(SkyscraperContextEvent.SgtList, String.Format("List #{0} ({1})", list.ServiceListId, list.GetName()));
|
||||
ScraperStorage.InsertSgtList(list);
|
||||
}
|
||||
}
|
||||
|
||||
void SgtEventHandler.OnSgtError(SgtError invalidTableId)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
void SgtEventHandler.OnSgtService(SgtService child)
|
||||
{
|
||||
if (!ScraperStorage.TestForSgtService(child))
|
||||
{
|
||||
LogEvent(SkyscraperContextEvent.SgtService, String.Format("LCN #{0} in List #{1} ({2})", child.Lcn, child.ServiceListId, child.GetName()));
|
||||
ScraperStorage.InsertSgtService(child);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessVirtualFilesystem(IFilesystem vfs, ProgramMappingStream programMappingStream)
|
||||
{
|
||||
yo3explorerState state = yo3explorerState.GetInstance();
|
||||
|
||||
yo3explorerToSkyscraperContextBridge context = new yo3explorerToSkyscraperContextBridge();
|
||||
|
||||
PluginManager pluginManager = PluginManager.GetInstance();
|
||||
IReadOnlyList<skyscraper8.yo3explorer.FilesystemProcessorPlugin> processors = pluginManager.GetFilesystemProcessors();
|
||||
|
||||
foreach(FilesystemProcessorPlugin processor in processors)
|
||||
{
|
||||
processor.ProcessFilesystem(vfs, context, state);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -70,6 +70,8 @@
|
||||
TimCorrection,
|
||||
TimContentionControl,
|
||||
TimCorrectionControl,
|
||||
TimNetworkLayerInfo
|
||||
TimNetworkLayerInfo,
|
||||
SgtList,
|
||||
SgtService
|
||||
}
|
||||
}
|
||||
|
||||
@ -33,6 +33,7 @@ using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Dns;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Storage.InMemory;
|
||||
using skyscraper5.Teletext;
|
||||
using skyscraper8.Ses;
|
||||
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem
|
||||
@ -1406,5 +1407,25 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Filesystem
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TestForSgtList(SgtList list)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InsertSgtList(SgtList list)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool TestForSgtService(SgtService child)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public void InsertSgtService(SgtService child)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ using skyscraper5.src.InteractionChannel.Model.Descriptors;
|
||||
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Dns;
|
||||
using skyscraper5.Teletext;
|
||||
using skyscraper8.Ses;
|
||||
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Scraper.Storage
|
||||
@ -175,5 +176,9 @@ namespace skyscraper5.Skyscraper.Scraper.Storage
|
||||
bool NetworkLayerInfoTim(PhysicalAddress mac, _0xa0_NetworkLayerInfoDescriptor nlid, DateTime timestamp);
|
||||
|
||||
IEnumerable<DbBlindscanJob> GetDbBlindscanJobs();
|
||||
bool TestForSgtList(SgtList list);
|
||||
void InsertSgtList(SgtList list);
|
||||
bool TestForSgtService(SgtService child);
|
||||
void InsertSgtService(SgtService child);
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,6 +31,8 @@ using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Dns;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Storage.InMemory;
|
||||
using skyscraper5.Teletext;
|
||||
using skyscraper8.Ses;
|
||||
using skyscraper8.Skyscraper.Scraper.Storage.InMemory.Model;
|
||||
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
||||
@ -1012,37 +1014,54 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
private HashSet<DbBlindscanJobContainer> jobs;
|
||||
public void InsertBlindscanJob(DbBlindscanJob jobInDb)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
if (jobs == null)
|
||||
jobs = new HashSet<DbBlindscanJobContainer>();
|
||||
|
||||
DbBlindscanJobContainer jobContainer = new DbBlindscanJobContainer(jobInDb);
|
||||
jobs.Add(jobContainer);
|
||||
}
|
||||
|
||||
public void UpdateJobState(DbBlindscanJob jobInDb)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void InsertSearchResult(DbBlindscanJob jobInDb, bool satellite, SearchResult searchResult, int polarityIndex,
|
||||
SearchResult2 searchResult2)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
DbBlindscanJobContainer dbBlindscanJobContainer = jobs.First(x => x.JobGuid.Equals(jobInDb.JobGuid));
|
||||
if (dbBlindscanJobContainer == null)
|
||||
throw new Exception("Failed to find the job.");
|
||||
|
||||
dbBlindscanJobContainer.AddSearchResult(satellite, searchResult, polarityIndex, searchResult2);
|
||||
}
|
||||
|
||||
public void UpdateTransponderState(DbBlindscanJob jobInDb, bool satellite, SearchResult searchResult,
|
||||
BlindscanResultState blindscanResultState, SearchResult2 searchResult2)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
|
||||
}
|
||||
|
||||
public void InsertTransponderService(DbBlindscanJob jobInDb, bool resultSatellite, SearchResult resultSr1,
|
||||
SearchResult2 resultSr2, HumanReadableService humanReadableService)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
DbBlindscanJobContainer jobContainer = jobs.First(x => x.JobGuid.Equals(jobInDb.JobGuid));
|
||||
if (jobContainer == null)
|
||||
throw new Exception("Failed to find the job.");
|
||||
|
||||
DbBlindscanJobContainer.SearchResultContainer searchResultContainer = jobContainer.GetSearchResult(resultSatellite, resultSr1, resultSr2);
|
||||
if (searchResultContainer == null)
|
||||
throw new Exception("Failed to find the search result.");
|
||||
searchResultContainer.AddService(humanReadableService);
|
||||
}
|
||||
|
||||
public bool TestForIncompleteJob()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
return false;
|
||||
}
|
||||
|
||||
public DbBlindscanJob GetPastBlindscanJob(long offset)
|
||||
@ -1236,5 +1255,39 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.InMemory
|
||||
|
||||
dnsRecords.Add(record);
|
||||
}
|
||||
|
||||
private SgtList[] sgtLists;
|
||||
public bool TestForSgtList(SgtList list)
|
||||
{
|
||||
if (sgtLists == null)
|
||||
return false;
|
||||
|
||||
return sgtLists[list.ServiceListId] != null;
|
||||
}
|
||||
|
||||
public void InsertSgtList(SgtList list)
|
||||
{
|
||||
if (sgtLists == null)
|
||||
sgtLists = new SgtList[ushort.MaxValue];
|
||||
|
||||
sgtLists[list.ServiceListId] = list;
|
||||
}
|
||||
|
||||
private HashSet<SgtService> sgtServices;
|
||||
public bool TestForSgtService(SgtService child)
|
||||
{
|
||||
if (sgtServices == null)
|
||||
return false;
|
||||
|
||||
return sgtServices.Contains(child);
|
||||
}
|
||||
|
||||
public void InsertSgtService(SgtService child)
|
||||
{
|
||||
if (sgtServices == null)
|
||||
sgtServices = new HashSet<SgtService>();
|
||||
|
||||
sgtServices.Add(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,122 @@
|
||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.Skyscraper.Scraper.Storage.InMemory.Model
|
||||
{
|
||||
internal class DbBlindscanJobContainer
|
||||
{
|
||||
private DbBlindscanJob jobInDb;
|
||||
private List<SearchResultContainer> searchResults;
|
||||
|
||||
public DbBlindscanJobContainer(DbBlindscanJob jobInDb)
|
||||
{
|
||||
this.jobInDb = jobInDb;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is DbBlindscanJobContainer container &&
|
||||
EqualityComparer<DbBlindscanJob>.Default.Equals(jobInDb, container.jobInDb);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(jobInDb);
|
||||
}
|
||||
|
||||
internal void AddSearchResult(bool satellite, SearchResult searchResult, int polarityIndex, SearchResult2 searchResult2)
|
||||
{
|
||||
if (searchResults == null)
|
||||
searchResults = new List<SearchResultContainer>();
|
||||
|
||||
searchResults.Add(new SearchResultContainer(satellite, searchResult, polarityIndex, searchResult2));
|
||||
}
|
||||
|
||||
internal SearchResultContainer GetSearchResult(bool satellit, SearchResult searchResult, int polarityIndex, SearchResult2 searchResult2)
|
||||
{
|
||||
SearchResultContainer searchResultContainer = searchResults.First(x => x.Matches(satellit, searchResult, polarityIndex, searchResult2));
|
||||
return searchResultContainer;
|
||||
}
|
||||
|
||||
internal SearchResultContainer GetSearchResult(bool satellit, SearchResult searchResult, SearchResult2 searchResult2)
|
||||
{
|
||||
SearchResultContainer searchResultContainer = searchResults.First(x => x.Matches(satellit, searchResult, searchResult2));
|
||||
return searchResultContainer;
|
||||
}
|
||||
|
||||
public Guid JobGuid
|
||||
{
|
||||
get
|
||||
{
|
||||
return jobInDb.JobGuid;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SearchResultContainer
|
||||
{
|
||||
private bool satellite;
|
||||
private SearchResult searchResult;
|
||||
private int polarityIndex;
|
||||
private SearchResult2 searchResult2;
|
||||
private List<HumanReadableService> services;
|
||||
|
||||
public SearchResultContainer(bool satellite, SearchResult searchResult, int polarityIndex, SearchResult2 searchResult2)
|
||||
{
|
||||
this.satellite = satellite;
|
||||
this.searchResult = searchResult;
|
||||
this.polarityIndex = polarityIndex;
|
||||
this.searchResult2 = searchResult2;
|
||||
}
|
||||
|
||||
public override bool Equals(object? obj)
|
||||
{
|
||||
return obj is SearchResultContainer container &&
|
||||
satellite == container.satellite &&
|
||||
EqualityComparer<SearchResult>.Default.Equals(searchResult, container.searchResult) &&
|
||||
polarityIndex == container.polarityIndex &&
|
||||
EqualityComparer<SearchResult2>.Default.Equals(searchResult2, container.searchResult2);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return HashCode.Combine(satellite, searchResult, polarityIndex, searchResult2);
|
||||
}
|
||||
|
||||
public bool Matches(bool satellite, SearchResult searchResult, int polarityIndex, SearchResult2 searchResult2)
|
||||
{
|
||||
if (this.satellite != satellite)
|
||||
return false;
|
||||
if (!EqualityComparer<SearchResult>.Default.Equals(searchResult, this.searchResult))
|
||||
return false;
|
||||
if (this.polarityIndex != polarityIndex)
|
||||
return false;
|
||||
if (!EqualityComparer<SearchResult2>.Default.Equals(searchResult2, this.searchResult2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Matches(bool satellite, SearchResult searchResult,SearchResult2 searchResult2)
|
||||
{
|
||||
if (this.satellite != satellite)
|
||||
return false;
|
||||
if (!EqualityComparer<SearchResult>.Default.Equals(searchResult, this.searchResult))
|
||||
return false;
|
||||
if (!EqualityComparer<SearchResult2>.Default.Equals(searchResult2, this.searchResult2))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
internal void AddService(HumanReadableService humanReadableService)
|
||||
{
|
||||
if (services == null)
|
||||
services = new List<HumanReadableService>();
|
||||
services.Add(humanReadableService);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -31,6 +31,7 @@ using skyscraper5.src.InteractionChannel.Model.Descriptors;
|
||||
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Dns;
|
||||
using skyscraper5.Teletext;
|
||||
using skyscraper8.Ses;
|
||||
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Scraper.Storage.Split
|
||||
@ -160,5 +161,9 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Split
|
||||
bool CorrectionControlTim(PhysicalAddress mac, _0xac_CorrectionControlDescriptor descriptor);
|
||||
bool NetworkLayerInfoTim(PhysicalAddress mac, _0xa0_NetworkLayerInfoDescriptor nlid, DateTime timestamp);
|
||||
IEnumerable<DbBlindscanJob> GetDbBlindscanJobs();
|
||||
bool TestForSgtList(SgtList list);
|
||||
void InsertSgtList(SgtList list);
|
||||
bool TestForSgtService(SgtService child);
|
||||
void InsertSgtService(SgtService child);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,6 +28,7 @@ using skyscraper5.src.InteractionChannel.Model.Descriptors;
|
||||
using skyscraper5.src.Skyscraper.FrequencyListGenerator;
|
||||
using skyscraper5.src.Skyscraper.Scraper.Dns;
|
||||
using skyscraper5.Teletext;
|
||||
using skyscraper8.Ses;
|
||||
using Platform = skyscraper5.Dvb.SystemSoftwareUpdate.Model.Platform;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Scraper.Storage.Split
|
||||
@ -862,5 +863,29 @@ namespace skyscraper5.Skyscraper.Scraper.Storage.Split
|
||||
{
|
||||
dataStorage.RememberDnsRecord(record);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public bool TestForSgtList(SgtList list)
|
||||
{
|
||||
return dataStorage.TestForSgtList(list);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public void InsertSgtList(SgtList list)
|
||||
{
|
||||
dataStorage.InsertSgtList(list);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public bool TestForSgtService(SgtService child)
|
||||
{
|
||||
return dataStorage.TestForSgtService(child);
|
||||
}
|
||||
|
||||
[DebuggerStepThrough]
|
||||
public void InsertSgtService(SgtService child)
|
||||
{
|
||||
dataStorage.InsertSgtService(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,6 +14,7 @@ using skyscraper5.Dvb.DataBroadcasting.SkyscraperVfs;
|
||||
using skyscraper5.Mpeg2;
|
||||
using skyscraper5.Mpeg2.Psi.Model;
|
||||
using skyscraper5.Skyscraper.Plugins;
|
||||
using Tsubasa.IO;
|
||||
|
||||
namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants
|
||||
{
|
||||
@ -60,12 +61,11 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants
|
||||
|
||||
public void NotifyDownloadComplete(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion, Stream result, bool isObjectCarousel)
|
||||
{
|
||||
Score += 2;
|
||||
Score++;
|
||||
}
|
||||
|
||||
public void DsmCcDoItNowEvent(ProgramMapping programMapping, StreamEventDescriptor descriptorListStreamEventDescriptor, int pid)
|
||||
{
|
||||
Score++;
|
||||
}
|
||||
|
||||
public void PreventDsmCcModuleRepetition(int elementaryPid, ushort moduleModuleId, byte moduleModuleVersion)
|
||||
@ -106,5 +106,9 @@ namespace skyscraper5.Skyscraper.Scraper.StreamAutodetection.Contestants
|
||||
}
|
||||
skyscraperContext.DvbContext.RegisterPacketProcessor(pid, new PsiDecoder(pid, new DataCarouselDecoder(programContext.Stream, programContext.Program, DataCarouselIntention.NoIntention, skyscraperContext)));
|
||||
}
|
||||
|
||||
public void ProcessVirtualFilesystem(IFilesystem vfs, ProgramMappingStream pmtPid)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -13,4 +13,8 @@
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Folder Include="DvbI\Model\" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
67
skyscraper8/yo3explorer/Filesystem.cs
Normal file
67
skyscraper8/yo3explorer/Filesystem.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using skyscraper5.Dvb.DataBroadcasting.Biop;
|
||||
using skyscraper5.Skyscraper.IO.CrazycatStreamReader;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Xml.Linq;
|
||||
using static System.Runtime.InteropServices.JavaScript.JSType;
|
||||
|
||||
namespace Tsubasa.IO
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a simple interface to a virtual filesystem.
|
||||
///
|
||||
/// This interface is here as a memento to remember where Skyscraper originated from.
|
||||
/// It was copied 1:1 from the source code of yo3explorer, a project I abandoned a long time ago, but is still dear to me.
|
||||
///yo3explorer was designed to extract game assets of Yu-Gi-Oh! ONLINE 3, a long defunct online game with a fully automatic simulation of the Yu-Gi-Oh! Trading Card Game.
|
||||
///The GUI of yo3explorer used this interface to talk to Archive Format parsers.
|
||||
///Eventually, yo3explorer grew to not only support Yu-Gi-Oh! ONLINE 3, but other games as well.
|
||||
///Some notable ones:
|
||||
/// - Artificial Girl 3
|
||||
/// - Ever17: The out of infinity
|
||||
/// - Jokei Kazoku III ~Himitsu~
|
||||
/// - Hyperdimension Neptunia Re; Birth
|
||||
/// - Steins;Gate
|
||||
/// - Yu-Gi-Oh! Power of Chaos
|
||||
/// - Spelunky
|
||||
/// - Super Heroine Chronicle
|
||||
/// - Spocon! ~Sports Wear-Complex ~
|
||||
///This interface is, at the time of adding this comment, over 10 years old. It was written on 24.12.2013
|
||||
/// </summary>
|
||||
public interface IFilesystem : IDisposable
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Checks whether a file by a specified name is present in a virtual filesystem.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename to check for.</param>
|
||||
/// <returns>true if the file is present in the virtual filesystem, false if not. If filename appears in FileList this should return true.</returns>
|
||||
bool FileExists(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the contents of a file in a virtual filesystem.
|
||||
/// </summary>
|
||||
/// <param name="filename">The filename of the file you want the contents of.</param>
|
||||
/// <returns>The file contents as a byte array.</returns>
|
||||
byte[] GetFile(string filename);
|
||||
|
||||
/// <summary>
|
||||
/// All the names of the files contained in this virtual filesystem.
|
||||
/// </summary>
|
||||
string[] FileList
|
||||
{
|
||||
get;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// A human readable name for this virutal filesystem.
|
||||
/// </summary>
|
||||
string FilesystemName
|
||||
{
|
||||
get;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
24
skyscraper8/yo3explorer/FilesystemProcessorPlugin.cs
Normal file
24
skyscraper8/yo3explorer/FilesystemProcessorPlugin.cs
Normal file
@ -0,0 +1,24 @@
|
||||
using skyscraper5.Skyscraper.Scraper;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using Tsubasa.IO;
|
||||
|
||||
namespace skyscraper8.yo3explorer
|
||||
{
|
||||
/// <summary>
|
||||
/// This interface is intended to describe a Skyscraper plugin that processes a yo3explorer compatible filesystem.
|
||||
/// </summary>
|
||||
internal interface FilesystemProcessorPlugin
|
||||
{
|
||||
/// <summary>
|
||||
/// Lets this Skyscraper plugin process a yo3explorer compatible filesystem.
|
||||
/// </summary>
|
||||
/// <param name="vfs">A yo3explorer compatible filesystem.</param>
|
||||
/// <param name="context">Data that might be useful to the plugin.</param>
|
||||
/// <param name="state">Data that is supposed to be kept spanning multiple yo3explorer sessions. One could argue that this object simulates the GUI of yo3explorer.</param>
|
||||
void ProcessFilesystem(IFilesystem vfs, yo3explorerToSkyscraperContextBridge context, yo3explorerState state);
|
||||
}
|
||||
}
|
||||
26
skyscraper8/yo3explorer/yo3explorerState.cs
Normal file
26
skyscraper8/yo3explorer/yo3explorerState.cs
Normal file
@ -0,0 +1,26 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.yo3explorer
|
||||
{
|
||||
internal class yo3explorerState
|
||||
{
|
||||
private static yo3explorerState instance;
|
||||
private yo3explorerState()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public static yo3explorerState GetInstance()
|
||||
{
|
||||
if (instance == null)
|
||||
{
|
||||
instance = new yo3explorerState();
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,12 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace skyscraper8.yo3explorer
|
||||
{
|
||||
internal class yo3explorerToSkyscraperContextBridge
|
||||
{
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user