~ruther/NosTale-PacketLogger

39ccc8e1759ba341c324146a6268e55dd6d340a3 — Rutherther 2 years ago 82a2a8f
fix: make no profile working correctly, changing to no profile on change
A src/PacketLogger/Converters/EnumToBooleanConverter.cs => src/PacketLogger/Converters/EnumToBooleanConverter.cs +28 -0
@@ 0,0 1,28 @@
//
//  EnumToBooleanConverter.cs
//
//  Copyright (c) František Boháček. All rights reserved.
//  Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;
using System.Globalization;
using Avalonia.Data;
using Avalonia.Data.Converters;

namespace PacketLogger.Converters;

/// <inheritdoc />
public class EnumToBooleanConverter : IValueConverter
{
    /// <inheritdoc />
    public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        return value?.Equals(parameter);
    }

    /// <inheritdoc />
    public object? ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
    {
        return value?.Equals(true) == true ? parameter : BindingOperations.DoNothing;
    }
}
\ No newline at end of file

M src/PacketLogger/Models/Filters/FilterProfiles.cs => src/PacketLogger/Models/Filters/FilterProfiles.cs +6 -1
@@ 29,7 29,7 @@ public class FilterProfiles
        AllProfiles = new ObservableCollection<FilterProfile>();
        SelectableProfiles = new ObservableCollection<FilterProfile>();

        SelectableProfiles.Add(new FilterProfile(false)
        SelectableProfiles.Add(NoProfile = new FilterProfile(false)
        {
            Name = "No profile"
        });


@@ 74,6 74,11 @@ public class FilterProfiles
    public ObservableCollection<FilterProfile> AllProfiles { get; }

    /// <summary>
    /// Gets or sets the profile used as no profile.
    /// </summary>
    public FilterProfile NoProfile { get; set; }

    /// <summary>
    /// Add the given profile.
    /// </summary>
    /// <param name="profile">The profile to add.</param>

M src/PacketLogger/ViewModels/Filters/FilterChooseViewModel.cs => src/PacketLogger/ViewModels/Filters/FilterChooseViewModel.cs +60 -24
@@ 7,6 7,8 @@
using System;
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reflection.Metadata.Ecma335;
using Avalonia.Controls.Notifications;
using DynamicData;
using DynamicData.Binding;
using PacketLogger.Models.Filters;


@@ 20,22 22,26 @@ namespace PacketLogger.ViewModels.Filters;
public class FilterChooseViewModel : ViewModelBase, IDisposable
{
    private FilterProfile _currentProfile = null!;
    private FilterProfile _currentRealProfile = null!;
    private IDisposable? _cleanUp;
    private FilterProfile _noProfile;
    private FilterProfile _noRealProfile;

    /// <summary>
    /// Initializes a new instance of the <see cref="FilterChooseViewModel"/> class.
    /// </summary>
    /// <param name="currentProfile">The current filter profile.</param>
    public FilterChooseViewModel(FilterProfile currentProfile)
    /// <param name="noProfile">The real no profile.</param>
    public FilterChooseViewModel(FilterProfile currentProfile, FilterProfile noProfile)
    {
        RecvFilterSelected = true;
        CurrentProfile = currentProfile;
        CurrentFilter = CreateSendRecvFilter();
        _noProfile = new FilterProfile(false)
        {
            Name = "No profile"
        };
        _noRealProfile = noProfile;
        RecvFilterSelected = true;
        CurrentProfile = currentProfile;
        CurrentFilter = CreateSendRecvFilter();
    }

    /// <summary>


@@ 51,10 57,25 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable
                return;
            }

            if (value.Name == "No profile" && value != _noProfile)
            var setCurrentProfile = value;
            if (value.Name == "No profile")
            {
                CurrentProfile = _noProfile;
                return;
                if (value != _noProfile)
                {
                    value = _noProfile;
                }
                else
                {
                    setCurrentProfile = _noRealProfile;
                }

                CopyCurrentToNoProfile(_currentProfile);
            }

            var cleanUp = new CompositeDisposable();
            if (RecvEntryViewModel is not null)
            {
                cleanUp = new CompositeDisposable(RecvEntryViewModel, SendEntryViewModel);
            }

            var lastProfile = value;


@@ 65,15 86,19 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable
                    value.RecvFilterEntry,
                    (data) =>
                    {
                        CopyCurrentToNoProfile(lastProfile);
                        _noProfile.RecvFilterEntry.Filters.Add(data);
                        CurrentProfile = _noProfile;
                        _noProfile.RecvFilterEntry.Filters.Add(data);
                    },
                    (data) =>
                    {
                        CopyCurrentToNoProfile(lastProfile);
                        CurrentProfile = _noProfile;
                        _noProfile.RecvFilterEntry.Filters.Remove(data);
                    },
                    (data) =>
                    {
                        CurrentProfile = _noProfile;
                        _noProfile.RecvFilterEntry.Active = data.Active;
                        _noProfile.RecvFilterEntry.Whitelist = data.Whitelist;
                    }
                );
                SendEntryViewModel = new FilterEntryViewModel


