using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.Gps; using skyscraper5.Skyscraper.IO.TunerInterface; using skyscraper5.Skyscraper.Scraper.Storage.Filesystem; using skyscraper5.Skyscraper.Scraper.Storage.InMemory; using skyscraper5.src.Skyscraper; using skyscraper8.Skyscraper.Plugins; using skyscraper8.Skyscraper.Scraper.Storage; using System.IO; using System.Net.NetworkInformation; namespace skyscraper8.UI.MonoGame { class Program { public static void Main(string[] args) { PluginLogger localLogger = PluginLogManager.GetLogger(typeof(Program)); SkyscraperHandleCollection handles = new SkyscraperHandleCollection(); Queue errors = new Queue(); localLogger.Log(PluginLogLevel.Info,"Starting up..."); //LOAD STORAGE ---------------------------------------------------------------------------------------------------------------------------------------------------------- localLogger.Log(PluginLogLevel.Info, "Starting Storage Connection Manager..."); StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); localLogger.Log(PluginLogLevel.Info, "Enumerating Data Storage Factories..."); handles.AllDataStorages = connectionManager.GetDataStorages().ToList().AsReadOnly(); localLogger.Log(PluginLogLevel.Debug, "Enumerating Object Storage Factories..."); handles.AllObjectStorages = connectionManager.GetObjectStorages().ToList().AsReadOnly(); localLogger.Log(PluginLogLevel.Debug, "Checking for configuration file..."); if (!connectionManager.IniExists()) { localLogger.Log(PluginLogLevel.Warn, "Configuration file not found!"); errors.Enqueue(String.Format("The configuration file does not exist.\r\nPlease create one in the UI!")); handles.Ini = new Ini(); } DataStorageFactory dataStorageFactory; try { localLogger.Log(PluginLogLevel.Debug, "Getting default data storage factory..."); dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); } catch (Exception e) { localLogger.Log(PluginLogLevel.Error, "Failed to start the data storage factory: {0}", e.Message); errors.Enqueue(String.Format("Could not load the data storage factory.\nThe following went wrong:\n\n{0}\n\n", e.Message)); dataStorageFactory = new InMemoryScraperStorageFactory(); } ObjectStorageFactory objectStorageFactory; try { localLogger.Log(PluginLogLevel.Debug, "Getting default object storage factory..."); objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); } catch (Exception e) { localLogger.Log(PluginLogLevel.Error, "Failed to start the object storage factory: {0}", e.Message); errors.Enqueue(String.Format("Could not load the object storage factory.\nThe following went wrong:\n\n{0}\n\n", e.Message)); objectStorageFactory = new FilesystemScraperStorageFactory() { Directory = "dummy_object_storage" }; } localLogger.Log(PluginLogLevel.Info, "Creating Data Storage..."); handles.DataStorage = dataStorageFactory.CreateDataStorage(); localLogger.Log(PluginLogLevel.Info, "Checking whether the data storage and the object storage are the same..."); bool equivalentStorages = objectStorageFactory.IsEquivalent(dataStorageFactory); if (equivalentStorages) { localLogger.Log(PluginLogLevel.Info, "Casting Data Storage to Object Storage."); handles.ObjectStorage = (ObjectStorage)handles.DataStorage; } else { localLogger.Log(PluginLogLevel.Info,"It isn't -> Creating object storage..."); try { handles.ObjectStorage = objectStorageFactory.CreateObjectStorage(); } catch (Exception e) { string objectStorageName = connectionManager.GetName(objectStorageFactory); localLogger.Log(PluginLogLevel.Error, "Failed to start the object storage factory: {0}", e.Message); errors.Enqueue(String.Format("Could not load {1}.\nThe following went wrong:\n\n{0}\n\n", e.Message, objectStorageName)); } } localLogger.Log(PluginLogLevel.Info,"Reporting UI Version to the storages..."); handles.DataStorage?.UiSetVersion(2); handles.ObjectStorage?.UiSetVersion(2); localLogger.Log(PluginLogLevel.Info,"Testing whether the data storage is responding..."); try { handles.DataStorage.Ping(); } catch (Exception e) { string brokenStorageName = connectionManager.GetName(dataStorageFactory); InMemoryScraperStorageFactory fssf = new InMemoryScraperStorageFactory(); handles.DataStorage = fssf.CreateDataStorage(); errors.Enqueue(String.Format( "{0} failed to respond.\nThe following went wrong:\n\n{1}\n\nI've switched to a volatile in-memory storage. This will work, but is quite possibly not what you want. It will not and cannot save any data. Please consider configuring {0} correctly.", brokenStorageName, e.Message)); } localLogger.Log(PluginLogLevel.Info,"Please wait while I test whether the object storage is responding..."); try { handles.ObjectStorage.Ping(); } catch (Exception e) { string brokenStorageName = connectionManager.GetName(objectStorageFactory); FilesystemScraperStorageFactory fssf = new FilesystemScraperStorageFactory(); fssf.Directory = "dummy_object_storage"; handles.ObjectStorage = fssf.CreateObjectStorage(); errors.Enqueue(String.Format( "{0} failed to respond.\nThe following went wrong:\n\n{1}\n\nI've switched to a file system based storage. This will work, but is quite possibly not what you want. Please consider configuring {0} correctly.", brokenStorageName, e.Message)); } //LOAD GPS ---------------------------------------------------------------------------------------------------------------------------------------------------------------- localLogger.Log(PluginLogLevel.Info, "Please wait while I load the GPS receiver library..."); int gpsReceiverId = GpsManager.GetConfiguredGpsId(); IGpsReceiverFactory gpsReceiverFactory = GpsManager.GetGpsReceiverFactoryById(gpsReceiverId); GpsManager.AutoconfigureGpsReceiverFactory(gpsReceiverFactory); localLogger.Log(PluginLogLevel.Info,"Instantiating the GPS receiver..."); handles.Gps = gpsReceiverFactory.CreateGpsReceiver(); localLogger.Log(PluginLogLevel.Info,"Starting the GPS receiver..."); handles.Gps.Start(); //LOAD BASE DATA -------------------------------------------------------------------------------------------------------------------------------------------------------------- localLogger.Log(PluginLogLevel.Info,"Querying the storage for known satellite positions..."); handles.SatellitePositions = handles.DataStorage.UiSatellitesListAll(); localLogger.Log(PluginLogLevel.Info,"Checking for the default LNB types..."); EquipmentUtilities.InsertDefaultLnbTypes(handles.DataStorage); localLogger.Log(PluginLogLevel.Info,"Querying the storage for known LNB types..."); handles.LnbTypes = handles.DataStorage.UiLnbTypesListAll(); localLogger.Log(PluginLogLevel.Info,"Checking for the default dish types..."); EquipmentUtilities.InsertDefaultDishTypes(handles.DataStorage); localLogger.Log(PluginLogLevel.Info,"Querying the storage for known Dish types..."); handles.DishTypes = handles.DataStorage.UiDishTypesListAll(); //LOAD TUNER -------------------------------------------------------------------------------------------------------------------------------------------------------------------- localLogger.Log(PluginLogLevel.Info,"Chcking the Tuner Factory classes..."); TunerFactoryConnectionManager tunerFactoryConnectionManager = TunerFactoryConnectionManager.GetInstance(); handles.AllTunerFactories = tunerFactoryConnectionManager.GetKnownFactories(); int tunerFactory = handles.Ini.ReadValue("startup", "tunerFactory", 0); KeyValuePair bootingTuner = handles.AllTunerFactories.First(x => x.Key.Id == tunerFactory); bool isNoTuner = bootingTuner.Key.DisplayName.Equals("No tuner"); if (isNoTuner) { errors.Enqueue("Please not that Skyscraper is currently configured to not use a Tuner Factory Class. This will work, but functionality will be severely limited. Please configure a Tuner Factory Class in order to get the best experience."); } localLogger.Log(PluginLogLevel.Info,"Applying the tuner factory class configuration..:"); TunerFactoryConnectionManager.ConfigureFactoryFromIni(bootingTuner, handles.Ini); List foundTuners = new List(); localLogger.Log(PluginLogLevel.Info,"Please wait while the Tuner Factory class code is being executed..."); try { handles.StreamReader = bootingTuner.Value.CreateStreamReader(); try { localLogger.Log(PluginLogLevel.Info,"Trying to see whether the tuner factory works..."); handles.StreamReader.CheckForDVB(); } catch (BadImageFormatException e) { errors.Enqueue("The configured tuner factory is not suitable for the current processor architecture. Tuning won't work, therefore functionality will be severely limited. Please configure a Tuner Factory Class suitable for this processor architecture in order to get the best experience. If you need to run crazycat69's StreamReader.dll on 64-bit machines, try RemoteStreamReader."); handles.StreamReader = new NullTunerFactory().CreateStreamReader(); } localLogger.Log(PluginLogLevel.Info, "Checking for your tuners..."); bool checkForDvbExEx = handles.StreamReader.CheckForDVBExEx((index, name, type) => { TunerMetadata tuner = new TunerMetadata(index, name, type); localLogger.Log(PluginLogLevel.Info, String.Format("Found tuner {0}", name)); foundTuners.Add(tuner); }); if (!checkForDvbExEx) { if (!isNoTuner) localLogger.Log(PluginLogLevel.Error, String.Format("{0} has failed. Tuning won't be possible!", nameof(handles.StreamReader.CheckForDVBExEx))); } } catch (Exception e) { localLogger.Log(PluginLogLevel.Error,"Oh dear, it failed."); errors.Enqueue( "Please not that the Tuner Factory class code failed to execute. " + "This won't stop the program from working, but functionality will be severely limited. " + "Please make sure the Tuner Factory Class is properly configured in order to get the best experience.\n\n" + "The following went wrong:\n" + e.Message); handles.StreamReader = new NullTunerFactory().CreateStreamReader(); } foreach (TunerMetadata foundTuner in foundTuners) { handles.StreamReader.StopDVB(); localLogger.Log(PluginLogLevel.Info,String.Format("Starting tuner {0}", foundTuner.Name)); bool startDvbEx = handles.StreamReader.StartDvbEx(foundTuner.Index); if (!startDvbEx) { localLogger.Log(PluginLogLevel.Error,String.Format("Failed to start {0}", foundTuner.Name)); Thread.Sleep(1000); continue; } localLogger.Log(PluginLogLevel.Info, String.Format("Checking capabilities of {0}", foundTuner.Name)); foundTuner.Caps = handles.StreamReader.GetCaps(); byte[] macBuffer = new byte[6]; localLogger.Log(PluginLogLevel.Info, String.Format("Reading MAC Address of {0}", foundTuner.Name)); bool mac = handles.StreamReader.GetMAC(macBuffer); if (!mac) { localLogger.Log(PluginLogLevel.Error,String.Format("Failed to read MAC Address of {0}", foundTuner.Name)); Thread.Sleep(1000); } else { foundTuner.MacAddress = new PhysicalAddress(macBuffer); } localLogger.Log(PluginLogLevel.Info, String.Format("Stopping {0}", foundTuner.Name)); bool stopDvb = handles.StreamReader.StopDVB(); if (!stopDvb) { localLogger.Log(PluginLogLevel.Error, String.Format("Failed to stop {0}", foundTuner.Name)); Thread.Sleep(1000); continue; } localLogger.Log(PluginLogLevel.Info, String.Format("Querying storage for configuration of {0}...", foundTuner.Name)); if (handles.DataStorage.UiTunerTestFor(foundTuner)) { handles.DataStorage.UiTunerGetConfiguration(foundTuner); } if (handles.Tuners == null) handles.Tuners = new List(); handles.Tuners.Add(foundTuner); } localLogger.Log(PluginLogLevel.Info,"Checking the engine Version..."); string engineProductName = handles.StreamReader.GetEngineName(); Version engineVersion = handles.StreamReader.GetEngineVersion(); if (!engineProductName.Equals("NullStreamReader")) { bool finalCaps = handles.StreamReader.CheckForDVB(); if (!finalCaps) { errors.Enqueue("Somehow CheckForDVB failed after a second call."); } } localLogger.Log(PluginLogLevel.Info,"Qualifying the engine..."); QualificationToolResultEnum qualification = QualificationTool.QualifyTunerFactory(engineProductName, engineVersion); switch (qualification) { case QualificationToolResultEnum.Good: break; case QualificationToolResultEnum.Bad: errors.Enqueue(String.Format("You are using {0}, Version {1}\nThis version is known to cause issues with skyscraper. You can continue using it, but if it causes issues, you're on your own.", engineProductName, engineVersion)); break; case QualificationToolResultEnum.Unknown: errors.Enqueue(String.Format("You are using {0}, Version {1}\nThis version has not been tested with skyscraper, and might cause some issues. Consider submitting a copy of this version to the author.", engineProductName, engineVersion)); break; case QualificationToolResultEnum.PossibleIssues: errors.Enqueue(String.Format("You are using {0}, Version {1}\nThis version will work, but might have minor issues in some edge cases.", engineProductName, engineVersion)); break; default: errors.Enqueue(String.Format("You are using {0}, Version {1}\nThe Qualification said \"{2}\", but this status is not implemented.\n Possibly your skyscraper Version and your testdrid Version mismatch?", engineProductName, engineVersion, qualification.ToString())); break; } SkyscraperGame game = new SkyscraperGame(handles,errors); game.Run(); } } }