From 12c60045788999f655fe468470e0aadb8bf41a7b Mon Sep 17 00:00:00 2001 From: feyris-tan <4116042+feyris-tan@users.noreply.github.com> Date: Mon, 30 Jun 2025 22:57:40 +0200 Subject: [PATCH] Prevent bitrot on ImGui version. --- .../Forms/BlindscanJobDeleter.cs | 5 +- .../Forms/ConfigureDishTypes.cs | 5 +- .../Forms/ConfigureGpsWindow.cs | 2 +- .../Forms/ConfigureLnbTypes.cs | 5 +- .../Forms/ConfigureStorage.cs | 42 ++-- .../Forms/ConfigureTunersWindow.cs | 5 +- GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs | 35 +-- .../Forms/SatellitesConfigurationWindow.cs | 5 +- GUIs/skyscraper8.UI.ImGui/JobContext.cs | 7 +- GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs | 7 +- .../Jobs/CoopBlindscan.cs | 2 +- .../Jobs/ScrapeFromTcp.cs | 2 +- GUIs/skyscraper8.UI.ImGui/Program.cs | 233 +++++++++++++----- .../SdlWrapper/Surface.cs | 14 +- .../Skyscraper/Plugins/PluginAppender.cs | 76 ++++++ .../Skyscraper/Plugins/PluginException.cs | 23 ++ .../Skyscraper/Scraper/Storage/DataStorage.cs | 4 +- .../Storage/StorageConnectionManager.cs | 18 +- .../Skyscraper/SkyscraperCoreException.cs | 24 ++ 19 files changed, 384 insertions(+), 130 deletions(-) create mode 100644 skyscraper8/Skyscraper/Plugins/PluginAppender.cs create mode 100644 skyscraper8/Skyscraper/Plugins/PluginException.cs create mode 100644 skyscraper8/Skyscraper/SkyscraperCoreException.cs diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/BlindscanJobDeleter.cs b/GUIs/skyscraper8.UI.ImGui/Forms/BlindscanJobDeleter.cs index ccc31d1..da4be70 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/BlindscanJobDeleter.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/BlindscanJobDeleter.cs @@ -8,18 +8,19 @@ using System.Linq; using System.Runtime.Intrinsics.X86; using System.Text; using System.Threading.Tasks; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { class BlindscanJobDeleter : IRenderable { - private readonly IScraperStroage storage; + private readonly DataStorage storage; private List blindscanJobs; private Guid selectedGuid; private string tableGuid; public bool Closed { get; private set; } - public BlindscanJobDeleter(IScraperStroage storage) + public BlindscanJobDeleter(DataStorage storage) { this.storage = storage; this.LoadPastBlindscans(); diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureDishTypes.cs b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureDishTypes.cs index 7bf63f3..36a1947 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureDishTypes.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureDishTypes.cs @@ -7,19 +7,20 @@ using System.Text; using System.Threading.Tasks; using System.Xml.Linq; using skyscraper5.Skyscraper.Equipment; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { internal class ConfigureDishTypes : IRenderable { - private readonly IScraperStroage _scraperStroage; + private readonly DataStorage _scraperStroage; private List dishTypes; private string tableUuid; private string name; private int diameter; private DishShape shape; - public ConfigureDishTypes(IScraperStroage scraperStroage, List dishTypes) + public ConfigureDishTypes(DataStorage scraperStroage, List dishTypes) { _scraperStroage = scraperStroage; this.dishTypes = dishTypes; diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureGpsWindow.cs b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureGpsWindow.cs index e00f8e4..588350a 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureGpsWindow.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureGpsWindow.cs @@ -9,7 +9,7 @@ using ImGuiNET; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Gps; using skyscraper5.Skyscraper.Scraper.Storage; -using static SDL2Demo.Forms.ConfigureStorageWindow; +using static SDL2Demo.Forms.ConfigureDataStorageWindow; namespace SDL2Demo.Forms { diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureLnbTypes.cs b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureLnbTypes.cs index 08df4a5..4a6cdcb 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureLnbTypes.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureLnbTypes.cs @@ -9,12 +9,13 @@ using System.Threading.Tasks; using System.Data; using System.Xml.Linq; using skyscraper5.Skyscraper.Equipment; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { internal class ConfigureLnbTypes : IRenderable { - private readonly IScraperStroage _scraperStroage; + private readonly DataStorage _scraperStroage; private List lnbTypes; private string tableUuid; private string lnbPopupUuid; @@ -22,7 +23,7 @@ namespace SDL2Demo.Forms private string name; private int lof1, lof2, lofSw, minFreq, maxFreq; - public ConfigureLnbTypes(IScraperStroage scraperStroage, List lnbTypes) + public ConfigureLnbTypes(DataStorage scraperStroage, List lnbTypes) { _scraperStroage = scraperStroage; this.lnbTypes = lnbTypes; diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureStorage.cs b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureStorage.cs index ae1be51..5d96a5d 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureStorage.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureStorage.cs @@ -8,44 +8,54 @@ using System.Threading.Tasks; using ImGuiNET; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Scraper.Storage; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { - internal class ConfigureStorageWindow : IRenderable + internal class ConfigureDataStorageWindow : IRenderable { public Ini Ini { get; } - public ReadOnlyCollection> StorageFactories { get; } + public ReadOnlyCollection> StorageFactories { get; } + private Dictionary FactoryNames; + private Dictionary TempGuids; + private StorageConnectionManager connectionManager; - public ConfigureStorageWindow(Ini ini, ReadOnlyCollection> storageFactories) + public ConfigureDataStorageWindow(Ini ini, ReadOnlyCollection> storageFactories) { Ini = ini; StorageFactories = storageFactories; IsOpen = true; storageId = ini.ReadValue("startup", "storage", 0); settings = new List(); + FactoryNames = new Dictionary(); + connectionManager = StorageConnectionManager.GetInstance(); + TempGuids = new Dictionary(); + - foreach (KeyValuePair keyValuePair in storageFactories) + foreach (KeyValuePair keyValuePair in storageFactories) { + FactoryNames.Add(keyValuePair.Key, connectionManager.GetName(keyValuePair.Value)); + TempGuids.Add(keyValuePair.Key, Guid.NewGuid()); PropertyInfo[] propertyInfos = keyValuePair.Value.GetType().GetProperties(); foreach (PropertyInfo propertyInfo in propertyInfos) { Setting s = new Setting(); - s.IniKey = keyValuePair.Key.Id; + s.IniKey = keyValuePair.Key; s.SettingName = propertyInfo.Name; s.SettingControlUuid = Guid.NewGuid().ToString(); switch (propertyInfo.PropertyType.Name) { case nameof(String): s.SettingMode = 1; - s.StringValue = ini.ReadValue(String.Format("storage{0}", s.IniKey), s.SettingName, ""); + s.StringValue = ini.ReadValue(String.Format("dataStorage{0}", s.IniKey), s.SettingName, ""); break; case nameof(Boolean): s.SettingMode = 2; - s.BooleanValue = ini.ReadValue(String.Format("storage{0}", s.IniKey), s.SettingName, false); + s.BooleanValue = ini.ReadValue(String.Format("dataStorage{0}", s.IniKey), s.SettingName, false); break; case nameof(UInt16): s.SettingMode = 3; - s.UshortValue = (ushort)ini.ReadValue(String.Format("storage{0}", s.IniKey), s.SettingName, ushort.MinValue); + s.UshortValue = (ushort)ini.ReadValue(String.Format("dataStorage{0}", s.IniKey), s.SettingName, ushort.MinValue); break; default: throw new NotImplementedException(propertyInfo.PropertyType.Name); @@ -94,19 +104,19 @@ namespace SDL2Demo.Forms private void Save() { - Ini.WriteValue("startup", "storage", storageId); + Ini.WriteValue("startup", "dataStorage", storageId); foreach (Setting setting in settings) { switch (setting.SettingMode) { case 1: - Ini.WriteValue(String.Format("storage{0}", setting.IniKey), setting.SettingName, setting.StringValue); + Ini.WriteValue(String.Format("dataStorage{0}", setting.IniKey), setting.SettingName, setting.StringValue); break; case 2: - Ini.WriteValue(String.Format("storage{0}", setting.IniKey), setting.SettingName, setting.BooleanValue); + Ini.WriteValue(String.Format("dataStorage{0}", setting.IniKey), setting.SettingName, setting.BooleanValue); break; case 3: - Ini.WriteValue(String.Format("storage{0}", setting.IniKey), setting.SettingName, setting.UshortValue); + Ini.WriteValue(String.Format("dataStorage{0}", setting.IniKey), setting.SettingName, setting.UshortValue); break; default: throw new NotImplementedException(String.Format("Setting mode {0}", setting.SettingMode)); @@ -142,16 +152,16 @@ namespace SDL2Demo.Forms ImGui.Begin("Configure ScraperStorage", ref IsOpen, flags); - foreach (KeyValuePair keyValuePair in StorageFactories) + foreach (KeyValuePair keyValuePair in StorageFactories) { - if (ImGui.RadioButton(keyValuePair.Key.DisplayName, ref storageId, keyValuePair.Key.Id)) + if (ImGui.RadioButton(FactoryNames[keyValuePair.Key], ref storageId, keyValuePair.Key)) { HasChanges = true; } - ImGui.BeginTable(keyValuePair.Key.TemporaryUUID, 2); + ImGui.BeginTable(TempGuids[keyValuePair.Key].ToString(), 2); - foreach (Setting setting in settings.Where(x => x.IniKey == keyValuePair.Key.Id)) + foreach (Setting setting in settings.Where(x => x.IniKey == keyValuePair.Key)) { ImGui.TableNextRow(); ImGui.TableSetColumnIndex(0); diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureTunersWindow.cs b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureTunersWindow.cs index 649ecc7..6d934dc 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureTunersWindow.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/ConfigureTunersWindow.cs @@ -3,17 +3,18 @@ using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Equipment; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.Scraper.Storage; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { internal class ConfigureTunersWindow : IRenderable { - private readonly IScraperStroage _scraperStroage; + private readonly DataStorage _scraperStroage; private List satPositions; private List lnbTypes; private List dishTypes; - public ConfigureTunersWindow(List tuners, IScraperStroage scraperStroage) + public ConfigureTunersWindow(List tuners, DataStorage scraperStroage) { _scraperStroage = scraperStroage; Tuners = tuners; diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs b/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs index 578586a..ba00b96 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/LogWindow.cs @@ -8,10 +8,11 @@ using System.Text; using System.Threading.Tasks; using ImGuiNET; using skyscraper5.Skyscraper.Scraper; +using skyscraper8.Skyscraper.Plugins; namespace SDL2Demo.Forms { - internal class LogWindow : IRenderable, ISkyscraperEventLogger + internal class LogWindow : PluginAppenderEx, IRenderable { public LogWindow() { @@ -126,8 +127,7 @@ namespace SDL2Demo.Forms } return logEntriesFirst.Value; } - - private const bool LOG_TO_CONSOLE = true; + private const bool LOG_TO_DEBUG = false; private const bool LOG_TO_TRACE = false; public void Log(string toString, int flags = 1) @@ -143,8 +143,6 @@ namespace SDL2Demo.Forms if (((this.flags) & (flags)) != 0) { logEntries.AddLast(toString); - if (LOG_TO_CONSOLE) - Console.WriteLine(toString); if (LOG_TO_DEBUG) Debug.WriteLine(toString); if (LOG_TO_TRACE) @@ -153,27 +151,12 @@ namespace SDL2Demo.Forms } } } - - public void Log(TimeSpan duration, DateTime eventTimestamp, SkyscraperContextEvent eventType, string name = null) - { - StringBuilder sb = new StringBuilder(); - sb.AppendFormat("[{0} {1}] ", eventTimestamp.ToShortDateString(), eventTimestamp.ToShortTimeString()); - sb.AppendFormat("{0}", eventType.ToString()); - - if (!string.IsNullOrEmpty(name) && !string.IsNullOrWhiteSpace(name)) - { - sb.AppendFormat(" ({0}) ", name); - } - - - if (eventType != SkyscraperContextEvent.StartPacketProcessing && eventType != SkyscraperContextEvent.TdtTime && eventType != SkyscraperContextEvent.TotTime) - { - sb.AppendFormat(" ({0} ms)", duration.TotalMilliseconds); - } - - Log(sb.ToString(),2); - } - + public ulong NumEvents => (uint)logEntries.Count; + + public override void Log(DateTime mappedTime, PluginLogLevel mappedLevel, string? mappedLoggerName, string? mappedMessage) + { + Log(String.Format("{0} {1} [{2}] {3}", mappedTime.ToShortDateString(), mappedTime.ToShortTimeString(), mappedLoggerName, mappedMessage)); + } } } diff --git a/GUIs/skyscraper8.UI.ImGui/Forms/SatellitesConfigurationWindow.cs b/GUIs/skyscraper8.UI.ImGui/Forms/SatellitesConfigurationWindow.cs index c150417..0517f3d 100644 --- a/GUIs/skyscraper8.UI.ImGui/Forms/SatellitesConfigurationWindow.cs +++ b/GUIs/skyscraper8.UI.ImGui/Forms/SatellitesConfigurationWindow.cs @@ -6,12 +6,13 @@ using System.Threading.Tasks; using ImGuiNET; using skyscraper5.Skyscraper; using skyscraper5.Skyscraper.Scraper.Storage; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Forms { internal class SatellitesConfigurationWindow : IRenderable { - public SatellitesConfigurationWindow(IScraperStroage storage) + public SatellitesConfigurationWindow(DataStorage storage) { _storage = storage; lnbPopupUuid = Guid.NewGuid().ToString(); @@ -24,7 +25,7 @@ namespace SDL2Demo.Forms private string lnbPopupUuid; private string memoryTableUuid; private List allPositions; - private readonly IScraperStroage _storage; + private readonly DataStorage _storage; private string name; diff --git a/GUIs/skyscraper8.UI.ImGui/JobContext.cs b/GUIs/skyscraper8.UI.ImGui/JobContext.cs index 5ed2baa..094a808 100644 --- a/GUIs/skyscraper8.UI.ImGui/JobContext.cs +++ b/GUIs/skyscraper8.UI.ImGui/JobContext.cs @@ -5,6 +5,8 @@ using skyscraper5.Skyscraper.Gps; using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.Scraper; using skyscraper5.Skyscraper.Scraper.Storage; +using skyscraper8.Skyscraper.Plugins; +using skyscraper8.Skyscraper.Scraper.Storage; using SkyscraperUI; namespace SDL2Demo @@ -18,8 +20,9 @@ namespace SDL2Demo public Queue MessageQueue { get; set; } public CharSet[] Puppets { get; set; } - public ISkyscraperEventLogger ScraperEventLogger { get; set; } - public IScraperStroage ScraperStorage { get; set; } + public PluginAppenderEx ScraperEventLogger { get; set; } + public DataStorage DataStorage { get; set; } + public ObjectStorage ObjectStorage { get; set; } public bool CanCancel { get; set; } public List Renderables { get; set; } diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs index a8a4278..70db551 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/Blindscan.cs @@ -19,6 +19,7 @@ using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.src.Skyscraper.FrequencyListGenerator; using skyscraper5.src.Mpeg2.PacketFilter; +using skyscraper8.Skyscraper.Scraper.Storage; namespace SDL2Demo.Jobs { @@ -83,9 +84,9 @@ namespace SDL2Demo.Jobs private DbBlindscanJob jobInDb; private IDbBlindscanJobStorage jobStorage; - public Blindscan(List tuners, List satellitePositions, List lnbTypes, IDbBlindscanJobStorage jobStorage) + public Blindscan(List tuners, List satellitePositions, List lnbTypes, DataStorage dataStorage) { - this.jobStorage = jobStorage; + this.jobStorage = dataStorage; continuationDataExists = jobStorage.TestForIncompleteJob(); possibleBlindscanTargets = new List(); @@ -1174,7 +1175,7 @@ namespace SDL2Demo.Jobs } SoundPlayer.PlaySoundFile("Success1.wav"); - skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.ScraperEventLogger, JobContext.ScraperStorage); + skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.DataStorage, JobContext.ObjectStorage); skyscraperContext.TcpProxyEnabled = true; skyscraperContext.UiJunction = jobDisplay; IPacketFilter[] packetFilters = new IPacketFilter[0]; diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs index 0ac3a2e..04a337b 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/CoopBlindscan.cs @@ -847,7 +847,7 @@ namespace SDL2Demo.Jobs SoundPlayer.PlaySoundFile("Success1.wav"); SkipFilter skipper = new SkipFilter(SkipFilter.CRAZYSCAN_BUFFER * 7); - skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.ScraperEventLogger, JobContext.ScraperStorage); + skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.DataStorage, JobContext.ObjectStorage); skyscraperContext.TcpProxyEnabled = true; skyscraperContext.UiJunction = jobDisplay; IPacketFilter[] packetFilters = new IPacketFilter[0]; diff --git a/GUIs/skyscraper8.UI.ImGui/Jobs/ScrapeFromTcp.cs b/GUIs/skyscraper8.UI.ImGui/Jobs/ScrapeFromTcp.cs index 6f31b4a..2c1757e 100644 --- a/GUIs/skyscraper8.UI.ImGui/Jobs/ScrapeFromTcp.cs +++ b/GUIs/skyscraper8.UI.ImGui/Jobs/ScrapeFromTcp.cs @@ -65,7 +65,7 @@ namespace SDL2Demo.Jobs jobDisplay = new JobDisplay(JobContext); JobContext.Puppets[0].AutoMoveTo(new Point(JobContext.Puppets[0].X, 600)); - skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.ScraperEventLogger, JobContext.ScraperStorage); + skyscraperContext = SkyscraperContextFactory.CreateSkyscraper(JobContext.DataStorage, JobContext.ObjectStorage); skyscraperContext.UiJunction = jobDisplay; skyscraperContext.TcpProxyEnabled = true; skyscraperContext.EnableTimeout = allowTimeout; diff --git a/GUIs/skyscraper8.UI.ImGui/Program.cs b/GUIs/skyscraper8.UI.ImGui/Program.cs index b7f7363..64fc4d3 100644 --- a/GUIs/skyscraper8.UI.ImGui/Program.cs +++ b/GUIs/skyscraper8.UI.ImGui/Program.cs @@ -18,8 +18,12 @@ using skyscraper5.Skyscraper.IO; using skyscraper5.Skyscraper.IO.CrazycatStreamReader; using skyscraper5.Skyscraper.IO.TunerInterface; using skyscraper5.Skyscraper.Scraper.Storage; +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 Exception = System.Exception; namespace SkyscraperUI @@ -33,10 +37,13 @@ namespace SkyscraperUI private bool quit; + private static PluginLogger logger = PluginLogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); + private void Run() { rng = new Random(); + logger.Log(PluginLogLevel.Debug, "Loading skyscraper5.ini..."); FileInfo iniFile = new FileInfo("skyscraper5.ini"); if (iniFile.Exists) ini = new Ini(iniFile.FullName); @@ -44,58 +51,71 @@ namespace SkyscraperUI ini = new Ini(); showPuppets = ini.ReadValue("ui", "enable_puppets", true); - - int sdlInit = SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING); + + logger.Log(PluginLogLevel.Debug, "Initializing SDL..."); + int sdlInit = SDL.SDL_Init(SDL.SDL_INIT_EVERYTHING); if (sdlInit != 0) { throw new Exception(SDL.SDL_GetError()); } - int imgInit = SDL_image.IMG_Init(SDL_image.IMG_InitFlags.IMG_INIT_PNG); + logger.Log(PluginLogLevel.Debug, "Initializing SDL_Image..."); + int imgInit = SDL_image.IMG_Init(SDL_image.IMG_InitFlags.IMG_INIT_PNG); if (imgInit != 2) { throw new Exception(SDL.SDL_GetError()); } - window = Window.Create("skyscraper5 GUI", 1280, 720); - renderer = Renderer.Create(window); + logger.Log(PluginLogLevel.Debug, "Create Window..."); + window = Window.Create("skyscraper5 GUI", 1280, 720); + + logger.Log(PluginLogLevel.Debug, "Create Renderer..."); + renderer = Renderer.Create(window); renderer.SetDrawBlendMode(SDL.SDL_BlendMode.SDL_BLENDMODE_BLEND); PictureWindow.Renderer = renderer; - IntPtr intPtr = ImGui.CreateContext(); + logger.Log(PluginLogLevel.Debug, "Create ImGui Context..."); + IntPtr intPtr = ImGui.CreateContext(); ImGui.SetCurrentContext(intPtr); - ImGui.StyleColorsClassic(); ImGui.GetStyle().FrameRounding = 2; ImGui.GetStyle().FrameBorderSize = 1; - imGuiDevice = new ImGuiDevice(window.Pointer, renderer.Pointer); + logger.Log(PluginLogLevel.Debug, "Create ImGui Device..."); + imGuiDevice = new ImGuiDevice(window.Pointer, renderer.Pointer); imGuiDevice.Initialize(); EventPoller.GetInstance().Junction = imGuiDevice; - - Surface charsetSurface = Surface.LoadFromBMP("charset.bmp"); + + logger.Log(PluginLogLevel.Debug, "Loading Puppet Charset..."); + Surface charsetSurface = Surface.LoadFromBMP("charset.bmp"); charsetSurface.SetColorKey(1, 0x00000000); Texture charsetTexture = Texture.FromSurface(renderer, charsetSurface); charsetSurface.Dispose(); - Surface object2Surface = Surface.ImageLoad("Object2.bmp"); + logger.Log(PluginLogLevel.Debug, "Create Pressure Plate Charset..."); + Surface object2Surface = Surface.ImageLoad("Object2.bmp"); object2Surface.SetColorKey(1, 0x00000000); Texture object2Texture = Texture.FromSurface(renderer, object2Surface); object2Surface.Dispose(); object2Charset = new CharSet(object2Texture) { CharacterNumber = 4 }; logWindow = new LogWindow(); + logWindow.Register(); logWindow.IsOpen = ini.ReadValue("ui", "enable_log", true); ; + uiBlockingWindow = new UiBlockingWindow(); messageWindows = new List(); - LoadScreenHacks(); + logger.Log(PluginLogLevel.Debug, "Loading Screen Hacks..."); + LoadScreenHacks(); - Thread theStartupThread = new Thread(StartupThread); + logger.Log(PluginLogLevel.Debug, "Starting Startup Thread..."); + Thread theStartupThread = new Thread(StartupThread); theStartupThread.Priority = ThreadPriority.Lowest; theStartupThread.Start(); - charsets = new CharSet[8]; + logger.Log(PluginLogLevel.Debug, "Formatting Charset..."); + charsets = new CharSet[8]; for (byte i = 0; i < 8; i++) { charsets[i] = new CharSet(charsetTexture) @@ -104,9 +124,11 @@ namespace SkyscraperUI charsets[i].AutoMoveToHome(); } - EventPoller.GetInstance().Quit += TestdridClass_Quit; - - previous = DateTime.Now; + logger.Log(PluginLogLevel.Debug, "Registering Quit Handler..."); + EventPoller.GetInstance().Quit += TestdridClass_Quit; + + logger.Log(PluginLogLevel.Debug, "Entering Main Loop..."); + previous = DateTime.Now; now = DateTime.Now; while (!quit) { @@ -127,7 +149,8 @@ namespace SkyscraperUI if (gps != null) gps.Stop(); - streamReader.Dispose(); + if (streamReader != null) + streamReader.Dispose(); } private void LoadScreenHacks() @@ -165,17 +188,19 @@ namespace SkyscraperUI private ConfigureTunersWindow configureTunersWindow; private Ini ini; - private ReadOnlyCollection> scraperStorageFactories; + private ReadOnlyCollection> dataStorageFactories; + private ReadOnlyCollection> objectStorageFactories; private ReadOnlyCollection> tunerFactories; private IStreamReader streamReader; - private IScraperStroage scraperStroage; + private DataStorage dataStorage; + private ObjectStorage objectStorage; private IGpsReceiver gps; private List messageWindows; private AboutWindow aboutWindow; - private ConfigureStorageWindow configureStorageWindow; + private ConfigureDataStorageWindow configureStorageWindow; private SatellitesConfigurationWindow satellitesConfigurationWindow; private List satellitePositions; private List lnbTypes; @@ -439,9 +464,9 @@ namespace SkyscraperUI if (ImGui.MenuItem("Connect to TCP/IP Stream", CanScrapeFromTcpIp())) scrapeFromTcpWindow = new ScrapeFromTcp(); if (ImGui.MenuItem("Perform Blindscan", CanPerformBlindscan())) - blindscanWindow = new Blindscan(tuners, satellitePositions, lnbTypes, scraperStroage); + blindscanWindow = new Blindscan(tuners, satellitePositions, lnbTypes, dataStorage); if (ImGui.MenuItem("Perform Cooperative Blindscan", CanPerformBlindscan())) - coopBlindscanWindow = new CoopBlindscan(tuners, satellitePositions, lnbTypes, scraperStroage); + coopBlindscanWindow = new CoopBlindscan(tuners, satellitePositions, lnbTypes, dataStorage); if (ImGui.MenuItem("Cancel current job", CanCancelJob())) jobContext.Job.Cancel(); if (ImGui.MenuItem("Quit")) @@ -482,24 +507,24 @@ namespace SkyscraperUI if (ImGui.MenuItem("Configure Tuners", CanOpenTunerConfiguration())) { showConfigureTunersWindow = true; - configureTunersWindow = new ConfigureTunersWindow(tuners, scraperStroage); + configureTunersWindow = new ConfigureTunersWindow(tuners, dataStorage); } if (ImGui.MenuItem("Configure LNB Types", CanOpenLnbTypesConfiguration())) { showConfigureLnbTypesWindow = true; - configureLnbTypesWindow = new ConfigureLnbTypes(scraperStroage, lnbTypes); + configureLnbTypesWindow = new ConfigureLnbTypes(dataStorage, lnbTypes); } if (ImGui.MenuItem("Configure Dish Types", CanOpenDishTypesConfiguration())) { showConfigureDishTypesWindow = true; - configureDishTypesWindow = new ConfigureDishTypes(scraperStroage, dishTypes); + configureDishTypesWindow = new ConfigureDishTypes(dataStorage, dishTypes); } - if (ImGui.MenuItem("Configure ScraperStorage", configureStorageWindow == null)) + if (ImGui.MenuItem("Configure Data Storage", configureStorageWindow == null)) { - configureStorageWindow = new ConfigureStorageWindow(ini, scraperStorageFactories); + configureStorageWindow = new ConfigureDataStorageWindow(ini, dataStorageFactories); } if (ImGui.MenuItem("Configure GPS Receiver", configureGpsWindow == null)) @@ -509,7 +534,7 @@ namespace SkyscraperUI if (ImGui.MenuItem("Configure Satellite Positions", satellitesConfigurationWindow == null)) { - satellitesConfigurationWindow = new SatellitesConfigurationWindow(scraperStroage); + satellitesConfigurationWindow = new SatellitesConfigurationWindow(dataStorage); } ImGui.EndMenu(); @@ -519,7 +544,7 @@ namespace SkyscraperUI { if (ImGui.MenuItem("Delete Blindscan Jobs", CanOpenJobDeleter())) { - jobDeleter = new BlindscanJobDeleter(scraperStroage); + jobDeleter = new BlindscanJobDeleter(dataStorage); } ImGui.EndMenu(); } @@ -635,7 +660,7 @@ namespace SkyscraperUI if (satellitesConfigurationWindow.Closed) { satellitesConfigurationWindow = null; - satellitePositions = scraperStroage.UiSatellitesListAll(); + satellitePositions = dataStorage.UiSatellitesListAll(); } } @@ -755,62 +780,142 @@ namespace SkyscraperUI jobContext.Job = job; jobContext.ReadyForNextJob = false; jobContext.Puppets = charsets; - jobContext.ScraperStorage = scraperStroage; + jobContext.DataStorage = dataStorage; + jobContext.ObjectStorage = objectStorage; jobContext.ScraperEventLogger = logWindow; jobContext.Thread = new Thread(job.Run); jobContext.Thread.Name = "Current Job"; jobContext.Thread.Start(); } + private class StartupThreadType + { + + } + private void StartupThread() { + PluginLogger localLogger = PluginLogManager.GetLogger(typeof(StartupThreadType)); + uiBlockingWindow.Title = "Starting up..."; - uiBlockingWindow.Text = "Please wait while I read the configuration file..."; blockUi = true; //LOAD STORAGE ---------------------------------------------------------------------------------------------------------------------------------------------------------- - uiBlockingWindow.Text = "Please wait while I load the storage factory library..."; - ScraperStorageFactoryConnectionManager scraperStorageFactoryConnectionManager = ScraperStorageFactoryConnectionManager.GetInstance(); - uiBlockingWindow.Text = "Please wait while I check the storage factory classes..."; - scraperStorageFactories = scraperStorageFactoryConnectionManager.GetKnownFactories(); - int storage = ini.ReadValue("startup", "storage", 0); - KeyValuePair bootingStorage = - scraperStorageFactories.First(x => x.Key.Id == storage); - if (bootingStorage.Key.VolatileStorage) - messageWindows.Add(new MessageWindow( - "Please note that Skyscraper is currently using a volatile storage class. This will work, but won't save any data. If you want to save the gathered data, please configure a non-volatile storage class.")); + localLogger.Log(PluginLogLevel.Debug, "Starting Storage Connection Manager..."); + uiBlockingWindow.Text = "Please wait while I acquire a handle to the Storage Connection Manager..."; + StorageConnectionManager connectionManager = StorageConnectionManager.GetInstance(); - uiBlockingWindow.Text = "Please wait while I apply the storage factory class configuration..."; - string factoryCname = String.Format("storage{0}", bootingStorage.Key.Id); - ScraperStorageFactoryConnectionManager.ConfigureFactoryFromIni(bootingStorage, ini); + localLogger.Log(PluginLogLevel.Debug, "Enumerating Data Storage Factories..."); + uiBlockingWindow.Text = "Please wait while I enumerate the data storage factories..."; + dataStorageFactories = connectionManager.GetDataStorages().ToList().AsReadOnly(); - uiBlockingWindow.Text = "Please wait while I start-up the storage..."; + localLogger.Log(PluginLogLevel.Debug, "Enumerating Object Storage Factories..."); + uiBlockingWindow.Text = "Please wait while I enumerate the object storage factories..."; + objectStorageFactories = connectionManager.GetObjectStorages().ToList().AsReadOnly(); + + localLogger.Log(PluginLogLevel.Debug, "Checking for configuration file..."); + uiBlockingWindow.Text = "Please wait while I check for the configuration file..."; + if (!connectionManager.IniExists()) + { + localLogger.Log(PluginLogLevel.Warn, "Configuration file not found!"); + string rant = String.Format("The configuration file does not exist.\r\nPlease create one in the UI!"); + messageWindows.Add(new MessageWindow(rant)); + ini = new Ini(); + blockUi = false; + showMainMenu = true; + return; + } + + DataStorageFactory dataStorageFactory; + try + { + localLogger.Log(PluginLogLevel.Debug, "Getting default data storage factory..."); + uiBlockingWindow.Text = "Please wait while I acquire the default data storage factory..."; + dataStorageFactory = connectionManager.GetDefaultDataStorageFactory(); + } + catch (Exception e) + { + localLogger.Log(PluginLogLevel.Error, "Failed to start the data storage factory: {0}", e.Message); + string rant = String.Format("Could not load the data storage factory.\nThe following went wrong:\n\n{0}\n\n", e.Message); + messageWindows.Add(new MessageWindow(rant)); + blockUi = false; + showMainMenu = true; + return; + } + + ObjectStorageFactory objectStorageFactory; + try + { + localLogger.Log(PluginLogLevel.Debug, "Getting default object storage factory..."); + uiBlockingWindow.Text = "Please wait while I acquire the default object storage factory..."; + objectStorageFactory = connectionManager.GetDefaultObjectStorageFactory(); + } + catch (Exception e) + { + localLogger.Log(PluginLogLevel.Error, "Failed to start the object storage factory: {0}", e.Message); + string rant = String.Format("Could not load the object storage factory.\nThe following went wrong:\n\n{0}\n\n", e.Message); + messageWindows.Add(new MessageWindow(rant)); + blockUi = false; + showMainMenu = true; + return; + } + + uiBlockingWindow.Text = "Please wait while I open the data storage..."; + dataStorage = dataStorageFactory.CreateDataStorage(); + + uiBlockingWindow.Text = "Please wait while I check whether the data storage and the object storage are the same..."; + bool equivalentStorages = objectStorageFactory.IsEquivalent(dataStorageFactory); + + if (equivalentStorages) + { + uiBlockingWindow.Text = "It is."; + uiBlockingWindow.Line2 = "Casting Data Storage to Object Storage."; + objectStorage = (ObjectStorage)dataStorage; + } + else + { + uiBlockingWindow.Text = "It isn't."; + uiBlockingWindow.Line2 = "Creating object storage..."; + objectStorage = objectStorageFactory.CreateObjectStorage(); + } + + + uiBlockingWindow.Text = "Reporting UI Version to the storages..."; + uiBlockingWindow.Line2 = ""; + dataStorage.UiSetVersion(2); + objectStorage.UiSetVersion(2); + + uiBlockingWindow.Text = "Please wait while I test whether the data storage is responding..."; try { - scraperStroage = bootingStorage.Value.CreateScraperStroage(); + dataStorage.Ping(); } catch (Exception e) { - scraperStroage = new InMemoryScraperStorageFactory().CreateScraperStroage(); + string brokenStorageName = connectionManager.GetName(objectStorageFactory); + InMemoryScraperStorageFactory fssf = new InMemoryScraperStorageFactory(); + dataStorage = fssf.CreateDataStorage(); string rant = String.Format( - "{0} failed to start.\nThe following went wrong:\n\n{1}\n\nI've switched to volatile storage. This will work, but won't save any data. If you want to save the gathered data, please consider configuring {0} correctly.", - bootingStorage.Value.GetType().Name, e.Message); + "{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); messageWindows.Add(new MessageWindow(rant)); } - scraperStroage.UiSetVersion(2); - uiBlockingWindow.Text = "Please wait while I test whether the storage is responding..."; + uiBlockingWindow.Text = "Please wait while I test whether the object storage is responding..."; try { - scraperStroage.Ping(); + objectStorage.Ping(); } catch (Exception e) { - scraperStroage = new InMemoryScraperStorageFactory().CreateScraperStroage(); + string brokenStorageName = connectionManager.GetName(objectStorageFactory); + FilesystemScraperStorageFactory fssf = new FilesystemScraperStorageFactory(); + fssf.Directory = "dummy_object_storage"; + objectStorage = fssf.CreateObjectStorage(); string rant = String.Format( - "{0} failed to respond.\nThe following went wrong:\n\n{1}\n\nI've switched to volatile storage. This will work, but won't save any data. If you want to save the gathered data, please consider configuring {0} correctly.", - bootingStorage.Value.GetType().Name, e.Message); + "{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); messageWindows.Add(new MessageWindow(rant)); } @@ -828,19 +933,19 @@ namespace SkyscraperUI //LOAD BASE DATA -------------------------------------------------------------------------------------------------------------------------------------------------------------- uiBlockingWindow.Text = "Please wait while I query the storage for known satellite positions..."; - satellitePositions = scraperStroage.UiSatellitesListAll(); + satellitePositions = dataStorage.UiSatellitesListAll(); uiBlockingWindow.Text = "Please wait while I check for the default LNB types..."; - EquipmentUtilities.InsertDefaultLnbTypes(scraperStroage); + EquipmentUtilities.InsertDefaultLnbTypes(dataStorage); uiBlockingWindow.Text = "Please wait while I query the storage for known LNB types..."; - lnbTypes = scraperStroage.UiLnbTypesListAll(); + lnbTypes = dataStorage.UiLnbTypesListAll(); uiBlockingWindow.Text = "Please wait while I check for the default dish types..."; - EquipmentUtilities.InsertDefaultDishTypes(scraperStroage); + EquipmentUtilities.InsertDefaultDishTypes(dataStorage); uiBlockingWindow.Text = "Please wait while I query the storage for known Dish types..."; - dishTypes = scraperStroage.UiDishTypesListAll(); + dishTypes = dataStorage.UiDishTypesListAll(); //LOAD TUNER -------------------------------------------------------------------------------------------------------------------------------------------------------------------- uiBlockingWindow.Text = "Please wait while I check the Tuner Factory classes..."; @@ -941,9 +1046,9 @@ namespace SkyscraperUI } uiBlockingWindow.Line2 = String.Format("Querying storage for configuration of {0}...", foundTuner.Name); - if (scraperStroage.UiTunerTestFor(foundTuner)) + if (dataStorage.UiTunerTestFor(foundTuner)) { - scraperStroage.UiTunerGetConfiguration(foundTuner); + dataStorage.UiTunerGetConfiguration(foundTuner); } if (tuners == null) diff --git a/GUIs/skyscraper8.UI.ImGui/SdlWrapper/Surface.cs b/GUIs/skyscraper8.UI.ImGui/SdlWrapper/Surface.cs index f048d6a..abcc3fa 100644 --- a/GUIs/skyscraper8.UI.ImGui/SdlWrapper/Surface.cs +++ b/GUIs/skyscraper8.UI.ImGui/SdlWrapper/Surface.cs @@ -19,8 +19,12 @@ namespace testdrid.SdlWrapper public static Surface LoadFromBMP(string filename) { + FileInfo fi = new FileInfo(filename); + if (!fi.Exists) + throw new FileNotFoundException(filename); + Surface result = new Surface(); - result.IntPointer = SDL.SDL_LoadBMP(filename); + result.IntPointer = SDL.SDL_LoadBMP(fi.FullName); if (result.IntPointer == IntPtr.Zero) throw SdlException.GenerateException(); return result; @@ -28,8 +32,12 @@ namespace testdrid.SdlWrapper public static Surface ImageLoad(string filename) { - Surface result = new Surface(); - result.IntPointer = SDL_image.IMG_Load(filename); + FileInfo fi = new FileInfo(filename); + if (!fi.Exists) + throw new FileNotFoundException(filename); + + Surface result = new Surface(); + result.IntPointer = SDL_image.IMG_Load(fi.FullName); if (result.IntPointer == IntPtr.Zero) throw SdlException.GenerateException(); return result; diff --git a/skyscraper8/Skyscraper/Plugins/PluginAppender.cs b/skyscraper8/Skyscraper/Plugins/PluginAppender.cs new file mode 100644 index 0000000..b810317 --- /dev/null +++ b/skyscraper8/Skyscraper/Plugins/PluginAppender.cs @@ -0,0 +1,76 @@ +using log4net; +using log4net.Appender; +using log4net.Core; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using log4net.Repository; +using log4net.Repository.Hierarchy; + +namespace skyscraper8.Skyscraper.Plugins +{ + internal class PluginAppender : AppenderSkeleton + { + private PluginAppenderEx _finalOutput; + protected override void Append(LoggingEvent loggingEvent) + { + PluginLogLevel mappedLevel = MapLevel(loggingEvent.Level); + DateTime mappedTime = DateTime.Now; + string mappedLoggerName = loggingEvent.LoggerName; + string mappedMessage = loggingEvent.MessageObject.ToString(); + _finalOutput.Log(mappedTime, mappedLevel, mappedLoggerName, mappedMessage); + } + + private PluginLogLevel MapLevel(Level loggingEventLevel) + { + if (loggingEventLevel.Equals(Level.Debug)) + return PluginLogLevel.Debug; + else if (loggingEventLevel.Equals(Level.All)) + return PluginLogLevel.All; + else if (loggingEventLevel.Equals(Level.Error)) + return PluginLogLevel.Error; + else if (loggingEventLevel.Equals(Level.Fatal)) + return PluginLogLevel.Fatal; + else if (loggingEventLevel.Equals(Level.Info)) + return PluginLogLevel.Info; + else if (loggingEventLevel.Equals(Level.Warn)) + return PluginLogLevel.Warn; + else if (loggingEventLevel.Equals(Level.Off)) + return PluginLogLevel.Off; + else + throw new NotImplementedException(loggingEventLevel.ToString()); + } + + internal PluginAppender(PluginAppenderEx pex) + { + this._finalOutput = pex; + } + } + + public abstract class PluginAppenderEx + { + private static readonly ILog logger = LogManager.GetLogger(typeof(PluginAppenderEx)); + private PluginAppender appender; + + public abstract void Log(DateTime mappedTime, PluginLogLevel mappedLevel, string? mappedLoggerName, string? mappedMessage); + + private bool registered; + public void Register() + { + if (registered) + throw new PluginsException("Appender was already registered."); + + logger.DebugFormat("Registering a log appender plugin: {0}",this.GetType().Name); + + appender = new PluginAppender(this); + + ILoggerRepository loggerRepository = log4net.LogManager.GetRepository(); + Hierarchy hierarchy = (log4net.Repository.Hierarchy.Hierarchy)loggerRepository; + hierarchy.Root.AddAppender(appender); + + registered = true; + } + } +} diff --git a/skyscraper8/Skyscraper/Plugins/PluginException.cs b/skyscraper8/Skyscraper/Plugins/PluginException.cs new file mode 100644 index 0000000..6941bdb --- /dev/null +++ b/skyscraper8/Skyscraper/Plugins/PluginException.cs @@ -0,0 +1,23 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace skyscraper8.Skyscraper.Plugins +{ + public class PluginsException : SkyscraperCoreException + { + public PluginsException() + { + } + + public PluginsException(string message) : base(message) + { + } + + public PluginsException(string message, Exception inner) : base(message, inner) + { + } + } +} diff --git a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs index eeeee89..7ab8b8e 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/DataStorage.cs @@ -188,5 +188,7 @@ namespace skyscraper8.Skyscraper.Scraper.Storage void DvbNipInsertCarrier(NipActualCarrierInformation currentCarrierInformation); object[] GetPluginConnector(); - } + + void Ping(); + } } diff --git a/skyscraper8/Skyscraper/Scraper/Storage/StorageConnectionManager.cs b/skyscraper8/Skyscraper/Scraper/Storage/StorageConnectionManager.cs index cc3a1d2..7102f45 100644 --- a/skyscraper8/Skyscraper/Scraper/Storage/StorageConnectionManager.cs +++ b/skyscraper8/Skyscraper/Scraper/Storage/StorageConnectionManager.cs @@ -12,7 +12,7 @@ using skyscraper5.Skyscraper.Scraper.Storage; namespace skyscraper8.Skyscraper.Scraper.Storage { - internal class StorageConnectionManager + public class StorageConnectionManager { private StorageConnectionManager() { @@ -124,6 +124,20 @@ namespace skyscraper8.Skyscraper.Scraper.Storage Array.Copy(objectConnector, 0, result, dataConnector.Length, objectConnector.Length); return result; } - + + public bool IniExists() + { + return ini != null; + } + + public ReadOnlyDictionary GetObjectStorages() + { + return plugins.GetObjectStorages(); + } + + public ReadOnlyDictionary GetDataStorages() + { + return plugins.GetDataStorages(); + } } } diff --git a/skyscraper8/Skyscraper/SkyscraperCoreException.cs b/skyscraper8/Skyscraper/SkyscraperCoreException.cs new file mode 100644 index 0000000..1d5a28a --- /dev/null +++ b/skyscraper8/Skyscraper/SkyscraperCoreException.cs @@ -0,0 +1,24 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using skyscraper5; + +namespace skyscraper8.Skyscraper +{ + public class SkyscraperCoreException : SkyscraperException + { + public SkyscraperCoreException() + { + } + + public SkyscraperCoreException(string message) : base(message) + { + } + + public SkyscraperCoreException(string message, Exception inner) : base(message, inner) + { + } + } +}