@@ 81,45 106,56 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable
                    value.SendFilterEntry,
                    (data) =>
                    {
                        CopyCurrentToNoProfile(lastProfile);
                        _noProfile.SendFilterEntry.Filters.Add(data);
                        CurrentProfile = _noProfile;
                        _noProfile.SendFilterEntry.Filters.Add(data);
                    },
                    (data) =>
                    {
                        CopyCurrentToNoProfile(lastProfile);
                        CurrentProfile = _noProfile;
                        _noProfile.SendFilterEntry.Filters.Remove(data);
                    },
                    (data) =>
                    {
                        CurrentProfile = _noProfile;
                        _noProfile.SendFilterEntry.Active = data.Active;
                        _noProfile.SendFilterEntry.Whitelist = data.Whitelist;
                    }
                );
            }
            else
            {
                RecvEntryViewModel = new FilterEntryViewModel(value.RecvFilterEntry, null, null);
                SendEntryViewModel = new FilterEntryViewModel(value.SendFilterEntry, null, null);
                RecvEntryViewModel = new FilterEntryViewModel(value.RecvFilterEntry);
                SendEntryViewModel = new FilterEntryViewModel(value.SendFilterEntry);
            }
            _currentProfile = value;

            var recvWhenAny = _currentProfile.RecvFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist")
            _currentRealProfile = value;
            _currentProfile = setCurrentProfile;

            var recvWhenAny = _currentRealProfile.RecvFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist")
                .Subscribe((e) => OnChange());

            var sendWhenAny = _currentProfile.SendFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist")
            var sendWhenAny = _currentRealProfile.SendFilterEntry.WhenAnyPropertyChanged("Active", "Whitelist")
                .Subscribe((e) => OnChange());

            var recvFilters = _currentProfile.RecvFilterEntry.Filters.ObserveCollectionChanges()
            var recvFilters = _currentRealProfile.RecvFilterEntry.Filters.ObserveCollectionChanges()
                .Subscribe((e) => OnChange());

            var sendFilters = _currentProfile.SendFilterEntry.Filters.ObserveCollectionChanges()
            var sendFilters = _currentRealProfile.SendFilterEntry.Filters.ObserveCollectionChanges()
                .Subscribe((e) => OnChange());

            _cleanUp?.Dispose();
            _cleanUp = new CompositeDisposable(recvWhenAny, sendWhenAny, recvFilters, sendFilters);
            _cleanUp = new CompositeDisposable(recvWhenAny, sendWhenAny, recvFilters, sendFilters, cleanUp);
            OnChange();
        }
    }

    private void CopyCurrentToNoProfile(FilterProfile lastProfile)
    private void CopyCurrentToNoProfile(FilterProfile? lastProfile)
    {
        if (lastProfile is null)
        {
            return;
        }

        _noProfile.RecvFilterEntry.Filters.Clear();
        _noProfile.RecvFilterEntry.Filters.AddRange(lastProfile.RecvFilterEntry.Filters);



@@ 168,8 204,8 @@ public class FilterChooseViewModel : ViewModelBase, IDisposable
    /// <returns>The created filter.</returns>
    public IFilter CreateSendRecvFilter()
    {
        IFilter recvFilter = CreateCompound(RecvEntryViewModel.Entry);
        IFilter sendFilter = CreateCompound(SendEntryViewModel.Entry);
        IFilter recvFilter = CreateCompound(_currentRealProfile.RecvFilterEntry);
        IFilter sendFilter = CreateCompound(_currentRealProfile.SendFilterEntry);

        return new SendRecvFilter(sendFilter, recvFilter);
    }

M src/PacketLogger/ViewModels/Filters/FilterConfigViewModel.cs => src/PacketLogger/ViewModels/Filters/FilterConfigViewModel.cs +2 -2
@@ 22,8 22,8 @@ public class FilterConfigViewModel : ViewModelBase
    public FilterConfigViewModel(FilterProfile filterProfile)
    {
        _filterProfile = filterProfile;
        RecvEntryViewModel = new FilterEntryViewModel(filterProfile.RecvFilterEntry, null, null);
        SendEntryViewModel = new FilterEntryViewModel(filterProfile.SendFilterEntry, null, null);
        RecvEntryViewModel = new FilterEntryViewModel(filterProfile.RecvFilterEntry);
        SendEntryViewModel = new FilterEntryViewModel(filterProfile.SendFilterEntry);
    }

    /// <summary>

M src/PacketLogger/ViewModels/Filters/FilterEntryViewModel.cs => src/PacketLogger/ViewModels/Filters/FilterEntryViewModel.cs +72 -2
@@ 6,6 6,7 @@

using System;
using System.Reactive;
using System.Reactive.Disposables;
using PacketLogger.Models.Filters;
using ReactiveUI;



@@ 14,17 15,27 @@ namespace PacketLogger.ViewModels.Filters;
/// <summary>
/// A view model for FilterEntryView.
/// </summary>
public class FilterEntryViewModel : ViewModelBase
public class FilterEntryViewModel : ViewModelBase, IDisposable
{
    private readonly Action<(bool Active, bool Whitelist)>? _whitelistActiveChanged;
    private readonly IDisposable _cleanUp;

    /// <summary>
    /// Initializes a new instance of the <see cref="FilterEntryViewModel"/> class.
    /// </summary>
    /// <param name="entry">The profile entry.</param>
    /// <param name="addNew">The action called upon adding new.</param>
    /// <param name="remove">The action called upon removing the given filter data.</param>
    /// <param name="whitelistActiveChanged">Called when whitelist or active has been changed.</param>
    public FilterEntryViewModel
        (FilterProfileEntry entry, Action<FilterCreator.FilterData>? addNew, Action<FilterCreator.FilterData>? remove)
    (
        FilterProfileEntry entry,
        Action<FilterCreator.FilterData>? addNew = default,
        Action<FilterCreator.FilterData>? remove = default,
        Action<(bool Active, bool Whitelist)>? whitelistActiveChanged = default
    )
    {
        _whitelistActiveChanged = whitelistActiveChanged;
        NewFilterType = FilterCreator.FilterType.PacketHeader;
        Entry = entry;
        RemoveCurrent = ReactiveCommand.Create


@@ 77,6 88,52 @@ public class FilterEntryViewModel : ViewModelBase
                }
            }
        );

        var whitelistChanged = Entry.WhenAnyValue(x => x.Whitelist)
            .Subscribe(_ => this.RaisePropertyChanged("Whitelist"));

        var activeChanged = Entry.WhenAnyValue(x => x.Active)
            .Subscribe(_ => this.RaisePropertyChanged("Active"));

        _cleanUp = new CompositeDisposable(whitelistChanged, activeChanged);
    }

    /// <summary>
    /// Gets or sets whether whitelist or blacklist.
    /// </summary>
    public bool Whitelist
    {
        get => Entry.Whitelist;
        set
        {
            if (_whitelistActiveChanged is not null)
            {
                _whitelistActiveChanged((Entry.Active, value));
            }
            else
            {
                Entry.Whitelist = value;
            }
        }
    }

    /// <summary>
    /// Gets or sets whether the filter entry is active.
    /// </summary>
    public bool Active
    {
        get => Entry.Active;
        set
        {
            if (_whitelistActiveChanged is not null)
            {
                _whitelistActiveChanged((value, Entry.Whitelist));
            }
            else
            {
                Entry.Active = value;
            }
        }
    }

    /// <summary>


