endpoint configuration template

This commit is contained in:
4sval
2022-08-06 02:38:28 +02:00
parent 746292892d
commit 516fa33f93
15 changed files with 349 additions and 193 deletions

View File

@@ -212,12 +212,12 @@ public class BasePandaIcon : UCreator
return;
var x = 450f;
var y = Height / 2 - DisplayNamePaint.TextSize / 4;
while (DisplayNamePaint.MeasureText(DisplayName) > Width - x)
while (DisplayNamePaint.MeasureText(DisplayName) > Width - x / 1.25)
{
DisplayNamePaint.TextSize -= 1;
}
var y = Height / 2 - DisplayNamePaint.TextSize / 4;
foreach (var a in DisplayName.Select(character => character.ToString()))
{
c.DrawText(a, x, y, DisplayNamePaint);

View File

@@ -141,3 +141,9 @@ public enum EIconStyle
// [Description("Community")]
// CommunityMade
}
public enum EEndpointType
{
Aes,
Mapping
}

View File

@@ -0,0 +1,33 @@
namespace FModel.Framework;
public class FEndpoint : ViewModel
{
private string _url;
public string Url
{
get => _url;
set => SetProperty(ref _url, value);
}
private bool _overwrite;
public bool Overwrite
{
get => _overwrite;
set => SetProperty(ref _overwrite, value);
}
private string _path;
public string Path
{
get => _path;
set => SetProperty(ref _path, value);
}
public bool IsEnabled => !string.IsNullOrWhiteSpace(_url); // change this later
public FEndpoint() {}
public FEndpoint(string url)
{
Url = url;
}
}

View File

