public async Task ReloadContainerCache() { await Context.Channel.SendMessageAsync("**[Admin]** OK, reloading ContainerCache"); ContainerCache.Dispose(); ContainerCache.Initialize(Program.LOCAL_CONTAINER_CACHE_DIRECTORY); }
private void RenewCache() { _localDataCache = _localDataCache ?? MemoryContext.DataSegment.LocalData; _localDataCache.TakeSnapshot(); var objMgr = MemoryContext.DataSegment.ObjectManager; _objMgrCache = _objMgrCache ?? objMgr; if ((objMgr == null && _objMgrCache != null) || (objMgr.Address != _objMgrCache.Address)) { _playerCache = null; _acdCache = null; _attributeCache = null; _worldCache = null; _sceneCache = null; return; } _objMgrCache.TakeSnapshot(); _playerCache = _playerCache ?? _objMgrCache.Player; _playerCache.TakeSnapshot(); (_acdCache = _acdCache ?? new ContainerCache <MemoryModel.Core.ACD>(_objMgrCache.ACDManager.ActorCommonData)).Update(); (_actorCache = _actorCache ?? new ContainerCache <MemoryModel.Core.Actor>(_objMgrCache.Actors)).Update(); (_attributeCache = _attributeCache ?? new AttributeCache(MemoryContext, _objMgrCache.FastAttrib)).Update(); (_worldCache = _worldCache ?? new ContainerCache <MemoryModel.Core.World>(_objMgrCache.Worlds)).Update(); (_sceneCache = _sceneCache ?? new ContainerCache <MemoryModel.Core.Scene>(_objMgrCache.Scenes)).Update(); AttributeCache.Current = _attributeCache; }
public async Task RebuildIndex() { await Context.Channel.SendMessageAsync("**[Admin]** OK, building index"); // Create a dummy ContainerIndex using latest data ContainerIndex containerIndex = new ContainerIndex(); containerIndex.Event = StrippedContainer.ConvertToStrippedContainer(ContainerCache.GetEvents().First()); containerIndex.LineNews = StrippedContainer.ConvertToStrippedContainer(ContainerCache.GetLineNews().First()); containerIndex.PopUpNews = StrippedContainer.ConvertToStrippedContainer(ContainerCache.GetPopUpNews().First()); containerIndex.Present = StrippedContainer.ConvertToStrippedContainer(ContainerCache.GetPresents().First()); // Acquire the WebFileHandler lock lock (WebFileHandler.Lock) { // Connect WebFileHandler.Connect(((SsbuBotConfiguration)Configuration.LoadedConfiguration).WebConfig); // Write the file WebFileHandler.WriteAllText(((SsbuBotConfiguration)Configuration.LoadedConfiguration).WebConfig.ContainerIndexPath, WebFileHandler.ToJson(containerIndex)); // Disconnect WebFileHandler.Disconnect(); } await Context.Channel.SendMessageAsync("**[Admin]** Done"); }
public async Task AnnounceToChannel(string type, string id) { switch (type) { case "event": await EventDiscordHandler.HandleAdded(ContainerCache.GetEventWithId(id)); break; case "linenews": await LineNewsDiscordHandler.HandleAdded(ContainerCache.GetLineNewsWithId(id)); break; case "popupnews": await PopUpNewsDiscordHandler.HandleAdded(ContainerCache.GetPopUpNewsWithId(id)); break; case "present": await PresentDiscordHandler.HandleAdded(ContainerCache.GetPresentWithId(id)); break; default: throw new Exception("Invalid type (must be event, linenews, popupnews, or present)"); } await Context.Channel.SendMessageAsync("**[Admin]** OK, notified"); }
public void Dispose() { if (_wasDisposed) { return; } _wasDisposed = true; if (Role == ContainerRole.Root) { _singletons.DisposeAndClear(); } ContainerCache.DisposeAndClear(); _transients.DisposeAndClear(); _pluginGraph.SafeDispose(); if (Role == ContainerRole.Root) { _profiles.AllProfiles().Each(x => x.Dispose()); } _trackedDisposables.Each(x => x.Dispose()); }
public async Task RebuildList(string type) { await Context.Channel.SendMessageAsync("**[Admin]** OK, building list"); // Create a new StrippedContainer list List <StrippedContainer> containerList = new List <StrippedContainer>(); // Declare a variable to hold the path string indexPath = ((SsbuBotConfiguration)Configuration.LoadedConfiguration).WebConfig.ContainerListPath; switch (type) { case "event": ContainerCache.GetEvents().ForEach(x => containerList.Add(StrippedContainer.ConvertToStrippedContainer(x))); indexPath = string.Format(indexPath, "event"); break; case "linenews": ContainerCache.GetLineNews().ForEach(x => containerList.Add(StrippedContainer.ConvertToStrippedContainer(x))); indexPath = string.Format(indexPath, "line_news"); break; case "popupnews": ContainerCache.GetPopUpNews().ForEach(x => containerList.Add(StrippedContainer.ConvertToStrippedContainer(x))); indexPath = string.Format(indexPath, "popup_news"); break; case "present": ContainerCache.GetPresents().ForEach(x => containerList.Add(StrippedContainer.ConvertToStrippedContainer(x))); indexPath = string.Format(indexPath, "present"); break; default: throw new Exception("Invalid type (must be event, linenews, popupnews, or present)"); } // Acquire the WebFileHandler lock lock (WebFileHandler.Lock) { // Connect WebFileHandler.Connect(((SsbuBotConfiguration)Configuration.LoadedConfiguration).WebConfig); // Upload the file WebFileHandler.WriteAllText(indexPath, WebFileHandler.ToJson(containerList)); // Disconnect WebFileHandler.Disconnect(); } await Context.Channel.SendMessageAsync("**[Admin]** Done"); }
public static async Task ListContainers(FileType fileType, Language language, SocketCommandContext context) { // Create a list of IDs and their names List <string> ids = new List <string>(); switch (fileType) { case FileType.Event: foreach (Event smashEvent in ContainerCache.GetEvents()) { ids.Add($"``{smashEvent.Id}`` - {smashEvent.TitleText[language]}"); } break; case FileType.LineNews: foreach (LineNews lineNews in ContainerCache.GetLineNews()) { ids.Add($"``{lineNews.Id}``"); } break; case FileType.PopUpNews: // TODO: hack something better can be made, pages maybe? foreach (PopUpNews news in ContainerCache.GetPopUpNews().Where(x => !x.Id.Contains("_")).Take(10)) { ids.Add($"``{news.Id}`` - {news.TitleText[language]}"); } ids.Add("(only the 10 most recent Pop-Up News is displayed)"); break; case FileType.Present: foreach (Present present in ContainerCache.GetPresents()) { ids.Add($"``{present.Id}`` - {present.TitleText[language]}"); } break; default: throw new LocalizedException("list.unknown_file_type"); } Embed embed = new EmbedBuilder() .WithTitle(Localizer.Localize("list.title", language)) .WithDescription(Localizer.Localize("list.description", language) + string.Join('\n', ids) + "") .WithColor(Color.Green) .Build(); await context.Channel.SendMessageAsync(embed : embed); }
protected virtual async Task <FileContainerConfiguration> GetConfigurationAsync(string name) { var cacheItem = await ContainerCache.GetOrAddAsync( name, async() => { var container = await FileStoringContainerRepository.FindByNameAsync(name, true); return(container?.AsCacheItem()); }); return(cacheItem == null ? null : FileContainerConfigurationConverter.ToConfiguration(cacheItem)); }
public async Task Execute(string id = null, string languageString = null) { // Get the language Language language = DiscordUtil.GetDefaultLanguage(Context.Guild, languageString); // Check for no ID if (id == null) { await ListCommand.ListContainers(FileType.LineNews, language, Context); return; } // Get the PopUpNews with this ID LineNews lineNews = ContainerCache.GetLineNewsWithId(id); // Check if this exists if (lineNews == null) { throw new LocalizedException("line_news.not_found"); } // Localize the title string titleKey = "line_news.title"; string localizedTitle = string.Format(Localizer.Localize(titleKey, language), lineNews.Id); // Localize the description string descriptionKey = "line_news.description"; string localizedDescription = string.Format(Localizer.Localize(descriptionKey, language), $"https://smash.oatmealdome.me/line_news/{lineNews.Id}/{language.GetCode()}/"); // Localize the line field name string lineFieldNameKey = "line_news.line_title"; string localizedLineFieldName = Localizer.Localize(lineFieldNameKey, language); // Construct the Embed EmbedBuilder embedBuilder = new EmbedBuilder() .WithTitle(localizedTitle) //.WithDescription(localizedDescription) .AddField(Localizer.Localize("line_news.start_time", language), Localizer.LocalizeDateTime(lineNews.StartDateTime, language), true) .AddField(Localizer.Localize("line_news.end_time", language), Localizer.LocalizeDateTime(lineNews.EndDateTime, language), true); // Add every OneLine foreach (OneLine oneLine in lineNews.OneLines) { embedBuilder.AddField(string.Format(localizedLineFieldName, oneLine.Id), oneLine.Text[language]); } await Context.Channel.SendMessageAsync(embed : embedBuilder.Build()); }
private void Reset() { _minimapItemsDic.Clear(); if (_minimapItems.Count > 0) { Execute.OnUIThread(() => _minimapItems.Clear()); } _acdsObserver = null; _playerAcd = null; _ignoredSnoIds.Clear(); _localData = null; _objectManager = null; _isLocalActorReady = false; _previousFrame = 0; }
protected override async Task RunAppSpecificBootTasks() { // Create the cache directories if needed System.IO.Directory.CreateDirectory(Program.LOCAL_CONTAINER_CACHE_DIRECTORY); System.IO.Directory.CreateDirectory(Program.LOCAL_COMMON_CACHE_DIRECTORY); // Initialize the ContainerCache ContainerCache.Initialize(Program.LOCAL_CONTAINER_CACHE_DIRECTORY); await Task.FromResult(0); /*await DiscordBot.LoggingChannel.SendMessageAsync($"**[BootHousekeepingJob]** Scheduling archivals"); * * // Archive all Container pages in production mode * if (Configuration.LoadedConfiguration.IsProduction) * { * // Declare the minutes offset to stagger the archival jobs * int minutesOffset = 1; * * // Get the current DateTime in UTC * DateTime nowTime = DateTime.UtcNow; * * async Task ScheduleArchivalIfEligible(Nintendo.SmashUltimate.Bcat.Container container) * { * // Check if the Container's page is active * if (container.StartDateTime < nowTime && container.EndDateTime > nowTime) * { * // Schedule the Job * if (await ContainerArchivalHandler.ScheduleArchival(container, nowTime.AddMinutes(minutesOffset))) * { * // Increment the minutes * minutesOffset++; * } * } * } * * // Schedule for all PopUpNews and Events * foreach (PopUpNews popUpNews in ContainerCache.GetPopUpNews()) * { * await ScheduleArchivalIfEligible(popUpNews); * } * * foreach (Event smashEvent in ContainerCache.GetEvents()) * { * await ScheduleArchivalIfEligible(smashEvent); * } * }*/ }
public async Task Execute(string id = null, string languageString = null) { // Get the language Language language = DiscordUtil.GetDefaultLanguage(Context.Guild, languageString); // Check for no ID if (id == null) { await ListCommand.ListContainers(FileType.Present, language, Context); return; } // Get the Present with this ID Present present = ContainerCache.GetPresentWithId(id); // Check if this exists if (present == null) { throw new LocalizedException("present.not_found"); } // Localize the description string localizedDescription = string.Format(Localizer.Localize("present.description", language), present.ContentText[language], $"https://smash.oatmealdome.me/present/{present.Id}/{language.GetCode()}/"); // Construct the image URL string url = $"https://cdn.oatmealdome.me/smash/present/{present.Id}/image.jpg"; // Construct the Embed Embed embed = new EmbedBuilder() .WithTitle(present.TitleText[language]) .WithDescription(localizedDescription) .AddField(Localizer.Localize("present.start_time", language), Localizer.LocalizeDateTime(present.StartDateTime, language), true) .AddField(Localizer.Localize("present.end_time", language), Localizer.LocalizeDateTime(present.EndDateTime, language), true) .WithImageUrl(url) .Build(); await Context.Channel.SendMessageAsync(embed : embed); }
public async Task UploadCacheToS3() { await Context.Channel.SendMessageAsync("**[Admin]** OK, building list"); List <Container> allContainers = new List <Container>(); // Add all Containers to the List allContainers.AddRange(ContainerCache.GetEvents()); allContainers.AddRange(ContainerCache.GetLineNews()); allContainers.AddRange(ContainerCache.GetPopUpNews()); allContainers.AddRange(ContainerCache.GetPresents()); // Loop over every Container foreach (Container container in allContainers) { await Context.Channel.SendMessageAsync("**[Admin]** Uploading " + container.GetType().Name + " with ID " + container.Id); ContainerWebHandler.HandleContainer(container); } await Context.Channel.SendMessageAsync("**[Admin]** Done"); }
protected override async Task Run() { await DiscordBot.LoggingChannel.SendMessageAsync($"**[WebPConversionOneTimeTask]** Starting WebP image conversion"); List <Container> allContainers = new List <Container>(); // Add all Containers to the List allContainers.AddRange(ContainerCache.GetEvents()); allContainers.AddRange(ContainerCache.GetPopUpNews()); allContainers.AddRange(ContainerCache.GetPresents()); // Loop over every Container foreach (Container container in allContainers) { // Get the FileType FileType fileType = FileTypeExtensions.GetTypeFromContainer(container); // Format the destination S3 path string s3Path = $"/smash/{FileTypeExtensions.GetNamePrefixFromType(fileType)}/{container.Id}"; // Get the raw image byte[] jpgImage = (byte[])container.GetType().GetProperty("Image").GetValue(container); // Create a new MagickImage using (MagickImage image = new MagickImage(jpgImage)) { // Set the output format to WebP image.Format = MagickFormat.WebP; // Create the raw WebP byte[] webpImage = image.ToByteArray(); await DiscordBot.LoggingChannel.SendMessageAsync($"**[WebPConversionOneTimeTask]** Uploading image for {fileType.ToString()} ID {container.Id}"); // Upload to S3 S3Api.TransferFile(webpImage, s3Path, "image.webp", "image/webp"); } } }
public void Update(MemoryContext ctx) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } ctx.Memory.Reader.ResetCounters(); try { if (!IsLocalActorValid(ctx)) { return; } if (!IsObjectManagerOnNewFrame(ctx)) { return; } var itemsToAdd = new List <IMapMarker>(); var itemsToRemove = new List <IMapMarker>(); _acdsObserver = _acdsObserver ?? new ContainerCache <ACD>(ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData); _acdsObserver.Update(); // Must have a local ACD to base coords on. if (_playerAcd == null) { var playerAcdId = ctx.DataSegment.ObjectManager.PlayerDataManager[ ctx.DataSegment.ObjectManager.Player.LocalPlayerIndex].ACDID; _playerAcd = _acdsObserver.Items[(short)playerAcdId]; } foreach (var acd in ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData) { Console.WriteLine(acd.Name); if (!((acd.MonsterQuality == MonsterQuality.Champion) || (acd.MonsterQuality == MonsterQuality.Rare) || (acd.MonsterQuality == MonsterQuality.Boss))) { continue; } if (WindowsInput.InputSimulator.IsKeyDown(VirtualKeyCode.TAB)) { System.Drawing.Point MouseCords = D3ToScreen.FromD3toScreenCoords(acd.Position, _playerAcd.Position); if ((MouseCords.X > 0 && MouseCords.Y > 0) && (MouseCords.X < System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width && MouseCords.Y < System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height)) { SetCursorPos(MouseCords.X, MouseCords.Y); Thread.Sleep(600); } //System.Windows.MessageBox.Show("X " + MouseCords.X); } } } catch (Exception exception) { OnUpdateException(exception); } }
public void Update(MemoryContext ctx) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } ctx.Memory.Reader.ResetCounters(); try { if (!IsLocalActorValid(ctx)) { return; } if (!IsObjectManagerOnNewFrame(ctx)) { return; } var itemsToAdd = new List <IMapMarker>(); var itemsToRemove = new List <IMapMarker>(); _acdsObserver = _acdsObserver ?? new ContainerCache <ACD>(ctx.DataSegment.ObjectManager.ACDManager.ActorCommonData); _acdsObserver.Update(); // Must have a local ACD to base coords on. if (_playerAcd == null) { var playerAcdId = ctx.DataSegment.ObjectManager.PlayerDataManager[ ctx.DataSegment.ObjectManager.Player.LocalPlayerIndex].ACDID; _playerAcd = _acdsObserver.Items[(short)playerAcdId]; } foreach (var acd in _acdsObserver.OldItems) { var marker = default(IMapMarker); if (_minimapItemsDic.TryGetValue(acd.Address, out marker)) { Trace.WriteLine("Removing " + acd.Name); itemsToRemove.Add(marker); } } foreach (var acd in _acdsObserver.NewItems) { var actorSnoId = acd.ActorSNO; if (_ignoredSnoIds.Contains(actorSnoId)) { continue; } if (!_minimapItemsDic.ContainsKey(acd.Address)) { bool ignore; var minimapItem = MapMarkerFactory.Create(acd, out ignore); if (ignore) { _ignoredSnoIds.Add(actorSnoId); } else if (minimapItem != null) { _minimapItemsDic.Add(acd.Address, minimapItem); itemsToAdd.Add(minimapItem); } } } UpdateUI(itemsToAdd, itemsToRemove); } catch (Exception exception) { OnUpdateException(exception); } }
protected override void ShutdownAppSpecificItems() { // Shutdown the ContainerCache ContainerCache.Dispose(); }
public async Task Execute() { if (Configuration.LoadedConfiguration.IsProduction) { return; } /*Event marioEvent = ContainerCache.GetEventWithId(1003); * string path = Path.Combine(Path.GetDirectoryName(Program.LOCAL_LAST_TOPIC), "debug-event.json"); * File.WriteAllText(path, ToJson(marioEvent));*/ //await Context.Channel.SendMessageAsync("test <:thonk:508037103473655831>"); //throw new Exception("test exception"); //TestMessage testMessage = new TestMessage(Context.User); //await DiscordBot.SendInteractiveMessageAsync(Context.Channel, testMessage); //RecurringHousekeepingJob job = new RecurringHousekeepingJob(); //await job.Execute(null); //TwitterManager.GetAccount("SSBUBot").Tweet("[Test]", "test tweet from debug command", "URL: https://google.com"); //LineNewsTwitterHandler.HandleAdded(ContainerCache.GetLineNews().Last()); /*IList<PopUpNews> newsList = ContainerCache.GetPopUpNews(); * PopUpNews longestNews = newsList.FirstOrDefault(); * foreach (PopUpNews news in newsList) * { * if (news.TitleText[Language.EnglishUS].Length > longestNews.TitleText[Language.EnglishUS].Length) * { * longestNews = news; * } * } * * await Context.Channel.SendMessageAsync("[Debug] tweeting " + longestNews.Id); * * PopUpNewsTwitterHandler.HandleAdded(longestNews);*/ /*IList<LineNews> newsList = ContainerCache.GetLineNews(); * * LineNews longestNews = newsList.FirstOrDefault(); * OneLine longestLine = longestNews.OneLines[0]; * * foreach (LineNews news in newsList) * { * foreach (OneLine line in news.OneLines) * { * if (line.Text[Language.EnglishUS].Length > longestLine.Text[Language.EnglishUS].Length) * { * longestNews = news; * longestLine = line; * } * } * } * * await Context.Channel.SendMessageAsync("[Debug] line news " + longestNews.Id + ", oneline " + longestLine.Id + " is " + longestLine.Text[Language.EnglishUS].Length);*/ await Context.Channel.SendMessageAsync("[Debug] Test tweets..."); PopUpNewsTwitterHandler.HandleAdded(ContainerCache.GetPopUpNews().FirstOrDefault()); PresentTwitterHandler.HandleAdded(ContainerCache.GetPresents().FirstOrDefault()); LineNewsTwitterHandler.HandleAdded(ContainerCache.GetLineNews().FirstOrDefault()); }
public async Task Execute(IJobExecutionContext context) { try { // Log that we're about to begin a check await DiscordBot.LoggingChannel.SendMessageAsync("**[BCAT]** Beginning check"); // Download the latest Topic Topic topic = await BcatApi.GetDataTopic(Program.TITLE_ID, Program.PASSPHRASE); // Create the target folder name string targetFolder = string.Format(Program.LOCAL_OLD_DATA_DIRECTORY, DateTime.Now.ToString(Program.FOLDER_DATE_TIME_FORMAT)); // Check if this the first run if (!Configuration.LoadedConfiguration.FirstRunCompleted) { // Log that this is the first run of BCAT await DiscordBot.LoggingChannel.SendMessageAsync("**[BCAT]** First run"); // Download all data Dictionary <string, byte[]> downloadedData = await BcatCheckerUtils.DownloadAllData(topic, Program.TITLE_ID, Program.PASSPHRASE, targetFolder); // Loop over all data foreach (KeyValuePair <string, byte[]> pair in downloadedData) { // Get the FileType FileType fileType = FileTypeExtensions.GetTypeFromName(pair.Key); // Check if this is a container if (fileType.IsContainer()) { // Create a Container instance Nintendo.SmashUltimate.Bcat.Container container = CreateSmashContainerInstance(fileType, pair.Value); // Add this to the container cache ContainerCache.AddFile(container, Path.GetFileName(pair.Key), pair.Value); } else { // Write this file out to the common file cache File.WriteAllBytes(Path.Combine(Program.LOCAL_COMMON_CACHE_DIRECTORY, Path.GetFileName(pair.Key)), pair.Value); } } // Save the configuration Configuration.LoadedConfiguration.FirstRunCompleted = true; Configuration.LoadedConfiguration.Write(); // Write out the topic File.WriteAllBytes(Program.LOCAL_LAST_TOPIC, MessagePackSerializer.Serialize(topic)); // Log that we're about to begin a check await DiscordBot.LoggingChannel.SendMessageAsync("**[BCAT]** First run complete"); return; } // Load the old Topic Topic oldTopic = MessagePackSerializer.Deserialize <Topic>(File.ReadAllBytes(Program.LOCAL_LAST_TOPIC)); #if DEBUG if (!Configuration.LoadedConfiguration.IsProduction) { /*foreach (Bcat.Directory dir in oldTopic.Directories) * { * if (dir.Name == "line_news") * { * Data dbgData = dir.Data.FirstOrDefault(); * if (dbgData == null) * { * continue; * } * dir.Data.Remove(dbgData); * //dbgData.Digest = "deadbeef"; * } * }*/ } #endif // Get the differences List <KeyValuePair <DifferenceType, string> > differences = BcatCheckerUtils.GetTopicChanges(oldTopic, topic); // Check if there aren't any if (differences.Count == 0) { // Nothing to do here goto finished; } // Download all data Dictionary <string, byte[]> data = await BcatCheckerUtils.DownloadAllData(topic, Program.TITLE_ID, Program.PASSPHRASE, targetFolder); // Loop over every difference foreach (KeyValuePair <DifferenceType, string> pair in differences) { // Log the difference await DiscordBot.LoggingChannel.SendMessageAsync("**[BCAT]** diff: ``" + pair.Value + "`` (" + pair.Key.ToString() + ")"); // Get the FileType FileType fileType = FileTypeExtensions.GetTypeFromName(pair.Value); // Declare a variable to hold the method parameters object[] parameters; if (pair.Key == DifferenceType.Added) { // Get the raw file byte[] rawFile = data[pair.Value]; // Check if this is a Container if (fileType.IsContainer()) { // Create a Container instance Nintendo.SmashUltimate.Bcat.Container addedContainer = CreateSmashContainerInstance(fileType, data[pair.Value]); // Add this to the container cache ContainerCache.AddFile(addedContainer, Path.GetFileName(pair.Value), rawFile); // Set the method parameters parameters = new object[] { addedContainer }; } else { // Write this file out to the common file cache File.WriteAllBytes(Path.Combine(Program.LOCAL_COMMON_CACHE_DIRECTORY, Path.GetFileName(pair.Value)), data[pair.Value]); // Set the method parameters parameters = new object[] { rawFile }; } } else if (pair.Key == DifferenceType.Changed) { // Get the raw file byte[] rawFile = data[pair.Value]; // Check if this is a Container if (fileType.IsContainer()) { // Create a Container instance Nintendo.SmashUltimate.Bcat.Container addedContainer = CreateSmashContainerInstance(fileType, data[pair.Value]); // Overwrite this to the container cache Nintendo.SmashUltimate.Bcat.Container previousContainer = ContainerCache.OverwriteFile(addedContainer, Path.GetFileName(pair.Value), rawFile); // Set the method parameters parameters = new object[] { previousContainer, addedContainer }; } else { // Construct the commoon cache path string path = Path.Combine(Program.LOCAL_COMMON_CACHE_DIRECTORY, Path.GetFileName(pair.Value)); // Load the old file byte[] previousRawFile = File.ReadAllBytes(path); // Write this file out to the common file cache File.WriteAllBytes(path, data[pair.Value]); // Set the method parameters parameters = new object[] { previousRawFile, rawFile }; } } else // Removed { // TODO: discord print continue; } // Call every difference handler await BcatCheckerUtils.CallDifferenceHandlers((int)fileType, pair.Key, parameters); } // Write out the Topic File.WriteAllBytes(Program.LOCAL_LAST_TOPIC, MessagePackSerializer.Serialize(topic)); finished: await DiscordBot.LoggingChannel.SendMessageAsync("**[BCAT]** Check complete"); } catch (Exception exception) { // Notify the logging channel await DiscordUtil.HandleException(exception, $"in ``BcatCheckerJob``"); } }