@@ 108,4 165,17 @@ public class FilterEntryViewModel : ViewModelBase
    /// Gets the command to add new filter.
    /// </summary>
    public ReactiveCommand<Unit, Unit> AddNew { get; }

    /// <summary>
    /// Gets radio group.
    /// </summary>
    public string RadioGroup { get; } = Guid.NewGuid().ToString();

    /// <inheritdoc />
    public void Dispose()
    {
        _cleanUp.Dispose();
        RemoveCurrent.Dispose();
        AddNew.Dispose();
    }
}
\ No newline at end of file

M src/PacketLogger/ViewModels/Log/PacketLogViewModel.cs => src/PacketLogger/ViewModels/Log/PacketLogViewModel.cs +7 -7
@@ 40,13 40,13 @@ public class PacketLogViewModel : ViewModelBase, IDisposable
    public PacketLogViewModel(IPacketProvider packetProvider, FilterProfiles filterProfiles)
    {
        _filterProfiles = filterProfiles;
        FilterChoose = new FilterChooseViewModel(new FilterProfile(false));
        FilterChoose.CurrentProfile = filterProfiles.DefaultFilterEnabled
            ? filterProfiles.DefaultProfile
            : new FilterProfile(false)
            {
                Name = "No profile"
            };
        FilterChoose = new FilterChooseViewModel
        (
            filterProfiles.DefaultFilterEnabled
                ? filterProfiles.DefaultProfile
                : filterProfiles.NoProfile,
            filterProfiles.SelectableProfiles.Last()
        );
        Provider = packetProvider;

        var dynamicFilter = FilterChoose.WhenValueChanged(x => x.CurrentFilter)

M src/PacketLogger/ViewModels/MainWindowViewModel.cs => src/PacketLogger/ViewModels/MainWindowViewModel.cs +1 -1
@@ 35,7 35,7 @@ using ReactiveUI;
namespace PacketLogger.ViewModels;

/// <inheritdoc />
public class MainWindowViewModel : ViewModelBase, INotifyPropertyChanged
public class MainWindowViewModel : ViewModelBase
{
    private readonly DockFactory _factory;
    private readonly NostaleProcesses _processes;

M src/PacketLogger/Views/Filters/FilterEntryView.axaml => src/PacketLogger/Views/Filters/FilterEntryView.axaml +21 -6
@@ 3,16 3,26 @@
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:filters="clr-namespace:PacketLogger.ViewModels.Filters"
             xmlns:converters="clr-namespace:PacketLogger.Converters"
             xmlns:system="clr-namespace:System;assembly=System.Runtime"
             mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
             x:Class="PacketLogger.Views.Filters.FilterEntryView">
    <Design.DataContext>
        <filters:FilterEntryViewModel />
    </Design.DataContext>
    <UserControl.Resources>
        <converters:EnumToBooleanConverter x:Key="EnumToBooleanConverter" />
        <system:Boolean x:Key="True">True</system:Boolean>
        <system:Boolean x:Key="False">False</system:Boolean>
    </UserControl.Resources>

    <Grid ColumnDefinitions="*,*" RowDefinitions="*, 40, 40, 40">
        <DataGrid Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Items="{Binding Entry.Filters}" IsReadOnly="True"
                  SelectedItem="{Binding SelectedFilter}"
                  CanUserReorderColumns="True" CanUserSortColumns="True" CanUserResizeColumns="True">
            <DataGrid.KeyBindings>
                <KeyBinding Gesture="Delete" Command="{Binding RemoveCurrent}" />
            </DataGrid.KeyBindings>
            <DataGrid.Styles>
                <Style Selector="DataGridColumnHeader">
                    <Setter Property="MinHeight" Value="24" />


@@ 23,16 33,21 @@
                <DataGridTextColumn Header="Value" Binding="{Binding Value}" Width="*" MinWidth="100" />
            </DataGrid.Columns>
        </DataGrid>
        
        <CheckBox Grid.Row="1" Grid.Column="0" Content="Filter active" IsChecked="{Binding Entry.Active}" />

        <CheckBox Grid.Row="1" Grid.Column="0" Content="Filter active" IsChecked="{Binding Active}" />

        <Grid Grid.Row="1" Grid.Column="1" ColumnDefinitions="*,*">
            <RadioButton Grid.Column="0" Content="Wl" GroupName="WlBl"></RadioButton>
            <RadioButton Grid.Column="1" Content="Bl" GroupName="WlBl" IsChecked="{Binding !Entry.Whitelist}"></RadioButton>
            <RadioButton Grid.Column="0" Content="Wl" GroupName="{Binding RadioGroup}"
                         IsChecked="{Binding Whitelist, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={StaticResource True}}" />
            <RadioButton Grid.Column="1" Content="Bl" GroupName="{Binding RadioGroup}"
                         IsChecked="{Binding Whitelist, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={StaticResource False}}" />
        </Grid>

        <TextBox VerticalAlignment="Center" Margin="0, 0, 5, 0" Height="30" Grid.Row="2" Grid.Column="0"
                 Text="{Binding NewFilter}">
            <TextBox.KeyBindings>
                <KeyBinding Gesture="Enter" Command="{Binding AddNew}" />
            </TextBox.KeyBindings>
        </TextBox>
        <ComboBox x:Name="FilterType" VerticalAlignment="Center" HorizontalAlignment="Stretch" Margin="5, 0, 0, 0"
                  Height="32" Grid.Row="2"


@@ 41,6 56,6 @@
        <Button HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="0, 0, 5, 0" Grid.Row="3"
                Grid.Column="0" Content="Remove" Command="{Binding RemoveCurrent}" />
        <Button HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" Margin="5, 0, 0,0" Grid.Row="3"
                Grid.Column="1" Content="Add" Command="{Binding AddNew}" IsDefault="True" />
                Grid.Column="1" Content="Add" Command="{Binding AddNew}" />
    </Grid>
</UserControl>
</UserControl>
\ No newline at end of file

Do not follow this link