@@ -39,6 +39,16 @@ namespace FModel.Settings
if (File.Exists(FilePath)) File.Delete(FilePath);
}
public static bool TryGetGameCustomEndpoint(FGame game, EEndpointType type, out FEndpoint endpoint)
{
endpoint = null;
if (!Default.CustomEndpoints.TryGetValue(game, out var endpoints))
return false;
endpoint = endpoints[(int) type];
return endpoint.IsEnabled;
}
private bool _showChangelog = true;
public bool ShowChangelog
{
@@ -95,20 +105,6 @@ namespace FModel.Settings
set => SetProperty(ref _gameDirectory, value);
}
private bool _overwriteMapping;
public bool OverwriteMapping
{
get => _overwriteMapping;
set => SetProperty(ref _overwriteMapping, value);
}
private string _mappingFilePath;
public string MappingFilePath
{
get => _mappingFilePath;
set => SetProperty(ref _mappingFilePath, value);
}
private int _lastOpenedSettingTab;
public int LastOpenedSettingTab
{
@@ -382,6 +378,41 @@ namespace FModel.Settings
set => SetProperty(ref _overridedOptions, value);
}
private IDictionary<FGame, FEndpoint[]> _customEndpoints = new Dictionary<FGame, FEndpoint[]>
{
{FGame.Unknown, new FEndpoint[]{new (), new ()}},
{
FGame.FortniteGame, new []
{
new FEndpoint("https://fortnitecentral.gmatrixgames.ga/api/v1/aes"),
new FEndpoint("https://fortnitecentral.gmatrixgames.ga/api/v1/mappings")
}
},
{FGame.ShooterGame, new FEndpoint[]{new (), new ()}},
{FGame.DeadByDaylight, new FEndpoint[]{new (), new ()}},
{FGame.OakGame, new FEndpoint[]{new (), new ()}},
{FGame.Dungeons, new FEndpoint[]{new (), new ()}},
{FGame.WorldExplorers, new FEndpoint[]{new (), new ()}},
{FGame.g3, new FEndpoint[]{new (), new ()}},
{FGame.StateOfDecay2, new FEndpoint[]{new (), new ()}},
{FGame.Prospect, new FEndpoint[]{new (), new ()}},
{FGame.Indiana, new FEndpoint[]{new (), new ()}},
{FGame.RogueCompany, new FEndpoint[]{new (), new ()}},
{FGame.SwGame, new FEndpoint[]{new (), new ()}},
{FGame.Platform, new FEndpoint[]{new (), new ()}},
{FGame.BendGame, new FEndpoint[]{new (), new ()}},
{FGame.TslGame, new FEndpoint[]{new (), new ()}},
{FGame.PortalWars, new FEndpoint[]{new (), new ()}},
{FGame.Gameface, new FEndpoint[]{new (), new ()}},
{FGame.Athena, new FEndpoint[]{new (), new ()}},
{FGame.PandaGame, new FEndpoint[]{new (), new ()}}
};
public IDictionary<FGame, FEndpoint[]> CustomEndpoints
{
get => _customEndpoints;
set => SetProperty(ref _customEndpoints, value);
}
private IDictionary<FGame, IList<CustomDirectory>> _customDirectories = new Dictionary<FGame, IList<CustomDirectory>>
{
{FGame.Unknown, new List<CustomDirectory>()},

View File

@@ -22,7 +22,8 @@ public class ApiEndpointViewModel
public ValorantApiEndpoint ValorantApi { get; }
public FortniteCentralApiEndpoint CentralApi { get; }
public EpicApiEndpoint EpicApi { get; }
public FModelApi FModelApi { get; }
public FModelApiEndpoint FModelApi { get; }
public DynamicApiEndpoint DynamicApi { get; }
public ApiEndpointViewModel()
{
@@ -30,7 +31,8 @@ public class ApiEndpointViewModel
ValorantApi = new ValorantApiEndpoint(_client);
CentralApi = new FortniteCentralApiEndpoint(_client);
EpicApi = new EpicApiEndpoint(_client);
FModelApi = new FModelApi(_client);
FModelApi = new FModelApiEndpoint(_client);
DynamicApi = new DynamicApiEndpoint(_client);
}
public async Task DownloadFileAsync(string fileLink, string installationPath)

View File

@@ -0,0 +1,47 @@
using System.Threading;
using System.Threading.Tasks;
using FModel.Framework;
using FModel.ViewModels.ApiEndpoints.Models;
using RestSharp;
using Serilog;
namespace FModel.ViewModels.ApiEndpoints;
public class DynamicApiEndpoint : AbstractApiProvider
{
public DynamicApiEndpoint(RestClient client) : base(client)
{
}
public async Task<AesResponse> GetAesKeysAsync(CancellationToken token, string url)
{
var request = new FRestRequest(url)
{
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
};
var response = await _client.ExecuteAsync<AesResponse>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public AesResponse GetAesKeys(CancellationToken token, string url)
{
return GetAesKeysAsync(token, url).GetAwaiter().GetResult();
}
public async Task<MappingsResponse[]> GetMappingsAsync(CancellationToken token, string url)
{
var request = new FRestRequest(url)
{
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
};
var response = await _client.ExecuteAsync<MappingsResponse[]>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public MappingsResponse[] GetMappings(CancellationToken token, string url)
{
return GetMappingsAsync(token, url).GetAwaiter().GetResult();
}
}

View File

@@ -20,7 +20,7 @@ using MessageBoxResult = AdonisUI.Controls.MessageBoxResult;
namespace FModel.ViewModels.ApiEndpoints;
public class FModelApi : AbstractApiProvider
public class FModelApiEndpoint : AbstractApiProvider
{
private News _news;
private Info _infos;
@@ -29,7 +29,7 @@ public class FModelApi : AbstractApiProvider
private readonly IDictionary<string, CommunityDesign> _communityDesigns = new Dictionary<string, CommunityDesign>();
private ApplicationViewModel _applicationView => ApplicationService.ApplicationView;
public FModelApi(RestClient client) : base(client)
public FModelApiEndpoint(RestClient client) : base(client)
{
}

View File

@@ -2,7 +2,6 @@
using System.Threading;
using System.Threading.Tasks;
using FModel.Framework;
using FModel.ViewModels.ApiEndpoints.Models;
using RestSharp;
using Serilog;
@@ -14,38 +13,6 @@ public class FortniteCentralApiEndpoint : AbstractApiProvider
{
}
public async Task<AesResponse> GetAesKeysAsync(CancellationToken token)
{
var request = new FRestRequest("https://fortnitecentral.gmatrixgames.ga/api/v1/aes")
{
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
};
var response = await _client.ExecuteAsync<AesResponse>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public AesResponse GetAesKeys(CancellationToken token)
{
return GetAesKeysAsync(token).GetAwaiter().GetResult();
}
public async Task<MappingsResponse[]> GetMappingsAsync(CancellationToken token)
{
var request = new FRestRequest("https://fortnitecentral.gmatrixgames.ga/api/v1/mappings")
{
OnBeforeDeserialization = resp => { resp.ContentType = "application/json; charset=utf-8"; }
};
var response = await _client.ExecuteAsync<MappingsResponse[]>(request, token).ConfigureAwait(false);
Log.Information("[{Method}] [{Status}({StatusCode})] '{Resource}'", request.Method, response.StatusDescription, (int) response.StatusCode, response.ResponseUri?.OriginalString);
return response.Data;
}
public MappingsResponse[] GetMappings(CancellationToken token)
{
return GetMappingsAsync(token).GetAwaiter().GetResult();
}
public async Task<Dictionary<string, Dictionary<string, string>>> GetHotfixesAsync(CancellationToken token, string language = "en")
{
var request = new FRestRequest("https://fortnitecentral.gmatrixgames.ga/api/v1/hotfixes")

View File

@@ -293,16 +293,18 @@ public class CUE4ParseViewModel : ViewModel
public async Task RefreshAes()
{
if (Game == FGame.FortniteGame) // game directory dependent, we don't have the provider game name yet since we don't have aes keys
{
await _threadWorkerView.Begin(cancellationToken =>
{
var aes = _apiEndpointView.CentralApi.GetAesKeys(cancellationToken);
if (aes?.MainKey == null && aes?.DynamicKeys == null && aes?.Version == null) return;
// game directory dependent, we don't have the provider game name yet since we don't have aes keys
// except when this comes from the AES Manager
if (!UserSettings.TryGetGameCustomEndpoint(Game, EEndpointType.Aes, out var endpoint))
return;
UserSettings.Default.AesKeys[Game] = aes;
});
}
await _threadWorkerView.Begin(cancellationToken =>
{
var aes = _apiEndpointView.DynamicApi.GetAesKeys(cancellationToken, endpoint.Url);
if (aes?.MainKey == null && aes?.DynamicKeys == null) return;
UserSettings.Default.AesKeys[Game] = aes;
});
}
public async Task InitInformation()
@@ -321,20 +323,21 @@ public class CUE4ParseViewModel : ViewModel
public async Task InitBenMappings()
{
if (Game != FGame.FortniteGame) return;
if (!UserSettings.TryGetGameCustomEndpoint(Game, EEndpointType.Mapping, out var endpoint))
return;
await _threadWorkerView.Begin(cancellationToken =>
{
if (UserSettings.Default.OverwriteMapping && File.Exists(UserSettings.Default.MappingFilePath))
if (endpoint.Overwrite && File.Exists(endpoint.Path))
{
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(UserSettings.Default.MappingFilePath);
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(endpoint.Path);
FLogger.AppendInformation();
FLogger.AppendText($"Mappings pulled from '{UserSettings.Default.MappingFilePath.SubstringAfterLast("\\")}'", Constants.WHITE, true);
FLogger.AppendText($"Mappings pulled from '{endpoint.Path.SubstringAfterLast("\\")}'", Constants.WHITE, true);
}
else
{
var mappingsFolder = Path.Combine(UserSettings.Default.OutputDirectory, ".data");
var mappings = _apiEndpointView.CentralApi.GetMappings(cancellationToken);
var mappings = _apiEndpointView.DynamicApi.GetMappings(cancellationToken, endpoint.Url);
if (mappings is { Length: > 0 })
{
foreach (var mapping in mappings)

View File

@@ -96,6 +96,13 @@ public class SettingsViewModel : ViewModel
set => SetProperty(ref _selectedCompressedAudio, value);
}
private string _currentMappingFile;
public string CurrentMappingFile // only used so that it updates the UI
{
get => _currentMappingFile;
set => SetProperty(ref _currentMappingFile, value);
}
private EIconStyle _selectedCosmeticStyle;
public EIconStyle SelectedCosmeticStyle
{
@@ -191,6 +198,9 @@ public class SettingsViewModel : ViewModel
_optionsSnapshot = UserSettings.Default.OverridedOptions[_game];
}
if (UserSettings.TryGetGameCustomEndpoint(_game, EEndpointType.Mapping, out var endpoint))
CurrentMappingFile = endpoint.Path;
_assetLanguageSnapshot = UserSettings.Default.AssetLanguage;
_compressedAudioSnapshot = UserSettings.Default.CompressedAudioMode;
_cosmeticStyleSnapshot = UserSettings.Default.CosmeticStyle;

View File

@@ -81,16 +81,13 @@
HorizontalAlignment="Right" VerticalAlignment="Bottom" Content="OK" Click="OnClick" />
<Button Grid.Column="2" MinWidth="78" Margin="0 0 12 0" IsDefault="False" IsCancel="False"
HorizontalAlignment="Right" VerticalAlignment="Bottom" Content="Refresh" Click="OnRefreshAes">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
<Button.Visibility>
<!-- if aes custom endpoint is enabled, make this visible -->
<MultiBinding Converter="{x:Static converters:EndpointToTypeConverter.Instance}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.AesManager}}" Path="DataContext" />
<Binding Source="{x:Static local:EEndpointType.Aes}" />
</MultiBinding>
</Button.Visibility>
</Button>
</Grid>
</Border>

View File

@@ -0,0 +1,52 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using FModel.Framework;
using FModel.Settings;
using FModel.ViewModels;
namespace FModel.Views.Resources.Converters;
public class EndpointOverwriteToBoolConverter : IMultiValueConverter
{
public static readonly EndpointOverwriteToBoolConverter Instance = new();
private ApplicationViewModel _vm;
private EEndpointType _type;
private FEndpoint _endpoint;
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
_vm = values[0] as ApplicationViewModel;
_type = values[1] as EEndpointType? ?? EEndpointType.Mapping;
if (_vm == null || !UserSettings.TryGetGameCustomEndpoint(_vm.CUE4Parse.Game, _type, out _endpoint))
return default;
return targetType switch
{
not null when targetType == typeof(bool?) => _endpoint.Overwrite, // IsChecked
not null when targetType == typeof(string) => _endpoint.Path,
not null when targetType == typeof(Visibility) => _endpoint.Overwrite ? Visibility.Visible : Visibility.Collapsed,
_ => throw new NotImplementedException()
};
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
var t = value.GetType();
switch (t)
{
case not null when t == typeof(bool):
_endpoint.Overwrite = (bool)value;
break;
case not null when t == typeof(string):
_endpoint.Path = (string)value;
break;
default:
throw new NotImplementedException();
}
return new object[] { _vm, _type };
}
}

View File

@@ -0,0 +1,32 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
using FModel.Settings;
using FModel.ViewModels;
namespace FModel.Views.Resources.Converters;
public class EndpointToTypeConverter : IMultiValueConverter
{
public static readonly EndpointToTypeConverter Instance = new();
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values[0] is not ApplicationViewModel viewModel ||
values[1] is not EEndpointType type)
return false;
var isEnabled = UserSettings.TryGetGameCustomEndpoint(viewModel.CUE4Parse.Game, type, out _);
return targetType switch
{
not null when targetType == typeof(Visibility) => isEnabled ? Visibility.Visible : Visibility.Collapsed,
_ => throw new NotImplementedException()
};
}
public object[] ConvertBack(object value, Type[] targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}

View File

@@ -41,6 +41,7 @@
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
@@ -130,17 +131,6 @@
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" SelectionChanged="OnSelectionChanged" Margin="0 0 0 5">
</ComboBox>
<TextBlock Grid.Row="10" Grid.Column="0" Text="Texture Platform *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the game's platform to ensure texture compatibility" />
<ComboBox Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.Platforms}" SelectedItem="{Binding SettingsView.SelectedUePlatform, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" IsEnabled="{Binding SettingsView.EnableElements}"
Margin="0 0 0 5">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={x:Static converters:EnumToStringConverter.Instance}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="8" Grid.Column="0" Text="UE Versions *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the UE version to use when parsing packages" />
<ComboBox Grid.Row="8" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.UeGames}" SelectedItem="{Binding SettingsView.SelectedUeGame, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" IsEnabled="{Binding SettingsView.EnableElements}"
@@ -164,6 +154,17 @@
<Button Grid.Column="2" Content="Options" Click="OpenOptions" />
</Grid>
<TextBlock Grid.Row="10" Grid.Column="0" Text="Texture Platform *" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Override the game's platform to ensure texture compatibility" />
<ComboBox Grid.Row="10" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.Platforms}" SelectedItem="{Binding SettingsView.SelectedUePlatform, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" IsEnabled="{Binding SettingsView.EnableElements}"
Margin="0 0 0 5">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={x:Static converters:EnumToStringConverter.Instance}}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="11" Grid.Column="0" Text="Compressed Audio" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="What to do when encountering a compressed audio file" />
<ComboBox Grid.Row="11" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.CompressedAudios}" SelectedItem="{Binding SettingsView.SelectedCompressedAudio, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
@@ -174,31 +175,47 @@
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="12" Grid.Column="0" Text="AES Reload at Launch" VerticalAlignment="Center" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock Grid.Row="12" Grid.Column="0" Text="Endpoint Configuration" VerticalAlignment="Center" Margin="0 0 0 5" />
<Grid Grid.Row="12" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="AES" />
<Button Grid.Column="2" Content="Mapping">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="IsEnabled" Value="False"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="IsEnabled" Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
</Grid>
<TextBlock Grid.Row="13" Grid.Column="0" Text="AES Reload at Launch" VerticalAlignment="Center" Margin="0 0 0 5">
<TextBlock.Visibility>
<MultiBinding Converter="{x:Static converters:EndpointToTypeConverter.Instance}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}" Path="DataContext" />
<Binding Source="{x:Static local:EEndpointType.Aes}" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<ComboBox Grid.Row="12" Grid.Column="2" Grid.ColumnSpan="5" ItemsSource="{Binding SettingsView.AesReloads}" SelectedItem="{Binding SettingsView.SelectedAesReload, Mode=TwoWay}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" Margin="0 0 0 5">
<ComboBox.Style>
<Style TargetType="ComboBox" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</ComboBox.Style>
<ComboBox Grid.Row="13" Grid.Column="2" Grid.ColumnSpan="5" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}"
ItemsSource="{Binding SettingsView.AesReloads}" SelectedItem="{Binding SettingsView.SelectedAesReload, Mode=TwoWay}">
<ComboBox.Visibility>
<MultiBinding Converter="{x:Static converters:EndpointToTypeConverter.Instance}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}" Path="DataContext" />
<Binding Source="{x:Static local:EEndpointType.Aes}" />
</MultiBinding>
</ComboBox.Visibility>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={x:Static converters:EnumToStringConverter.Instance}}" />
@@ -206,90 +223,46 @@
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Row="13" Grid.Column="0" Text="Keep Directory Structure" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Auto-save packages following their game directory" />
<CheckBox Grid.Row="13" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
<TextBlock Grid.Row="14" Grid.Column="0" Text="Keep Directory Structure" VerticalAlignment="Center" Margin="0 0 0 5" ToolTip="Auto-save packages following their game directory" />
<CheckBox Grid.Row="14" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding KeepDirectoryStructure, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"/>
<TextBlock Grid.Row="14" Grid.Column="0" Text="Overwrite Mapping File" VerticalAlignment="Center" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock Grid.Row="15" Grid.Column="0" Text="Overwrite Mapping File" VerticalAlignment="Center" Margin="0 0 0 5">
<TextBlock.Visibility>
<!-- if mapping custom endpoint is enabled, make this visible -->
<MultiBinding Converter="{x:Static converters:EndpointToTypeConverter.Instance}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}" Path="DataContext" />
<Binding Source="{x:Static local:EEndpointType.Mapping}" />
</MultiBinding>
</TextBlock.Visibility>
</TextBlock>
<CheckBox Grid.Row="14" Grid.Column="2" Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}"
IsChecked="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay}" Margin="0 5 0 10"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<CheckBox.Style>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</CheckBox.Style>
<CheckBox x:Name="OverwriteCkBox" Grid.Row="15" Grid.Column="2" Margin="0 5 0 10"
Content="{Binding IsChecked, RelativeSource={RelativeSource Self}, Converter={x:Static converters:BoolToToggleConverter.Instance}}">
<CheckBox.Visibility>
<!-- if mapping custom endpoint is enabled, make this visible -->
<MultiBinding Converter="{x:Static converters:EndpointToTypeConverter.Instance}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}" Path="DataContext" />
<Binding Source="{x:Static local:EEndpointType.Mapping}" />
</MultiBinding>
</CheckBox.Visibility>
<CheckBox.IsChecked>
<!-- if mapping custom endpoint is enabled, this gets/sets the value of Overwrite -->
<MultiBinding Converter="{x:Static converters:EndpointOverwriteToBoolConverter.Instance}">
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}" Path="DataContext" />
<Binding Path="." Source="{x:Static local:EEndpointType.Mapping}" /> <!-- TwoWay binding needs a Path -->
</MultiBinding>
</CheckBox.IsChecked>
</CheckBox>
<TextBlock Grid.Row="15" Grid.Column="0" Text="Mapping File Path" VerticalAlignment="Center" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}" />
<Condition Binding="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
<TextBlock Grid.Row="16" Grid.Column="0" Text="Mapping File Path" VerticalAlignment="Center" Margin="0 0 0 5"
Visibility="{Binding IsChecked, ElementName=OverwriteCkBox, Converter={StaticResource BoolToVisibilityConverter}}">
</TextBlock>
<TextBox Grid.Row="15" Grid.Column="2" Grid.ColumnSpan="3" Margin="0 0 0 5"
Text="{Binding MappingFilePath, Source={x:Static local:Settings.UserSettings.Default}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<TextBox.Style>
<Style TargetType="TextBox" BasedOn="{StaticResource {x:Type TextBox}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}" />
<Condition Binding="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</TextBox.Style>
</TextBox>
<Button Grid.Row="15" Grid.Column="6" Content="..." HorizontalAlignment="Right" Click="OnBrowseMappings" Margin="0 0 0 5"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}">
<Button.Style>
<Style TargetType="Button" BasedOn="{StaticResource {x:Type Button}}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding CUE4Parse.Game}" Value="{x:Static local:FGame.FortniteGame}" />
<Condition Binding="{Binding OverwriteMapping, Source={x:Static local:Settings.UserSettings.Default}}" Value="True" />
</MultiDataTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<TextBox Grid.Row="16" Grid.Column="2" Grid.ColumnSpan="3" Margin="0 0 0 5"
IsReadOnly="True" Text="{Binding SettingsView.CurrentMappingFile, Mode=TwoWay}"
Visibility="{Binding IsChecked, ElementName=OverwriteCkBox, Converter={StaticResource BoolToVisibilityConverter}}"
DataContext="{Binding DataContext, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:Views.SettingsView}}}" />
<Button Grid.Row="16" Grid.Column="6" Content="..." HorizontalAlignment="Right" Click="OnBrowseMappings" Margin="0 0 0 5"
Visibility="{Binding IsChecked, ElementName=OverwriteCkBox, Converter={StaticResource BoolToVisibilityConverter}}" />
</Grid>
</DataTemplate>
<DataTemplate x:Key="CreatorTemplate">

View File

@@ -99,8 +99,11 @@ public partial class SettingsView
Filter = "USMAP Files (*.usmap)|*.usmap|All Files (*.*)|*.*"
};
if (!openFileDialog.ShowDialog().GetValueOrDefault()) return;
UserSettings.Default.MappingFilePath = openFileDialog.FileName;
if (!openFileDialog.ShowDialog().GetValueOrDefault() ||
!UserSettings.TryGetGameCustomEndpoint(_applicationView.CUE4Parse.Game, EEndpointType.Mapping, out var endpoint))
return;
endpoint.Path = _applicationView.SettingsView.CurrentMappingFile = openFileDialog.FileName;
await _applicationView.CUE4Parse.InitBenMappings();
}
@@ -167,4 +170,4 @@ public partial class SettingsView
_applicationView.SettingsView.SelectedOptions = dictionary.Options;
}
}
}