Beispiel #1
0
        public PacketDocumentViewModel(PacketDocumentSolutionItem solutionItem,
                                       IMainThread mainThread,
                                       MostRecentlySearchedService mostRecentlySearchedService,
                                       IDatabaseProvider databaseProvider,
                                       Func <INativeTextDocument> nativeTextDocumentCreator,
                                       IMessageBoxService messageBoxService,
                                       IPacketFilteringService filteringService,
                                       IDocumentManager documentManager,
                                       ITextDocumentService textDocumentService,
                                       IWindowManager windowManager,
                                       IPacketViewerSettings packetSettings,
                                       IEnumerable <IPacketDumperProvider> dumperProviders,
                                       ISniffLoader sniffLoader)
        {
            this.solutionItem      = solutionItem;
            this.mainThread        = mainThread;
            this.messageBoxService = messageBoxService;
            this.filteringService  = filteringService;
            this.sniffLoader       = sniffLoader;
            packetViewModelCreator = new PacketViewModelFactory(databaseProvider);
            MostRecentlySearched   = mostRecentlySearchedService.MostRecentlySearched;
            Title                 = "Sniff " + Path.GetFileNameWithoutExtension(solutionItem.File);
            SolutionItem          = solutionItem;
            FilterText            = nativeTextDocumentCreator();
            SelectedPacketPreview = nativeTextDocumentCreator();
            Watch(this, t => t.FilteringProgress, nameof(ProgressUnknown));

            filteredPackets    = AllPackets;
            ApplyFilterCommand = new AsyncCommand(async() =>
            {
                if (inApplyFilterCommand)
                {
                    return;
                }

                inApplyFilterCommand     = true;
                MostRecentlySearchedItem = FilterText.ToString();
                inApplyFilterCommand     = false;

                if (!string.IsNullOrEmpty(FilterText.ToString()))
                {
                    mostRecentlySearchedService.Add(FilterText.ToString());
                }

                if (currentActionToken != filteringToken)
                {
                    throw new Exception("Invalid concurrent access!");
                }
                filteringToken?.Cancel();
                filteringToken     = null;
                currentActionToken = null;
                await FilterPackets(FilterText.ToString());
            });

            SaveToFileCommand = new AsyncCommand(async() =>
            {
                var path = await windowManager.ShowSaveFileDialog("Text file|txt");
                if (path == null)
                {
                    return;
                }

                LoadingInProgress   = true;
                FilteringInProgress = true;
                try
                {
                    await using StreamWriter writer = File.CreateText(path);
                    int i     = 0;
                    int count = FilteredPackets.Count;
                    foreach (var packet in FilteredPackets)
                    {
                        await writer.WriteLineAsync(packet.Text);
                        if ((i % 100) == 0)
                        {
                            Report(i * 1.0f / count);
                        }
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    await this.messageBoxService.ShowDialog(new MessageBoxFactory <bool>()
                                                            .SetTitle("Fatal error")
                                                            .SetMainInstruction("Fatal error during saving file")
                                                            .SetContent(e.Message)
                                                            .WithOkButton(false)
                                                            .Build());
                }
                LoadingInProgress   = false;
                FilteringInProgress = false;
            });

            OpenHelpCommand = new DelegateCommand(() => windowManager.OpenUrl("https://github.com/BAndysc/WoWDatabaseEditor/wiki/Packet-Viewer"));

            On(() => SelectedPacket, doc =>
            {
                if (doc != null)
                {
                    SelectedPacketPreview.FromString(doc.Text);
                }
            });

            On(() => SplitUpdate, _ =>
            {
                SplitPacketsIfNeededAsync().Wait();
                ((ICommand)ApplyFilterCommand).Execute(null);
            });

            foreach (var dumper in dumperProviders)
            {
                Processors.Add(new(dumper));
            }

            RunProcessors = new AsyncAutoCommand(async() =>
            {
                var processors = Processors.Where(s => s.IsChecked).ToList();
                if (processors.Count == 0)
                {
                    return;
                }

                LoadingInProgress   = true;
                FilteringInProgress = true;
                try
                {
                    var tokenSource = new CancellationTokenSource();
                    AssertNoOnGoingTask();
                    currentActionToken = tokenSource;

                    var output = await RunProcessorsThreaded(processors, tokenSource.Token).ConfigureAwait(true);

                    if (!tokenSource.IsCancellationRequested)
                    {
                        var extension = processors.Select(p => p.Extension).Distinct().Count() == 1
                            ? processors[0].Extension
                            : "txt";
                        documentManager.OpenDocument(textDocumentService.CreateDocument($"{processors[0].Name} ({Title})", output, extension));
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    await messageBoxService.ShowDialog(new MessageBoxFactory <bool>()
                                                       .SetIcon(MessageBoxIcon.Error)
                                                       .SetTitle("Fatal error")
                                                       .SetMainInstruction("Fatal error during processing")
                                                       .SetContent(
                                                           "Sorry, fatal error occured, this is probably a bug in processors, please report it in github\n\n" + e)
                                                       .WithOkButton(true)
                                                       .Build());
                }
                LoadingInProgress   = false;
                FilteringInProgress = false;
                currentActionToken  = null;
            }, _ => Processors.Any(c => c.IsChecked));

            foreach (var proc in Processors)
            {
                AutoDispose(proc.ToObservable(p => p.IsChecked)
                            .SubscribeAction(_ => RunProcessors.RaiseCanExecuteChanged()));
            }

            wrapLines   = packetSettings.Settings.WrapLines;
            splitUpdate = packetSettings.Settings.AlwaysSplitUpdates;
            if (!string.IsNullOrEmpty(packetSettings.Settings.DefaultFilter))
            {
                FilterText.FromString(packetSettings.Settings.DefaultFilter);
            }
            LoadSniff().ListenErrors();

            AutoDispose(new ActionDisposable(() => currentActionToken?.Cancel()));
        }