mirror of
https://github.com/4sval/FModel.git
synced 2026-08-22 01:14:27 -05:00
endpoint configuration template
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -141,3 +141,9 @@ public enum EIconStyle
|
||||
// [Description("Community")]
|
||||
// CommunityMade
|
||||
}
|
||||
|
||||
public enum EEndpointType
|
||||
{
|
||||
Aes,
|
||||
Mapping
|
||||
}
|
||||
|
||||
33
FModel/Framework/FEndpoint.cs
Normal file
33
FModel/Framework/FEndpoint.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
@@ -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>()},
|
||||
|
||||
@@ -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)
|
||||
|
||||
47
FModel/ViewModels/ApiEndpoints/DynamicApiEndpoint.cs
Normal file
47
FModel/ViewModels/ApiEndpoints/DynamicApiEndpoint.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
}
|
||||
32
FModel/Views/Resources/Converters/EndpointToTypeConverter.cs
Normal file
32
FModel/Views/Resources/Converters/EndpointToTypeConverter.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user