FModel 3.1

This commit is contained in:
iAmAsval 2020-05-14 17:12:20 +02:00
parent 53443b0a31
commit 9b1385fdf1
650 changed files with 28477 additions and 34023 deletions

View File

@ -1,25 +1,29 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.452
VisualStudioVersion = 16.0.29806.167
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FModel", "FModel\FModel.csproj", "{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FModel", "FModel\FModel.csproj", "{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|x64 = Debug|x64
Release|Any CPU = Release|Any CPU
Release|x64 = Release|x64
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Debug|Any CPU.Build.0 = Debug|Any CPU
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Release|Any CPU.ActiveCfg = Release|Any CPU
{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}.Release|Any CPU.Build.0 = Release|Any CPU
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Debug|Any CPU.ActiveCfg = Debug|x64
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Debug|x64.ActiveCfg = Debug|x64
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Debug|x64.Build.0 = Debug|x64
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Release|Any CPU.ActiveCfg = Release|x64
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Release|x64.ActiveCfg = Release|x64
{A42F8737-D056-4FA5-BEB5-AA96E1639F8A}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {42CA5618-EB78-4DDF-95A4-BD589CC52791}
SolutionGuid = {FE6EA91D-BBB8-4FBC-875C-25AD92EDB519}
EndGlobalSection
EndGlobal

View File

@ -1,213 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<configSections>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="FModel.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
</startup>
<userSettings>
<FModel.Properties.Settings>
<setting name="FPak_Path" serializeAs="String">
<value />
</setting>
<setting name="FOutput_Path" serializeAs="String">
<value />
</setting>
<setting name="FPak_MainAES" serializeAs="String">
<value />
</setting>
<setting name="FRarity_Design" serializeAs="String">
<value>Default</value>
</setting>
<setting name="FLanguage" serializeAs="String">
<value>English</value>
</setting>
<setting name="FIsFeatured" serializeAs="String">
<value>False</value>
</setting>
<setting name="FUseWatermark" serializeAs="String">
<value>False</value>
</setting>
<setting name="FWatermarkFilePath" serializeAs="String">
<value />
</setting>
<setting name="FWatermarkOpacity" serializeAs="String">
<value>0</value>
</setting>
<setting name="FWatermarkScale" serializeAs="String">
<value>0</value>
</setting>
<setting name="FWatermarkXPos" serializeAs="String">
<value>3</value>
</setting>
<setting name="FWatermarkYPos" serializeAs="String">
<value>3</value>
</setting>
<setting name="FChallengeWatermark" serializeAs="String">
<value>{BundleName} - {Date}</value>
</setting>
<setting name="FUseChallengeWatermark" serializeAs="String">
<value>False</value>
</setting>
<setting name="FBannerFilePath" serializeAs="String">
<value />
</setting>
<setting name="FBannerOpacity" serializeAs="String">
<value>0</value>
</setting>
<setting name="FDiffFileSize" serializeAs="String">
<value>False</value>
</setting>
<setting name="HeaderVisibility" serializeAs="String">
<value>True</value>
</setting>
<setting name="ReadOnly" serializeAs="String">
<value>False</value>
</setting>
<setting name="StatusBarVisibility" serializeAs="String">
<value>True</value>
</setting>
<setting name="FPrimaryColor" serializeAs="String">
<value>21:32:43</value>
</setting>
<setting name="FSecondaryColor" serializeAs="String">
<value>29:161:242</value>
</setting>
<setting name="FUpdateSettings" serializeAs="String">
<value>True</value>
</setting>
<setting name="ReloadAES" serializeAs="String">
<value>True</value>
</setting>
<setting name="FOpenSounds" serializeAs="String">
<value>True</value>
</setting>
<setting name="FAutoExtractRaw" serializeAs="String">
<value>False</value>
</setting>
<setting name="FAutoSaveJson" serializeAs="String">
<value>False</value>
</setting>
<setting name="FAutoSaveImg" serializeAs="String">
<value>False</value>
</setting>
<setting name="FUM_AssetsType" serializeAs="String">
<value>{
"[BR] Cosmetics": {
"Path": "/FortniteGame/Content/Athena/Items/Cosmetics/",
"isChecked": "True"
},
"[BR] Cosmetics Variants": {
"Path": "/FortniteGame/Content/Athena/Items/CosmeticVariantTokens/",
"isChecked": "True"
},
"[BR] Banners": {
"Path": "/FortniteGame/Content/Athena/Items/BannerToken/",
"isChecked": "True"
},
"[BR] Challenges": {
"Path": "/FortniteGame/Content/Athena/Items/ChallengeBundles/",
"isChecked": "True"
},
"[BR] Consumables": {
"Path": "/FortniteGame/Content/Athena/Items/Consumables/",
"isChecked": "False"
},
"[BR] Traps": {
"Path": "/FortniteGame/Content/Athena/Items/Traps/",
"isChecked": "False"
},
"[BR] Weapons": {
"Path": "/FortniteGame/Content/Athena/Items/Weapons/",
"isChecked": "True"
},
"[BR] 2D Assets": {
"Path": "/FortniteGame/Content/2dAssets/",
"isChecked": "True"
},
"[BR] Featured Images": {
"Path": "/FortniteGame/Content/UI/Foundation/Textures/BattleRoyale/FeaturedItems/",
"isChecked": "False"
},
"[STW] Heroes": {
"Path": "/FortniteGame/Content/Heroes/",
"isChecked": "False"
},
"[STW] Defenders": {
"Path": "/FortniteGame/Content/Items/Defenders/",
"isChecked": "False"
},
"[STW] Schematics": {
"Path": "/FortniteGame/Content/Items/Schematics/",
"isChecked": "False"
},
"[STW] Traps": {
"Path": "/FortniteGame/Content/Items/Traps/",
"isChecked": "False"
},
"[STW] Weapons": {
"Path": "/FortniteGame/Content/Items/Weapons/",
"isChecked": "False"
},
"[STW] Ingredients": {
"Path": "/FortniteGame/Content/Items/Ingredients/",
"isChecked": "False"
},
"[STW] Persistent Resources": {
"Path": "/FortniteGame/Content/Items/PersistentResources/",
"isChecked": "False"
},
"[STW] CardPacks": {
"Path": "/FortniteGame/Content/Items/CardPacks/",
"isChecked": "False"
},
"Tokens": {
"Path": "/FortniteGame/Content/Items/Tokens/",
"isChecked": "False"
},
"Icons": {
"Path": "/FortniteGame/Content/UI/Foundation/Textures/Icons/",
"isChecked": "False"
},
"Additional Banners": {
"Path": "/FortniteGame/Content/UI/Foundation/Textures/Banner/",
"isChecked": "False"
},
"Additional Loading Screens": {
"Path": "/FortniteGame/Content/UI/Foundation/Textures/LoadingScreens/",
"isChecked": "False"
}
}</value>
</setting>
<setting name="ELauncherToken" serializeAs="String">
<value />
</setting>
<setting name="ELauncherExpiration" serializeAs="String">
<value>0</value>
</setting>
</FModel.Properties.Settings>
</userSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="SkiaSharp" publicKeyToken="0738eb9f132ed756" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.68.0.0" newVersion="1.68.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Numerics.Vectors" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.5.0" newVersion="4.1.5.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.6.0" newVersion="4.0.6.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,17 +1,13 @@
<Application x:Class="FModel.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:FModel"
StartupUri="FModel_Main.xaml"
ShutdownMode="OnMainWindowClose"
StartupUri="MainWindow.xaml" ShutdownMode="OnMainWindowClose"
DispatcherUnhandledException="OnDispatcherUnhandledException">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes\Styles.xaml" />
<ResourceDictionary Source="Forms/HexViewer/BrushesDictionary.xaml" />
<ResourceDictionary Source="Forms/HexViewer/MiscelanousDictionary.xaml" />
<ResourceDictionary Source="Forms/HexViewer/ToolTipDictionary.xaml" />
<ResourceDictionary Source="pack://application:,,,/Theme/Style.xaml" />
<ResourceDictionary Source="pack://application:,,,/ToastNotifications.Messages;component/Themes/Default.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>

View File

@ -1,20 +1,80 @@
using FModel.Methods.MessageBox;
using FModel.Methods.Utilities;
using FModel.Discord;
using FModel.Logger;
using FModel.Utils;
using FModel.ViewModels.StatusBar;
using FModel.Windows.DarkMessageBox;
using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows;
using System.Windows.Threading;
namespace FModel
{
/// <summary>
/// Logique d'interaction pour App.xaml
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
void OnDispatcherUnhandledException(object sender, System.Windows.Threading.DispatcherUnhandledExceptionEventArgs e)
internal static Stopwatch StartTimer { get; private set; }
static bool framerateSet = false;
protected override void OnStartup(StartupEventArgs e)
{
string errorMessage = string.Format("An unhandled exception occurred: {0}", e.Exception.Message);
StartTimer = Stopwatch.StartNew();
//Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("en-US");
DebugHelper.Init(LogsFilePath);
DebugHelper.WriteLine("{0} {1}", "[FModel]", "");
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Version]", Assembly.GetExecutingAssembly().GetName().Version.ToString());
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Build]", Globals.Build);
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[OS]", Logger.Logger.GetOperatingSystemProductName(true));
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Runtime]", RuntimeInformation.FrameworkDescription);
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Culture]", Thread.CurrentThread.CurrentUICulture);
StatusBarVm.statusBarViewModel.Set(FModel.Properties.Resources.Initializing, FModel.Properties.Resources.Loading);
DiscordIntegration.StartClient();
base.OnStartup(e);
}
public static string LogsFilePath
{
get
{
string filename = string.Format("FModel-Log-{0:yyyy-MM-dd}.txt", DateTime.Now);
// Copy user settings from previous application version if necessary
if (FModel.Properties.Settings.Default.UpdateSettings)
FModel.Properties.Settings.Default.Upgrade();
Folders.LoadFolders();
return Path.Combine(FModel.Properties.Settings.Default.OutputPath + "\\Logs", filename);
}
}
private void OnDispatcherUnhandledException(object sender, DispatcherUnhandledExceptionEventArgs e)
{
string errorMessage = string.Format(FModel.Properties.Resources.UnhandledExceptionOccured, e.Exception.Message);
DebugHelper.WriteException(e.Exception, "thrown in App.xaml.cs by OnDispatcherUnhandledException");
DarkMessageBox.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
DarkMessageBoxHelper.Show(errorMessage, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
e.Handled = true;
}
internal static void SetFramerate()
{
if (!framerateSet)
{
System.Windows.Media.Animation.Timeline.DesiredFrameRateProperty.OverrideMetadata(
typeof(System.Windows.Media.Animation.Timeline),
new FrameworkPropertyMetadata { DefaultValue = 10 });
framerateSet = true;
}
}
}
}

10
FModel/AssemblyInfo.cs Normal file
View File

@ -0,0 +1,10 @@
using System.Windows;
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]

View File

@ -1,12 +0,0 @@
using System.Windows.Input;
namespace FModel.Commands
{
static class FModel_Commands
{
public static readonly RoutedUICommand OpenSettings = new RoutedUICommand("Open Settings Window", "OpenSettings", typeof(MainWindow));
public static readonly RoutedUICommand OpenSearch = new RoutedUICommand("Open Search Window", "OpenSearch", typeof(MainWindow));
public static readonly RoutedUICommand OpenOutput = new RoutedUICommand("Open Output Folder", "OpenOutput", typeof(MainWindow));
public static readonly RoutedUICommand MergeImages = new RoutedUICommand("Merge Images", "MergeImages", typeof(MainWindow));
}
}

View File

@ -0,0 +1,102 @@
using FModel.Creator.Bundles;
using FModel.Creator.Texts;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using System.Collections.Generic;
namespace FModel.Creator
{
public class BaseBundle
{
public Header DisplayStyle;
public string DisplayName;
public string FolderName;
public string Watermark;
public int Width = 1024;
public int HeaderHeight = 261; // height is the header basically
public int AdditionalSize = 50; // must be increased depending on the number of quests to draw
public bool IsDisplayNameShifted;
public List<Quest> Quests;
public List<CompletionReward> CompletionRewards;
public BaseBundle()
{
DisplayStyle = new Header();
DisplayName = "";
FolderName = "";
Watermark = Properties.Settings.Default.ChallengeBannerWatermark;
Quests = new List<Quest>();
CompletionRewards = new List<CompletionReward>();
}
/// <summary>
/// used for the settings
/// </summary>
public BaseBundle(string watermark) : this()
{
DisplayName = "{DisplayName}";
FolderName = "{FolderName}";
Watermark = watermark;
Quests.Add(new Quest { Description = "", Count = 999, Reward = null });
AdditionalSize += 89;
}
public BaseBundle(IUExport export, string assetFolder) : this()
{
if (export.GetExport<StructProperty>("DisplayStyle") is StructProperty displayStyle)
DisplayStyle = new Header(displayStyle, assetFolder);
if (export.GetExport<TextProperty>("DisplayName") is TextProperty displayName)
DisplayName = Text.GetTextPropertyBase(displayName);
if (export.GetExport<ArrayProperty>("CareerQuestBitShifts") is ArrayProperty careerQuestBitShifts)
{
foreach (SoftObjectProperty questPath in careerQuestBitShifts.Value)
{
PakPackage p = Utils.GetPropertyPakPackage(questPath.Value.AssetPathName.String);
if (p.HasExport() && !p.Equals(default))
{
var obj = p.GetExport<UObject>();
if (obj != null)
Quests.Add(new Quest(obj));
}
}
}
if (export.GetExport<ArrayProperty>("BundleCompletionRewards") is ArrayProperty bundleCompletionRewards)
{
foreach (StructProperty completionReward in bundleCompletionRewards.Value)
{
if (completionReward.Value is UObject reward &&
reward.TryGetValue("CompletionCount", out var c) && c is IntProperty completionCount &&
reward.TryGetValue("Rewards", out var r) && r is ArrayProperty rewards)
{
foreach (StructProperty rew in rewards.Value)
{
if (rew.Value is UObject re &&
re.TryGetValue("Quantity", out var q) && q is IntProperty quantity &&
re.TryGetValue("TemplateId", out var t) && t is StrProperty templateId &&
re.TryGetValue("ItemDefinition", out var d) && d is SoftObjectProperty itemDefinition)
{
if (!itemDefinition.Value.AssetPathName.IsNone &&
!itemDefinition.Value.AssetPathName.String.StartsWith("/Game/Items/Tokens/") &&
!itemDefinition.Value.AssetPathName.String.StartsWith("/Game/Athena/Items/Quests"))
{
CompletionRewards.Add(new CompletionReward(completionCount, quantity, itemDefinition));
}
else if (!string.IsNullOrEmpty(templateId.Value))
{
CompletionRewards.Add(new CompletionReward(completionCount, quantity, templateId.Value));
}
}
}
}
}
}
FolderName = assetFolder;
AdditionalSize += 95 * Quests.Count;
if (CompletionRewards.Count > 0) AdditionalSize += 50 + (95 * CompletionRewards.Count);
}
}
}

126
FModel/Creator/BaseIcon.cs Normal file
View File

@ -0,0 +1,126 @@
using FModel.Creator.Icons;
using FModel.Creator.Rarities;
using FModel.Creator.Stats;
using FModel.Creator.Texts;
using FModel.Utils;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Windows;
namespace FModel.Creator
{
public class BaseIcon
{
public SKBitmap FallbackImage;
public SKBitmap IconImage;
public SKBitmap RarityBackgroundImage;
public SKBitmap[] UserFacingFlags;
public SKColor[] RarityBackgroundColors;
public SKColor[] RarityBorderColor;
public string DisplayName;
public string Description;
public string ShortDescription;
public string CosmeticSource;
public int Size = 512; // keep it 512 (or a multiple of 512) if you don't want blurry icons
public int AdditionalSize = 0; // must be increased if there are weapon stats, hero abilities or more to draw/show
public int Margin = 2;
public List<Statistic> Stats;
public BaseIcon()
{
FallbackImage = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_Placeholder_Item_Image.png")).Stream);
IconImage = FallbackImage;
RarityBackgroundImage = null;
UserFacingFlags = null;
RarityBackgroundColors = new SKColor[2] { SKColor.Parse("5EBC36"), SKColor.Parse("305C15") };
RarityBorderColor = new SKColor[2] { SKColor.Parse("74EF52"), SKColor.Parse("74EF52") };
DisplayName = "";
Description = "";
ShortDescription = "";
CosmeticSource = "";
Stats = new List<Statistic>();
}
/// <summary>
/// used to get low res icons ONLY
/// </summary>
/// <param name="export"></param>
/// <param name="assetName"></param>
public BaseIcon(IUExport export, string assetName) : this()
{
if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
LargeSmallImage.GetPreviewImage(this, itemDef, assetName, false);
else if (export.GetExport<SoftObjectProperty>("SmallPreviewImage", "SmallImage") is SoftObjectProperty previewImage)
LargeSmallImage.GetPreviewImage(this, previewImage);
}
/// <summary>
/// Order:
/// 1. Rarity
/// 2. Image
/// 3. Text
/// 1. DisplayName
/// 2. Description
/// 3. Misc
/// 4. GameplayTags
/// 1. order doesn't matter
/// 2. the importance here is to get the description before gameplay tags
/// </summary>
public BaseIcon(IUExport export, string exportType, string assetName) : this()
{
// rarity
if (export.GetExport<ObjectProperty>("Series") is ObjectProperty series)
Serie.GetRarity(this, series);
else if (Properties.Settings.Default.UseGameColors) // override default green
Rarity.GetInGameRarity(this, export.GetExport<EnumProperty>("Rarity")); // uncommon will be triggered by Rarity being null
else if (export.GetExport<EnumProperty>("Rarity") is EnumProperty rarity)
Rarity.GetHardCodedRarity(this, rarity);
// image
if (Properties.Settings.Default.UseItemShopIcon &&
DisplayAssetImage.GetDisplayAssetImage(this, export.GetExport<SoftObjectProperty>("DisplayAssetPath"), assetName))
{ } // ^^^^ will return false if image not found, if so, we try to get the normal icon
else if (export.GetExport<ObjectProperty>("HeroDefinition", "WeaponDefinition") is ObjectProperty itemDef)
LargeSmallImage.GetPreviewImage(this, itemDef, assetName);
else if (export.GetExport<SoftObjectProperty>("LargePreviewImage", "SmallPreviewImage", "ItemDisplayAsset") is SoftObjectProperty previewImage)
LargeSmallImage.GetPreviewImage(this, previewImage);
else if (export.GetExport<StructProperty>("IconBrush") is StructProperty iconBrush) // abilities
LargeSmallImage.GetPreviewImage(this, iconBrush);
// text
if (export.GetExport<TextProperty>("DisplayName", "DefaultHeaderText", "UIDisplayName") is TextProperty displayName)
DisplayName = Text.GetTextPropertyBase(displayName);
if (export.GetExport<TextProperty>("Description", "DefaultBodyText") is TextProperty description)
Description = Text.GetTextPropertyBase(description);
else if (export.GetExport<ArrayProperty>("Description") is ArrayProperty arrayDescription) // abilities
Description = Text.GetTextPropertyBase(arrayDescription);
if (export.GetExport<StructProperty>("MaxStackSize") is StructProperty maxStackSize)
ShortDescription = Text.GetMaxStackSize(maxStackSize);
else if (export.GetExport<TextProperty>("ShortDescription") is TextProperty shortDescription)
ShortDescription = Text.GetTextPropertyBase(shortDescription);
else if (exportType.Equals("AthenaItemWrapDefinition")) // if no ShortDescription it's most likely a wrap
ShortDescription = Localizations.GetLocalization("Fort.Cosmetics", "ItemWrapShortDescription", "Wrap");
// gameplaytags
if (export.GetExport<StructProperty>("GameplayTags") is StructProperty gameplayTags)
GameplayTag.GetGameplayTags(this, gameplayTags, exportType);
else if (export.GetExport<ObjectProperty>("cosmetic_item") is ObjectProperty cosmeticItem) // variants
CosmeticSource = cosmeticItem.Value.Resource.ObjectName.String;
if (export.GetExport<SoftObjectProperty>("AmmoData") is SoftObjectProperty ammoData)
Statistics.GetAmmoData(this, ammoData);
if (export.GetExport<StructProperty>("WeaponStatHandle") is StructProperty weaponStatHandle)
Statistics.GetWeaponStats(this, weaponStatHandle);
if (export.GetExport<ObjectProperty>("HeroGameplayDefinition") is ObjectProperty heroGameplayDefinition)
Statistics.GetHeroStats(this, heroGameplayDefinition);
/* Please do not add Schematics support because it takes way too much memory */
/* Thank the STW Dev Team for using a 5,69Mb file to get... Oh nvm, they all left */
AdditionalSize = 48 * Stats.Count;
}
}
}

View File

@ -0,0 +1,166 @@
using FModel.Creator.Texts;
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System.Collections.Generic;
namespace FModel.Creator
{
public class Options
{
public string Option;
public SKColor Color = SKColor.Parse("55C5FC").WithAlpha(150);
}
public class BaseUserOption
{
private readonly SKPaint descriptionPaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DisplayNameTypeface,
TextSize = 25,
Color = SKColor.Parse("88DBFF"),
};
public string OptionDisplayName;
public string OptionDescription;
public List<Options> OptionValues = new List<Options>();
public int Width = 512;
public int Height = 128;
public int Margin = 32;
public BaseUserOption(IUExport export)
{
if (export.GetExport<TextProperty>("OptionDisplayName") is TextProperty optionDisplayName)
OptionDisplayName = Text.GetTextPropertyBase(optionDisplayName).ToUpperInvariant();
if (export.GetExport<TextProperty>("OptionDescription") is TextProperty optionDescription)
{
OptionDescription = Text.GetTextPropertyBase(optionDescription);
Height += (int)descriptionPaint.TextSize * Helper.SplitLines(OptionDescription, descriptionPaint, Width - Margin).Length;
Height += (int)descriptionPaint.TextSize;
}
if (export.GetExport<ArrayProperty>("OptionValues") is ArrayProperty optionValues)
{
OptionValues = new List<Options>(optionValues.Value.Length);
for (int i = 0; i < OptionValues.Capacity; i++)
{
if (optionValues.Value[i] is StructProperty s && s.Value is UObject option)
{
if (option.TryGetValue("DisplayName", out var v1) && v1 is TextProperty displayName)
{
var opt = new Options { Option = Text.GetTextPropertyBase(displayName).ToUpperInvariant() };
if (option.TryGetValue("Value", out var v) && v is StructProperty value && value.Value is FLinearColor color)
opt.Color = SKColor.Parse(color.Hex).WithAlpha(150);
OptionValues.Add(opt);
}
else if (option.TryGetValue("PrimaryAssetName", out var v2) && v2 is NameProperty primaryAssetName)
OptionValues.Add(new Options { Option = primaryAssetName.Value.String });
}
}
}
if (export.GetExport<TextProperty>("OptionOnText") is TextProperty optionOnText)
OptionValues.Add(new Options { Option = Text.GetTextPropertyBase(optionOnText).ToUpperInvariant() });
if (export.GetExport<TextProperty>("OptionOffText") is TextProperty optionOffText)
OptionValues.Add(new Options { Option = Text.GetTextPropertyBase(optionOffText).ToUpperInvariant() });
if (export.GetExport<IntProperty>("Min", "DefaultValue") is IntProperty iMin &&
export.GetExport<IntProperty>("Max") is IntProperty iMax)
{
int increment = iMin.Value;
if (export.GetExport<IntProperty>("IncrementValue") is IntProperty incrementValue)
increment = incrementValue.Value;
for (int i = iMin.Value; i <= iMax.Value; i += increment)
{
OptionValues.Add(new Options { Option = i.ToString() });
}
}
if (export.GetExport<FloatProperty>("Min") is FloatProperty fMin &&
export.GetExport<FloatProperty>("Max") is FloatProperty fMax)
{
float increment = fMin.Value;
if (export.GetExport<FloatProperty>("IncrementValue") is FloatProperty incrementValue)
increment = incrementValue.Value;
for (float i = fMin.Value; i <= fMax.Value; i += increment)
{
OptionValues.Add(new Options { Option = i.ToString() });
}
}
Height += Margin;
Height += 35 * OptionValues.Count;
}
public void Draw(SKCanvas c)
{
c.DrawRect(new SKRect(0, 0, Width, Height),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateLinearGradient(
new SKPoint(Width / 2, Height),
new SKPoint(Width, Height / 4),
new SKColor[2] { SKColor.Parse("01369C"), SKColor.Parse("1273C8") },
SKShaderTileMode.Clamp)
});
int textSize = 45;
SKPaint namePaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DisplayNameTypeface,
TextSize = textSize,
Color = SKColors.White,
TextAlign = SKTextAlign.Left
};
// resize if too long
while (namePaint.MeasureText(OptionDisplayName) > (Width - (Margin * 2)))
{
namePaint.TextSize = textSize -= 2;
}
int y = Margin + textSize;
c.DrawText(OptionDisplayName, Margin, y, namePaint);
y += (int)descriptionPaint.TextSize + (Margin / 2);
// wrap if too long
Helper.DrawMultilineText(c, OptionDescription, Width, Margin, ETextSide.Left,
new SKRect(Margin, y, Width - Margin, 256), descriptionPaint, out int top);
int height = 30;
int space = 5;
foreach (Options option in OptionValues)
{
c.DrawRect(new SKRect(Margin, top, Width - Margin, top + height),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = option.Color
});
int ts = 20;
c.DrawText(option.Option, Margin + (space * 2), top + (ts * 1.1f),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DisplayNameTypeface,
TextSize = ts,
Color = SKColor.Parse("EEFFFF"),
TextAlign = SKTextAlign.Left
});
top += height + space;
}
}
}
}

View File

@ -0,0 +1,60 @@
using FModel.Utils;
using PakReader.Parsers.PropertyTagData;
using System;
namespace FModel.Creator.Bundles
{
public class CompletionReward
{
private const string _TRIGGER1 = "<text color=\"FFF\" case=\"upper\" fontface=\"black\">";
private const string _TRIGGER2 = "</>";
public string CompletionText;
public Reward Reward;
public CompletionReward(IntProperty completionCount)
{
string all = Localizations.GetLocalization("AthenaChallengeDetailsEntry", "CompletionRewardFormat_All", "Complete <text color=\"FFF\" case=\"upper\" fontface=\"black\">all {0} challenges</> to earn the reward item");
string allFormated = ReformatString(all, completionCount.Value.ToString(), true);
string any = Localizations.GetLocalization("AthenaChallengeDetailsEntry", "CompletionRewardFormat", "Complete <text color=\"FFF\" case=\"upper\" fontface=\"black\">any {0} challenges</> to earn the reward item");
string anyFormated = ReformatString(any, completionCount.Value.ToString(), false);
CompletionText = completionCount.Value >= 0 ? anyFormated : allFormated;
Reward = null;
}
public CompletionReward(IntProperty completionCount, IntProperty quantity, SoftObjectProperty itemDefinition) : this(completionCount)
{
Reward = new Reward(quantity, itemDefinition);
}
public CompletionReward(IntProperty completionCount, IntProperty quantity, string reward) : this(completionCount)
{
Reward = new Reward(quantity, reward);
}
private string ReformatString(string s, string completionCount, bool isAll)
{
s = s.Replace("({0})", "{0}").Replace("{QuestNumber}", "<text color=\"FFF\" case=\"upper\" fontface=\"black\">{0}</>");
int index = s.IndexOf("|plural(", StringComparison.CurrentCultureIgnoreCase);
if (index > -1)
{
int i = s.Substring(index).IndexOf(')', StringComparison.CurrentCultureIgnoreCase);
s = s.Replace(s.Substring(index, i + 1), string.Empty).Replace("{0} {0}", "{0}");
}
int index1 = s.IndexOf(_TRIGGER1, StringComparison.CurrentCultureIgnoreCase);
if (index1 < 0) index1 = 0;
string partOne = s.Substring(0, index1);
string partTemp = s.Substring(index1 + _TRIGGER1.Length);
int index2 = partTemp.IndexOf(_TRIGGER2, StringComparison.CurrentCultureIgnoreCase);
if (index2 < 0) index2 = 0;
string partUpper = partTemp.Substring(0, index2).ToUpper().Replace("{0}", isAll ? string.Empty : completionCount);
string partTwo = partTemp.Substring(index2 + _TRIGGER2.Length);
return string.Format("{0}{1}{2}", partOne, partUpper, partTwo).Replace(" ", " ").Replace(" ,", ",");
}
}
}

View File

@ -0,0 +1,106 @@
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
using System.IO;
namespace FModel.Creator.Bundles
{
public class Header
{
public SKColor PrimaryColor;
public SKColor SecondaryColor;
public SKColor AccentColor;
public SKBitmap DisplayImage; // 256x256
public SKBitmap CustomBackground; // 1024x256
private readonly Random _random = new Random(Environment.TickCount);
private readonly string[] _randomColors = new string[255]
{
"F44336", "FFEBEE", "FFCDD2", "EF9A9A", "E57373", "EF5350", "E53935", "D32F2F", "C62828", "B71C1C",
"FF8A80", "FF5252", "FF1744", "D50000", "FCE4EC", "F8BBD0", "F48FB1", "F06292", "EC407A", "E91E63",
"D81B60", "C2185B", "AD1457", "880E4F", "FF80AB", "FF4081", "F50057", "C51162", "F3E5F5", "E1BEE7",
"CE93D8", "BA68C8", "AB47BC", "9C27B0", "8E24AA", "7B1FA2", "6A1B9A", "4A148C", "EA80FC", "E040FB",
"D500F9", "AA00FF", "EDE7F6", "D1C4E9", "B39DDB", "9575CD", "7E57C2", "673AB7", "5E35B1", "512DA8",
"4527A0", "311B92", "B388FF", "7C4DFF", "651FFF", "6200EA", "E8EAF6", "C5CAE9", "9FA8DA", "7986CB",
"5C6BC0", "3F51B5", "3949AB", "303F9F", "283593", "1A237E", "8C9EFF", "536DFE", "3D5AFE", "304FFE",
"E3F2FD", "BBDEFB", "90CAF9", "64B5F6", "42A5F5", "2196F3", "1E88E5", "1976D2", "1565C0", "0D47A1",
"82B1FF", "448AFF", "2979FF", "2962FF", "E1F5FE", "B3E5FC", "81D4FA", "4FC3F7", "29B6F6", "03A9F4",
"039BE5", "0288D1", "0277BD", "01579B", "80D8FF", "40C4FF", "00B0FF", "0091EA", "E0F7FA", "B2EBF2",
"80DEEA", "4DD0E1", "26C6DA", "00BCD4", "00ACC1", "0097A7", "00838F", "006064", "84FFFF", "18FFFF",
"00E5FF", "00B8D4", "E0F2F1", "B2DFDB", "80CBC4", "4DB6AC", "26A69A", "009688", "00897B", "00796B",
"00695C", "004D40", "A7FFEB", "64FFDA", "1DE9B6", "00BFA5", "E8F5E9", "C8E6C9", "A5D6A7", "81C784",
"66BB6A", "4CAF50", "43A047", "388E3C", "2E7D32", "1B5E20", "B9F6CA", "69F0AE", "00E676", "00C853",
"F1F8E9", "DCEDC8", "C5E1A5", "AED581", "9CCC65", "8BC34A", "7CB342", "689F38", "558B2F", "33691E",
"CCFF90", "B2FF59", "76FF03", "64DD17", "F9FBE7", "F0F4C3", "E6EE9C", "DCE775", "D4E157", "CDDC39",
"C0CA33", "AFB42B", "9E9D24", "827717", "F4FF81", "EEFF41", "C6FF00", "AEEA00", "FFFDE7", "FFF9C4",
"FFF59D", "FFF176", "FFEE58", "FFEB3B", "FDD835", "FBC02D", "F9A825", "F57F17", "FFFF8D", "FFFF00",
"FFEA00", "FFD600", "FFF8E1", "FFECB3", "FFE082", "FFD54F", "FFCA28", "FFC107", "FFB300", "FFA000",
"FF8F00", "FF6F00", "FFE57F", "FFD740", "FFC400", "FFAB00", "FFF3E0", "FFE0B2", "FFCC80", "FFB74D",
"FFA726", "FF9800", "FB8C00", "F57C00", "EF6C00", "E65100", "FFD180", "FFAB40", "FF9100", "FF6D00",
"FBE9E7", "FFCCBC", "FFAB91", "FF8A65", "FF7043", "FF5722", "F4511E", "E64A19", "D84315", "BF360C",
"FF9E80", "FF6E40", "FF3D00", "DD2C00", "EFEBE9", "D7CCC8", "BCAAA4", "A1887F", "8D6E63", "795548",
"6D4C41", "5D4037", "4E342E", "3E2723", "FAFAFA", "F5F5F5", "EEEEEE", "E0E0E0", "BDBDBD", "9E9E9E",
"757575", "616161", "424242", "212121", "ECEFF1", "CFD8DC", "B0BEC5", "90A4AE", "78909C", "607D8B",
"546E7A", "455A64", "37474F", "263238", "000000",
};
public Header()
{
if (Properties.Settings.Default.UseChallengeBanner)
{
SKColor mainColor = SKColor.Parse(Properties.Settings.Default.ChallengeBannerPrimaryColor);
mainColor.ToHsl(out float h, out float s, out float l);
float i = l + 20.0F > 100.0F ? 100.0F - l : 20.0F;
PrimaryColor = mainColor;
SecondaryColor = SKColor.Parse(Properties.Settings.Default.ChallengeBannerSecondaryColor);
AccentColor = SKColor.FromHsl(h += i, s, l);
DisplayImage = null;
if (!string.IsNullOrEmpty(Properties.Settings.Default.ChallengeBannerPath))
CustomBackground = SKBitmap.Decode(new FileInfo(Properties.Settings.Default.ChallengeBannerPath).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
else CustomBackground = null;
}
else
{
SKColor mainColor = SKColor.Parse(_randomColors[_random.Next(0, 255)]);
mainColor.ToHsl(out float h, out float s, out float l);
while (l > 75 || l < 10)
{
mainColor = SKColor.Parse(_randomColors[_random.Next(0, 255)]);
mainColor.ToHsl(out float _, out float _, out l);
}
float i = l + 20.0F > 100.0F ? 100.0F - l : 20.0F;
PrimaryColor = mainColor;
SecondaryColor = SKColor.FromHsl(h, s, l += i);
AccentColor = SKColor.FromHsl(h += i, s, l);
DisplayImage = null;
CustomBackground = null;
}
}
public Header(StructProperty displayStyle, string assetFolder) : this()
{
if (displayStyle.Value is UObject o)
{
if (!Properties.Settings.Default.UseChallengeBanner && o.TryGetValue(out var c1, "PrimaryColor", "Context_LimitedTimeColor") && c1 is StructProperty s1 && s1.Value is FLinearColor primaryColor)
PrimaryColor = SKColor.Parse(primaryColor.Hex);
if (!Properties.Settings.Default.UseChallengeBanner && o.TryGetValue(out var c2, "SecondaryColor", "Context_BaseColor") && c2 is StructProperty s2 && s2.Value is FLinearColor secondaryColor)
SecondaryColor = SKColor.Parse(secondaryColor.Hex);
if (!Properties.Settings.Default.UseChallengeBanner && o.TryGetValue("AccentColor", out var c3) && c3 is StructProperty s3 && s3.Value is FLinearColor accentColor)
{
AccentColor = SKColor.Parse(accentColor.Hex);
if (SecondaryColor.Red + SecondaryColor.Green + SecondaryColor.Blue <= 75 || assetFolder.Equals("LTM", StringComparison.CurrentCultureIgnoreCase)) // if secondary is too dark
SecondaryColor = AccentColor; // use accent and pray for accent to be ligher
}
if (o.TryGetValue("DisplayImage", out var i) && i is SoftObjectProperty displayImage)
DisplayImage = Utils.GetSoftObjectTexture(displayImage);
if (CustomBackground == null && o.TryGetValue("CustomBackground", out var b) && b is SoftObjectProperty customBackground)
CustomBackground = Utils.GetSoftObjectTexture(customBackground);
}
}
}
}

View File

@ -0,0 +1,98 @@
using FModel.Creator.Texts;
using SkiaSharp;
using System;
namespace FModel.Creator.Bundles
{
static class HeaderStyle
{
public static void DrawHeaderPaint(SKCanvas c, BaseBundle icon)
{
c.DrawRect(new SKRect(0, 0, icon.Width, icon.HeaderHeight), new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = icon.DisplayStyle.PrimaryColor
});
if (icon.DisplayStyle.CustomBackground != null && icon.DisplayStyle.CustomBackground.Height != icon.DisplayStyle.CustomBackground.Width)
{
icon.IsDisplayNameShifted = false;
var bgPaint = new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High, BlendMode = SKBlendMode.Screen };
if (Properties.Settings.Default.UseChallengeBanner) bgPaint.Color = SKColors.Transparent.WithAlpha((byte)Properties.Settings.Default.ChallengeBannerOpacity);
c.DrawBitmap(icon.DisplayStyle.CustomBackground, new SKRect(0, 0, 1024, 256), bgPaint);
}
else if (icon.DisplayStyle.DisplayImage != null)
{
icon.IsDisplayNameShifted = true;
if (icon.DisplayStyle.CustomBackground != null && icon.DisplayStyle.CustomBackground.Height == icon.DisplayStyle.CustomBackground.Width)
c.DrawBitmap(icon.DisplayStyle.CustomBackground, new SKRect(0, 0, icon.HeaderHeight, icon.HeaderHeight),
new SKPaint {
IsAntialias = true, FilterQuality = SKFilterQuality.High, BlendMode = SKBlendMode.Screen,
ImageFilter = SKImageFilter.CreateDropShadow(2.5F, 0, 20, 0, icon.DisplayStyle.SecondaryColor.WithAlpha(25), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground)
});
c.DrawBitmap(icon.DisplayStyle.DisplayImage, new SKRect(0, 0, icon.HeaderHeight, icon.HeaderHeight),
new SKPaint {
IsAntialias = true, FilterQuality = SKFilterQuality.High,
ImageFilter = SKImageFilter.CreateDropShadow(-2.5F, 0, 20, 0, icon.DisplayStyle.SecondaryColor.WithAlpha(50), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground)
});
}
SKPath pathTop = new SKPath { FillType = SKPathFillType.EvenOdd };
pathTop.MoveTo(0, icon.HeaderHeight);
pathTop.LineTo(icon.Width, icon.HeaderHeight);
pathTop.LineTo(icon.Width, icon.HeaderHeight - 19);
pathTop.LineTo(icon.Width / 2 + 7, icon.HeaderHeight - 23);
pathTop.LineTo(icon.Width / 2 + 13, icon.HeaderHeight - 7);
pathTop.LineTo(0, icon.HeaderHeight - 19);
pathTop.Close();
c.DrawPath(pathTop, new SKPaint {
IsAntialias = true, FilterQuality = SKFilterQuality.High, Color = icon.DisplayStyle.SecondaryColor,
ImageFilter = SKImageFilter.CreateDropShadow(-5, -5, 0, 0, icon.DisplayStyle.AccentColor.WithAlpha(75), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground)
});
c.DrawRect(new SKRect(0, icon.HeaderHeight, icon.Width, icon.HeaderHeight + icon.AdditionalSize), new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = icon.DisplayStyle.PrimaryColor.WithAlpha(200) // default background is black, so i'm kinda lowering the brightness here and that's what i want
});
}
public static void DrawHeaderText(SKCanvas c, BaseBundle icon)
{
using SKPaint paint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.BundleDisplayNameTypeface,
TextSize = 50,
Color = SKColors.White,
TextAlign = SKTextAlign.Left,
};
string text = icon.DisplayName.ToUpper();
int x = icon.IsDisplayNameShifted ? 300 : 50;
while (paint.MeasureText(text) > (icon.Width - x))
{
paint.TextSize -= 2;
}
c.DrawText(text, x, 155, paint);
paint.Color = SKColors.White.WithAlpha(150);
paint.TextAlign = SKTextAlign.Right;
paint.TextSize = 23;
c.DrawText(icon.Watermark
.Replace("{BundleName}", text)
.Replace("{Date}", DateTime.Now.ToString("dd/MM/yyyy")),
icon.Width - 25, icon.HeaderHeight - 40, paint);
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
paint.Color = icon.DisplayStyle.SecondaryColor;
paint.TextAlign = SKTextAlign.Left;
paint.TextSize = 30;
c.DrawText(icon.FolderName.ToUpper(), x, 95, paint);
}
}
}

View File

@ -0,0 +1,94 @@
using FModel.Creator.Texts;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
namespace FModel.Creator.Bundles
{
public class Quest
{
public string Description;
public int Count;
public Reward Reward;
public Quest()
{
Description = "";
Count = 0;
Reward = null;
}
public Quest(UObject obj) : this()
{
if (obj.TryGetValue("Description", out var d) && d is TextProperty description)
Description = Text.GetTextPropertyBase(description);
if (obj.TryGetValue("ObjectiveCompletionCount", out var o) && o is IntProperty objectiveCompletionCount)
Count = objectiveCompletionCount.Value;
if (obj.TryGetValue("Objectives", out var v1) && v1 is ArrayProperty a1 &&
a1.Value.Length > 0 && a1.Value[0] is StructProperty s && s.Value is UObject objectives)
{
if (string.IsNullOrEmpty(Description) && objectives.TryGetValue("Description", out var od) && od is TextProperty objectivesDescription)
Description = Text.GetTextPropertyBase(objectivesDescription);
if (Count == 0 && objectives.TryGetValue("Count", out var c) && c is IntProperty count)
Count = count.Value;
}
if (obj.TryGetValue("RewardsTable", out var v4) && v4 is ObjectProperty rewardsTable)
{
PakPackage p = Utils.GetPropertyPakPackage(rewardsTable.Value.Resource.OuterIndex.Resource.ObjectName.String);
if (p.HasExport() && !p.Equals(default))
{
var u = p.GetExport<UDataTable>();
if (u != null && u.TryGetValue("Default", out var i) && i is UObject r &&
r.TryGetValue("TemplateId", out var i1) && i1 is NameProperty templateId &&
r.TryGetValue("Quantity", out var i2) && i2 is IntProperty quantity)
{
Reward = new Reward(quantity, templateId);
}
}
}
if (Reward == null && obj.TryGetValue("Rewards", out var v2) && v2 is ArrayProperty rewards)
{
foreach (StructProperty reward in rewards.Value)
{
if (reward.Value is UObject r1 &&
r1.TryGetValue("ItemPrimaryAssetId", out var i1) && i1 is StructProperty itemPrimaryAssetId &&
r1.TryGetValue("Quantity", out var i2) && i2 is IntProperty quantity)
{
if (itemPrimaryAssetId.Value is UObject r2 &&
r2.TryGetValue("PrimaryAssetType", out var t1) && t1 is StructProperty primaryAssetType &&
r2.TryGetValue("PrimaryAssetName", out var t2) && t2 is NameProperty primaryAssetName)
{
if (primaryAssetType.Value is UObject r3 && r3.TryGetValue("Name", out var k) && k is NameProperty name)
{
if (!name.Value.String.Equals("Quest") && !name.Value.String.Equals("Token") &&
!name.Value.String.Equals("ChallengeBundle") && !name.Value.String.Equals("GiftBox"))
{
Reward = new Reward(quantity, primaryAssetName);
break;
}
}
}
}
}
}
if (Reward == null && obj.TryGetValue("HiddenRewards", out var v3) && v3 is ArrayProperty hiddenRewards)
{
foreach (StructProperty reward in hiddenRewards.Value)
{
if (reward.Value is UObject r1 &&
r1.TryGetValue("TemplateId", out var i1) && i1 is NameProperty templateId &&
r1.TryGetValue("Quantity", out var i2) && i2 is IntProperty quantity)
{
Reward = new Reward(quantity, templateId);
break;
}
}
}
}
}
}

View File

@ -0,0 +1,174 @@
using FModel.Creator.Texts;
using SkiaSharp;
namespace FModel.Creator.Bundles
{
static class QuestStyle
{
public static void DrawQuests(SKCanvas c, BaseBundle icon)
{
using SKPaint paint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
TextSize = 27,
Color = SKColors.White,
TextAlign = SKTextAlign.Left,
Typeface = Text.TypeFaces.BundleDisplayNameTypeface
};
int y = icon.HeaderHeight + 50;
foreach (Quest q in icon.Quests)
{
DrawQuestBackground(c, icon, y, true);
paint.TextSize = 27;
paint.ImageFilter = null;
paint.Color = SKColors.White;
paint.TextAlign = SKTextAlign.Left;
paint.Typeface = Text.TypeFaces.BundleDisplayNameTypeface;
while (paint.MeasureText(q.Description) > icon.Width - 65 - 165)
{
paint.TextSize -= 1;
}
c.DrawText(q.Description, new SKPoint(65, y + paint.TextSize + 11), paint);
paint.TextSize = 16;
paint.Color = SKColors.White.WithAlpha(200);
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
c.DrawText(q.Count.ToString(), new SKPoint(93 + icon.Width - (175 * 3), y + 60), paint);
if (q.Reward?.RewardIcon != null)
{
if (q.Reward.IsCountShifted)
{
int l = q.Reward.RewardQuantity.ToString().Length;
paint.TextSize = l >= 5 ? 30 : 35;
paint.TextAlign = SKTextAlign.Right;
paint.Color = SKColor.Parse(q.Reward.RewardFillColor);
paint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 5, 5, SKColor.Parse(q.Reward.RewardBorderColor).WithAlpha(200), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground);
c.DrawText(q.Reward.RewardQuantity.ToString(), new SKPoint(icon.Width - 85, y + 47.5F), paint);
c.DrawBitmap(q.Reward.RewardIcon, new SKPoint(icon.Width - 30 - q.Reward.RewardIcon.Width, y + 12.5F),
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
}
else
c.DrawBitmap(q.Reward.RewardIcon, new SKPoint(icon.Width - 125, y + 5),
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
}
y += 95;
}
}
public static void DrawCompletionRewards(SKCanvas c, BaseBundle icon)
{
using SKPaint paint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
TextSize = 35,
Color = SKColors.White,
TextAlign = SKTextAlign.Left,
Typeface = Text.TypeFaces.BundleDisplayNameTypeface
};
int y = icon.HeaderHeight + (50 * 2) + (95 * icon.Quests.Count);
foreach (CompletionReward r in icon.CompletionRewards)
{
DrawQuestBackground(c, icon, y, false);
paint.TextSize = 35;
paint.ImageFilter = null;
paint.Color = SKColors.White;
paint.TextAlign = SKTextAlign.Left;
paint.Typeface = Text.TypeFaces.BundleDisplayNameTypeface;
while (paint.MeasureText(r.CompletionText) > icon.Width - 65 - 165)
{
paint.TextSize -= 1;
}
c.DrawText(r.CompletionText, new SKPoint(65, y + paint.TextSize + 15), paint);
if (r.Reward?.RewardIcon != null)
{
if (r.Reward.IsCountShifted)
{
int l = r.Reward.RewardQuantity.ToString().Length;
paint.TextSize = l >= 5 ? 30 : 35;
paint.TextAlign = SKTextAlign.Right;
paint.Color = SKColor.Parse(r.Reward.RewardFillColor);
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
paint.ImageFilter = SKImageFilter.CreateDropShadow(0, 0, 5, 5, SKColor.Parse(r.Reward.RewardBorderColor).WithAlpha(200), SKDropShadowImageFilterShadowMode.DrawShadowAndForeground);
c.DrawText(r.Reward.RewardQuantity.ToString(), new SKPoint(icon.Width - 85, y + 47.5F), paint);
c.DrawBitmap(r.Reward.RewardIcon, new SKPoint(icon.Width - 30 - r.Reward.RewardIcon.Width, y + 12.5F),
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
}
else
c.DrawBitmap(r.Reward.RewardIcon, new SKPoint(icon.Width - 125, y + 5),
new SKPaint { IsAntialias = true, FilterQuality = SKFilterQuality.High });
}
y += 95;
}
}
private static void DrawQuestBackground(SKCanvas c, BaseBundle icon, int y, bool hasSlider)
{
SKColor baseColor = icon.DisplayStyle.PrimaryColor;
using SKPaint paint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = baseColor
};
using SKPath secondaryRect = new SKPath
{
FillType = SKPathFillType.EvenOdd
};
using SKPath selector = new SKPath
{
FillType = SKPathFillType.EvenOdd
};
using SKPath slider = new SKPath
{
FillType = SKPathFillType.EvenOdd
};
c.DrawRect(new SKRect(25, y, icon.Width - 25, y + 75), paint);
baseColor.ToHsl(out float h, out float s, out float l);
baseColor = SKColor.FromHsl(h, s, l + 5);
paint.Color = baseColor;
secondaryRect.MoveTo(32, y + 5);
secondaryRect.LineTo(icon.Width - 155, y + 4);
secondaryRect.LineTo(icon.Width - 175, y + 68);
secondaryRect.LineTo(29, y + 71);
secondaryRect.Close();
c.DrawPath(secondaryRect, paint);
paint.Color = icon.DisplayStyle.SecondaryColor;
selector.MoveTo(41, y + 38);
selector.LineTo(48, y + 34);
selector.LineTo(52, y + 39);
selector.LineTo(46, y + 44);
selector.Close();
c.DrawPath(selector, paint);
if (hasSlider)
{
slider.MoveTo(65, y + 53);
slider.LineTo(65 + icon.Width - (175 * 3), y + 53);
slider.LineTo(65 + icon.Width - (175 * 3), y + 58);
slider.LineTo(65, y + 58);
slider.Close();
c.DrawPath(slider, paint);
paint.TextSize = 14;
paint.Color = SKColors.White;
paint.TextAlign = SKTextAlign.Left;
paint.Typeface = Text.TypeFaces.BundleDefaultTypeface;
c.DrawText("0 / ", new SKPoint(75 + icon.Width - (175 * 3), y + 59), paint);
}
}
}
}

View File

@ -0,0 +1,134 @@
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
namespace FModel.Creator.Bundles
{
public class Reward
{
public int RewardQuantity;
public SKBitmap RewardIcon;
public string RewardFillColor;
public string RewardBorderColor;
public bool IsCountShifted;
public Reward()
{
RewardQuantity = 0;
RewardIcon = null;
RewardFillColor = "";
RewardBorderColor = "";
IsCountShifted = false;
}
public Reward(IntProperty quantity, NameProperty primaryAssetName) : this(quantity, primaryAssetName.Value.String) { }
public Reward(IntProperty quantity, string assetName) : this()
{
RewardQuantity = quantity.Value;
if (assetName.Contains(':'))
{
string[] parts = assetName.Split(':');
if (parts[0].Equals("HomebaseBannerIcon", StringComparison.CurrentCultureIgnoreCase))
{
PakPackage p = Utils.GetPropertyPakPackage("/Game/Banners/BannerIcons");
if (p.HasExport() && !p.Equals(default))
{
var c = p.GetExport<UDataTable>();
if (c != null && c.TryGetCaseInsensitiveValue(parts[1], out var s) && s is UObject banner)
{
RewardIcon = new BaseIcon(banner, "BannerIcons.uasset").IconImage.Resize(64, 64);
}
}
}
else GetReward(parts[1]);
}
else GetReward(assetName);
}
public Reward(IntProperty quantity, SoftObjectProperty itemDefinition) : this()
{
RewardQuantity = quantity.Value;
PakPackage p = Utils.GetPropertyPakPackage(itemDefinition.Value.AssetPathName.String);
if (p.HasExport() && !p.Equals(default))
{
var d = p.GetExport<UObject>();
if (d != null)
{
int s1 = itemDefinition.Value.AssetPathName.String.LastIndexOf('/');
if (s1 < 0) s1 = 0;
int s2 = itemDefinition.Value.AssetPathName.String.LastIndexOf('.') - s1;
switch (itemDefinition.Value.AssetPathName.String)
{
case "/Game/Items/PersistentResources/AthenaBattleStar.AthenaBattleStar":
IsCountShifted = true;
RewardFillColor = "FFDB67";
RewardBorderColor = "8F4A20";
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-BattlePoints").Resize(48, 48);
break;
case "/Game/Items/PersistentResources/AthenaSeasonalXP.AthenaSeasonalXP":
IsCountShifted = true;
RewardFillColor = "E6FDB1";
RewardBorderColor = "51830F";
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-XPMedium").Resize(48, 48);
break;
case "/Game/Items/Currency/MtxGiveaway.MtxGiveaway":
IsCountShifted = true;
RewardFillColor = "DCE6FF";
RewardBorderColor = "64A0AF";
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-Items-MTX").Resize(48, 48);
break;
default:
IsCountShifted = false;
RewardIcon = new BaseIcon(d, itemDefinition.Value.AssetPathName.String.Substring(s1, s2) + ".uasset").IconImage.Resize(64, 64);
break;
}
}
}
}
private void GetReward(string trigger)
{
switch (trigger.ToLower())
{
case "athenabattlestar":
IsCountShifted = true;
RewardFillColor = "FFDB67";
RewardBorderColor = "8F4A20";
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-BattlePoints").Resize(48, 48);
break;
case "athenaseasonalxp":
IsCountShifted = true;
RewardFillColor = "E6FDB1";
RewardBorderColor = "51830F";
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-FNBR-XPMedium").Resize(48, 48);
break;
case "mtxgiveaway":
IsCountShifted = true;
RewardFillColor = "DCE6FF";
RewardBorderColor = "64A0AF";
RewardIcon = Utils.GetTexture("/Game/UI/Foundation/Textures/Icons/Items/T-Items-MTX").Resize(48, 48);
break;
default:
{
string path = Utils.GetFullPath($"/FortniteGame/Content/Athena/.*?/{trigger}.*").Replace("FortniteGame/Content", "Game");
PakPackage p = Utils.GetPropertyPakPackage(path);
if (p.HasExport() && !p.Equals(default))
{
var d = p.GetExport<UObject>();
if (d != null)
{
int i = path.LastIndexOf('/');
IsCountShifted = false;
RewardIcon = new BaseIcon(d, path.Substring(i > 0 ? i : 0) + ".uasset").IconImage.Resize(64, 64);
}
}
break;
}
}
}
}
}

180
FModel/Creator/Creator.cs Normal file
View File

@ -0,0 +1,180 @@
using FModel.Creator.Bundles;
using FModel.Creator.Icons;
using FModel.Creator.Rarities;
using FModel.Creator.Stats;
using FModel.Creator.Texts;
using FModel.ViewModels.ImageBox;
using PakReader.Parsers.Class;
using SkiaSharp;
using System.IO;
namespace FModel.Creator
{
static class Creator
{
/// <summary>
/// we draw based on the fist export type of the asset, no need to check others it's a waste of time
/// i don't cache images because i don't wanna store a lot of SKCanvas in the memory
/// </summary>
/// <returns>true if an icon has been drawn</returns>
public static bool TryDrawIcon(string assetPath, string exportType, IUExport export)
{
var d = new DirectoryInfo(assetPath);
string assetName = d.Name;
string assetFolder = d.Parent.Name;
if (Text.TypeFaces.NeedReload(false))
Text.TypeFaces = new Typefaces(); // when opening bundle creator settings without loading paks first
// please respect my wave if you wanna add a new exportType
// Athena first, then Fort, thank you
switch (exportType)
{
case "AthenaConsumableEmoteItemDefinition":
case "AthenaSkyDiveContrailItemDefinition":
case "AthenaLoadingScreenItemDefinition":
case "AthenaVictoryPoseItemDefinition":
case "AthenaPetCarrierItemDefinition":
case "AthenaMusicPackItemDefinition":
case "AthenaBattleBusItemDefinition":
case "AthenaCharacterItemDefinition":
case "AthenaBackpackItemDefinition":
case "AthenaPickaxeItemDefinition":
case "AthenaGadgetItemDefinition":
case "AthenaGliderItemDefinition":
case "AthenaDailyQuestDefinition":
case "AthenaSprayItemDefinition":
case "AthenaDanceItemDefinition":
case "AthenaEmojiItemDefinition":
case "AthenaItemWrapDefinition":
case "AthenaToyItemDefinition":
case "FortHeroType":
case "FortTokenType":
case "FortAbilityKit":
case "FortWorkerType":
case "FortBannerTokenType":
case "FortVariantTokenType":
case "FortFeatItemDefinition":
case "FortStatItemDefinition":
case "FortTrapItemDefinition":
case "FortAmmoItemDefinition":
case "FortQuestItemDefinition":
case "FortBadgeItemDefinition":
case "FortAwardItemDefinition":
case "FortGadgetItemDefinition":
case "FortPlaysetItemDefinition":
case "FortGiftBoxItemDefinition":
case "FortSpyTechItemDefinition":
case "FortAccoladeItemDefinition":
case "FortCardPackItemDefinition":
case "FortDefenderItemDefinition":
case "FortCurrencyItemDefinition":
case "FortResourceItemDefinition":
case "FortSchematicItemDefinition":
case "FortIngredientItemDefinition":
case "FortWeaponMeleeItemDefinition":
case "FortContextTrapItemDefinition":
case "FortPlayerPerksItemDefinition":
case "FortPlaysetPropItemDefinition":
case "FortHomebaseNodeItemDefinition":
case "FortWeaponRangedItemDefinition":
case "FortNeverPersistItemDefinition":
case "FortPlaysetGrenadeItemDefinition":
case "FortPersonalVehicleItemDefinition":
case "FortHardcoreModifierItemDefinition":
case "FortConsumableAccountItemDefinition":
case "FortConversionControlItemDefinition":
case "FortPersistentResourceItemDefinition":
case "FortCampaignHeroLoadoutItemDefinition":
case "FortConditionalResourceItemDefinition":
case "FortChallengeBundleScheduleDefinition":
case "FortWeaponMeleeDualWieldItemDefinition":
case "FortDailyRewardScheduleTokenDefinition":
{
BaseIcon icon = new BaseIcon(export, exportType, assetName);
int height = icon.Size + icon.AdditionalSize;
using (var ret = new SKBitmap(icon.Size, height, SKColorType.Rgba8888, SKAlphaType.Opaque))
using (var c = new SKCanvas(ret))
{
Rarity.DrawRarity(c, icon);
LargeSmallImage.DrawPreviewImage(c, icon);
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.NoText)
{
Text.DrawBackground(c, icon);
Text.DrawDisplayName(c, icon);
Text.DrawDescription(c, icon);
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign != EIconDesign.Mini)
{
if (!icon.ShortDescription.Equals(icon.DisplayName) && !icon.ShortDescription.Equals(icon.Description))
Text.DrawToBottom(c, icon, ETextSide.Left, icon.ShortDescription);
Text.DrawToBottom(c, icon, ETextSide.Right, icon.CosmeticSource);
}
}
UserFacingFlag.DrawUserFacingFlags(c, icon);
// has more things to show
if (height > icon.Size)
{
Statistics.DrawStats(c, icon);
}
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
}
return true;
}
case "FortItemSeriesDefinition":
{
BaseIcon icon = new BaseIcon();
using (var ret = new SKBitmap(icon.Size, icon.Size, SKColorType.Rgba8888, SKAlphaType.Opaque))
using (var c = new SKCanvas(ret))
{
Serie.GetRarity(icon, export);
Rarity.DrawRarity(c, icon);
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
}
return true;
}
case "PlaylistUserOptionEnum":
case "PlaylistUserOptionBool":
case "PlaylistUserOptionString":
case "PlaylistUserOptionIntEnum":
case "PlaylistUserOptionIntRange":
case "PlaylistUserOptionColorEnum":
case "PlaylistUserOptionFloatEnum":
case "PlaylistUserOptionFloatRange":
case "PlaylistUserOptionPrimaryAsset":
case "PlaylistUserOptionCollisionProfileEnum":
{
BaseUserOption icon = new BaseUserOption(export);
using (var ret = new SKBitmap(icon.Width, icon.Height, SKColorType.Rgba8888, SKAlphaType.Opaque))
using (var c = new SKCanvas(ret))
{
icon.Draw(c);
Watermark.DrawWatermark(c); // watermark should only be applied on icons with width = 512
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
}
return true;
}
case "FortChallengeBundleItemDefinition":
{
BaseBundle icon = new BaseBundle(export, assetFolder);
using (var ret = new SKBitmap(icon.Width, icon.HeaderHeight + icon.AdditionalSize, SKColorType.Rgba8888, SKAlphaType.Opaque))
using (var c = new SKCanvas(ret))
{
HeaderStyle.DrawHeaderPaint(c, icon);
HeaderStyle.DrawHeaderText(c, icon);
QuestStyle.DrawQuests(c, icon);
QuestStyle.DrawCompletionRewards(c, icon);
ImageBoxVm.imageBoxViewModel.Set(ret, assetName);
}
return true;
}
}
return false;
}
}
}

View File

@ -0,0 +1,55 @@
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
namespace FModel.Creator.Icons
{
static class DisplayAssetImage
{
public static bool GetDisplayAssetImage(BaseIcon icon, SoftObjectProperty o, string assetName)
{
string imageType = "DetailsImage";
switch ("DA_Featured_" + assetName)
{
case "DA_Featured_Glider_ID_141_AshtonBoardwalk.uasset":
case "DA_Featured_Glider_ID_150_TechOpsBlue.uasset":
case "DA_Featured_Glider_ID_131_SpeedyMidnight.uasset":
case "DA_Featured_Pickaxe_ID_178_SpeedyMidnight.uasset":
case "DA_Featured_Glider_ID_015_Brite.uasset":
case "DA_Featured_Glider_ID_016_Tactical.uasset":
case "DA_Featured_Glider_ID_017_Assassin.uasset":
case "DA_Featured_Pickaxe_ID_027_Scavenger.uasset":
case "DA_Featured_Pickaxe_ID_028_Space.uasset":
case "DA_Featured_Pickaxe_ID_029_Assassin.uasset":
return false;
case "DA_Featured_Glider_ID_070_DarkViking.uasset":
case "DA_Featured_CID_319_Athena_Commando_F_Nautilus.uasset":
imageType = "TileImage";
break;
}
string path = o?.Value.AssetPathName.String;
if (string.IsNullOrEmpty(path))
path = "/Game/Catalog/DisplayAssets/DA_Featured_" + assetName.Substring(0, assetName.LastIndexOf("."));
PakPackage p = Utils.GetPropertyPakPackage(path);
if (p.HasExport() && !p.Equals(default))
{
var obj = p.GetExport<UObject>();
if (obj != null)
{
if (obj.TryGetValue(imageType, out var v1) && v1 is StructProperty s && s.Value is UObject type &&
type.TryGetValue("ResourceObject", out var v2) && v2 is ObjectProperty resourceObject)
{
if (!resourceObject.Value.Resource.OuterIndex.Resource.ObjectName.String.Contains("/Game/Athena/Prototype/Textures/"))
{
icon.IconImage = Utils.GetObjectTexture(resourceObject);
return true;
}
}
}
}
return false;
}
}
}

View File

@ -0,0 +1,41 @@
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
namespace FModel.Creator.Icons
{
static class LargeSmallImage
{
public static void GetPreviewImage(BaseIcon icon, StructProperty u)
{
if (u.Value is UObject o && o.TryGetValue("ResourceObject", out var v) && v is ObjectProperty resourceObject)
icon.IconImage = Utils.GetObjectTexture(resourceObject);
}
public static void GetPreviewImage(BaseIcon icon, ObjectProperty o, string assetName) => GetPreviewImage(icon, o, assetName, true);
public static void GetPreviewImage(BaseIcon icon, ObjectProperty o, string assetName, bool hightRes)
{
string path = o.Value.Resource.OuterIndex.Resource.ObjectName.String;
if (path.Equals("/Game/Athena/Items/Weapons/WID_Harvest_Pickaxe_STWCosmetic_Tier"))
path += "_" + assetName.Substring(assetName.LastIndexOf(".") - 1, 1);
PakPackage p = Utils.GetPropertyPakPackage(path);
if (p.HasExport() && !p.Equals(default))
{
var obj = p.GetExport<UObject>();
if (obj != null)
{
if (hightRes && obj.TryGetValue("LargePreviewImage", out var sLarge) && sLarge is SoftObjectProperty largePreviewImage)
GetPreviewImage(icon, largePreviewImage);
else if (obj.TryGetValue("SmallPreviewImage", out var sSmall) && sSmall is SoftObjectProperty smallPreviewImage)
GetPreviewImage(icon, smallPreviewImage);
}
}
}
public static void GetPreviewImage(BaseIcon icon, SoftObjectProperty s) => icon.IconImage = Utils.GetSoftObjectTexture(s);
public static void DrawPreviewImage(SKCanvas c, BaseIcon icon) =>
c.DrawBitmap(icon.IconImage ?? icon.FallbackImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
}
}

View File

@ -0,0 +1,72 @@
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Windows;
namespace FModel.Creator.Icons
{
static class UserFacingFlag
{
public static void GetUserFacingFlags(List<string> uffs, BaseIcon icon, string exportType)
{
if (uffs.Count > 0)
{
PakPackage p = Utils.GetPropertyPakPackage("/Game/Items/ItemCategories"); //PrimaryCategories - SecondaryCategories - TertiaryCategories
if (p.HasExport() && !p.Equals(default))
{
var o = p.GetExport<UObject>();
if (o != null && o.TryGetValue("TertiaryCategories", out var tertiaryCategories) && tertiaryCategories is ArrayProperty tertiaryArray)
{
icon.UserFacingFlags = new SKBitmap[uffs.Count];
for (int i = 0; i < uffs.Count; i++)
{
if (uffs[i].Equals("Cosmetics.UserFacingFlags.HasUpgradeQuests"))
{
if (exportType.Equals("AthenaPetCarrierItemDefinition"))
icon.UserFacingFlags[i] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Pets-64.png")).Stream);
else
icon.UserFacingFlags[i] = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T-Icon-Quests-64.png")).Stream);
}
else
{
foreach (StructProperty structProp in tertiaryArray.Value)
{
if (structProp.Value is UObject mainUObject &&
mainUObject.TryGetValue("TagContainer", out var struc1) && struc1 is StructProperty tagContainer && tagContainer.Value is FGameplayTagContainer f && f.GameplayTags.TryGetGameplayTag(uffs[i], out var _) &&
mainUObject.TryGetValue("CategoryBrush", out var struc2) && struc2 is StructProperty categoryBrush && categoryBrush.Value is UObject categoryUObject &&
categoryUObject.TryGetValue("Brush_XXS", out var struc3) && struc3 is StructProperty brushXXS && brushXXS.Value is UObject brushUObject &&
brushUObject.TryGetValue("ResourceObject", out var object1) && object1 is ObjectProperty resourceObject)
{
icon.UserFacingFlags[i] = Utils.GetObjectTexture(resourceObject);
break;
}
}
}
}
}
}
}
}
public static void DrawUserFacingFlags(SKCanvas c, BaseIcon icon)
{
if (icon.UserFacingFlags != null)
{
int size = 25;
int x = icon.Margin * (int)2.5;
foreach (SKBitmap b in icon.UserFacingFlags)
{
if (b == null)
continue;
c.DrawBitmap(b.Resize(size, size), new SKPoint(x, icon.Margin * (int)2.5), new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
x += size;
}
}
}
}
}

View File

@ -0,0 +1,31 @@
using SkiaSharp;
using System.IO;
namespace FModel.Creator.Icons
{
static class Watermark
{
public static void DrawWatermark(SKCanvas c)
{
if (Properties.Settings.Default.UseIconWatermark && !string.IsNullOrWhiteSpace(Properties.Settings.Default.IconWatermarkPath))
{
using SKBitmap watermarkBase = SKBitmap.Decode(new FileInfo(Properties.Settings.Default.IconWatermarkPath).Open(FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
int sizeX = watermarkBase.Width * (int)Properties.Settings.Default.IconWatermarkScale / 512;
int sizeY = watermarkBase.Height * (int)Properties.Settings.Default.IconWatermarkScale / 512;
SKBitmap watermark = watermarkBase.Resize(sizeX, sizeY);
float left = Properties.Settings.Default.IconWatermarkX;
float top = Properties.Settings.Default.IconWatermarkY;
float right = left + watermark.Width;
float bottom = top + watermark.Height;
c.DrawBitmap(watermark, new SKRect(left, top, right, bottom),
new SKPaint
{
FilterQuality = SKFilterQuality.High,
IsAntialias = true,
Color = SKColors.Transparent.WithAlpha((byte)Properties.Settings.Default.IconWatermarkOpacity)
});
}
}
}
}

View File

@ -0,0 +1,15 @@
namespace FModel.Creator.Rarities
{
public enum EFortRarity : int
{
Common,
Uncommon,
Rare,
Epic,
Legendary,
Mythic,
Transcendent,
Unattainable,
//Impossible
}
}

View File

@ -0,0 +1,171 @@
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System.Linq;
namespace FModel.Creator.Rarities
{
static class Rarity
{
public static void GetInGameRarity(BaseIcon icon, EnumProperty e)
{
PakPackage p = Utils.GetPropertyPakPackage("/Game/Balance/RarityData");
if (p.HasExport() && !p.Equals(default))
{
var d = p.GetExport<UObject>();
if (d != null)
{
EFortRarity rarity = EFortRarity.Uncommon;
switch (e?.Value.String)
{
case "EFortRarity::Common":
rarity = EFortRarity.Common;
break;
case "EFortRarity::Rare":
rarity = EFortRarity.Rare;
break;
case "EFortRarity::Epic":
case "EFortRarity::Quality":
rarity = EFortRarity.Epic;
break;
case "EFortRarity::Legendary":
rarity = EFortRarity.Legendary;
break;
case "EFortRarity::Mythic":
rarity = EFortRarity.Mythic;
break;
case "EFortRarity::Transcendent":
rarity = EFortRarity.Transcendent;
break;
case "EFortRarity::Unattainable":
rarity = EFortRarity.Unattainable;
break;
}
if (d.Values.ElementAt((int)rarity) is StructProperty s && s.Value is UObject colors)
{
if (colors.TryGetValue("Color1", out var c1) && c1 is StructProperty s1 && s1.Value is FLinearColor color1 &&
colors.TryGetValue("Color2", out var c2) && c2 is StructProperty s2 && s2.Value is FLinearColor color2 &&
colors.TryGetValue("Color3", out var c3) && c3 is StructProperty s3 && s3.Value is FLinearColor color3)
{
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse(color1.Hex), SKColor.Parse(color3.Hex) };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse(color2.Hex), SKColor.Parse(color1.Hex) };
}
}
}
}
else GetHardCodedRarity(icon, e);
}
public static void GetHardCodedRarity(BaseIcon icon, EnumProperty e)
{
switch (e?.Value.String)
{
case "EFortRarity::Common":
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("6D6D6D"), SKColor.Parse("333333") };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("9E9E9E"), SKColor.Parse("9E9E9E") };
break;
case "EFortRarity::Rare":
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("3669BB"), SKColor.Parse("133254") };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("5180EE"), SKColor.Parse("5180EE") };
break;
case "EFortRarity::Epic":
case "EFortRarity::Quality":
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("8138C2"), SKColor.Parse("35155C") };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("B251ED"), SKColor.Parse("B251ED") };
break;
case "EFortRarity::Legendary":
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("C06A38"), SKColor.Parse("5C2814") };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("EC9650"), SKColor.Parse("EC9650") };
break;
case "EFortRarity::Mythic":
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("BA9C36"), SKColor.Parse("594415") };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("EED951"), SKColor.Parse("EED951") };
break;
case "EFortRarity::Transcendent":
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse("D51944"), SKColor.Parse("660522") };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse("FF3F58"), SKColor.Parse("FF3F58") };
break;
}
}
public static void DrawRarity(SKCanvas c, BaseIcon icon)
{
// border
c.DrawRect(new SKRect(0, 0, icon.Size, icon.Size),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateLinearGradient(
new SKPoint(icon.Size / 2, icon.Size),
new SKPoint(icon.Size, icon.Size / 4),
icon.RarityBorderColor,
SKShaderTileMode.Clamp)
});
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
{
case EIconDesign.Flat:
{
if (icon.RarityBackgroundImage != null)
c.DrawBitmap(icon.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
else
{
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = icon.RarityBackgroundColors[0]
});
var paint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = icon.RarityBackgroundColors[1].WithAlpha(75)
};
var pathTop = new SKPath { FillType = SKPathFillType.EvenOdd };
pathTop.MoveTo(icon.Margin, icon.Margin);
pathTop.LineTo(icon.Margin + (icon.Size / 17 * 10), icon.Margin);
pathTop.LineTo(icon.Margin, icon.Margin + (icon.Size / 17));
pathTop.Close();
c.DrawPath(pathTop, paint);
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
pathBottom.MoveTo(icon.Margin, icon.Size - icon.Margin);
pathBottom.LineTo(icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 2.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 4.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin);
pathBottom.Close();
c.DrawPath(pathBottom, paint);
}
break;
}
default:
{
if (icon.RarityBackgroundImage != null)
c.DrawBitmap(icon.RarityBackgroundImage, new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
else
c.DrawRect(new SKRect(icon.Margin, icon.Margin, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateRadialGradient(
new SKPoint(icon.Size / 2, icon.Size / 2),
icon.Size / 5 * 4,
icon.RarityBackgroundColors,
SKShaderTileMode.Clamp)
});
break;
}
}
}
}
}

View File

@ -0,0 +1,40 @@
using FModel.Creator.Texts;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
namespace FModel.Creator.Rarities
{
static class Serie
{
public static void GetRarity(BaseIcon icon, ObjectProperty o)
{
PakPackage p = Utils.GetPropertyPakPackage(o.Value.Resource.OuterIndex.Resource.ObjectName.String);
if (p.HasExport() && !p.Equals(default))
{
var obj = p.GetExport<UObject>();
if (obj != null)
GetRarity(icon, obj);
}
}
public static void GetRarity(BaseIcon icon, IUExport export)
{
if (export.TryGetValue("BackgroundTexture", out var t) && t is SoftObjectProperty sop)
icon.RarityBackgroundImage = Utils.GetSoftObjectTexture(sop);
if (export.TryGetValue("Colors", out var v) && v is StructProperty s && s.Value is UObject colors)
{
if (colors.TryGetValue("Color1", out var c1) && c1 is StructProperty s1 && s1.Value is FLinearColor color1 &&
colors.TryGetValue("Color2", out var c2) && c2 is StructProperty s2 && s2.Value is FLinearColor color2 &&
colors.TryGetValue("Color4", out var c4) && c4 is StructProperty s4 && s4.Value is FLinearColor color4)
{
icon.RarityBackgroundColors = new SKColor[2] { SKColor.Parse(color1.Hex), SKColor.Parse(color4.Hex) };
icon.RarityBorderColor = new SKColor[2] { SKColor.Parse(color2.Hex), SKColor.Parse(color1.Hex) };
}
}
}
}
}

View File

@ -0,0 +1,10 @@
using SkiaSharp;
namespace FModel.Creator.Stats
{
public class Statistic
{
public SKBitmap Icon;
public string Description;
}
}

View File

@ -0,0 +1,203 @@
using FModel.Creator.Texts;
using FModel.Utils;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
using System.Windows;
namespace FModel.Creator.Stats
{
static class Statistics
{
public static void GetAmmoData(BaseIcon icon, SoftObjectProperty ammoData)
{
PakPackage p = Utils.GetPropertyPakPackage(ammoData.Value.AssetPathName.String);
if (p.HasExport() && !p.Equals(default))
{
var obj = p.GetExport<UObject>();
if (obj != null)
{
if (obj.TryGetValue("DisplayName", out var v1) && v1 is TextProperty displayName &&
obj.TryGetValue("SmallPreviewImage", out var v2) && v2 is SoftObjectProperty smallPreviewImage)
{
icon.Stats.Add(new Statistic
{
Icon = Utils.GetSoftObjectTexture(smallPreviewImage),
Description = Text.GetTextPropertyBase(displayName).ToUpper()
});
}
}
}
}
public static void GetWeaponStats(BaseIcon icon, StructProperty weaponStatHandle)
{
if (weaponStatHandle.Value is UObject o1 &&
o1.TryGetValue("DataTable", out var c1) && c1 is ObjectProperty dataTable &&
o1.TryGetValue("RowName", out var c2) && c2 is NameProperty rowName)
{
PakPackage p = Utils.GetPropertyPakPackage(dataTable.Value.Resource.OuterIndex.Resource.ObjectName.String);
if (p.HasExport() && !p.Equals(default))
{
var table = p.GetExport<UDataTable>();
if (table != null)
{
if (table.TryGetValue(rowName.Value.String, out var v1) && v1 is UObject stats)
{
if (stats.TryGetValue("ReloadTime", out var s1) && s1 is FloatProperty reloadTime && reloadTime.Value != 0)
icon.Stats.Add(new Statistic
{
Icon = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_ReloadTime_Weapon_Stats.png")).Stream),
Description = $"{Localizations.GetLocalization(string.Empty, "6EA26D1A4252034FBD869A90F9A6E49A", "Reload Time")} ({Localizations.GetLocalization(string.Empty, "6BA53D764BA5CC13E821D2A807A72365", "seconds")}) : {reloadTime.Value:0.0}".ToUpper()
});
if (stats.TryGetValue("ClipSize", out var s2) && s2 is IntProperty clipSize && clipSize.Value != 0)
icon.Stats.Add(new Statistic
{
Icon = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_ClipSize_Weapon_Stats.png")).Stream),
Description = $"{Localizations.GetLocalization(string.Empty, "068239DD4327B36124498C9C5F61C038", "Magazine Size")} : {clipSize.Value}".ToUpper()
});
if (stats.TryGetValue("DmgPB", out var s3) && s3 is FloatProperty dmgPB && dmgPB.Value != 0)
icon.Stats.Add(new Statistic
{
Icon = SKBitmap.Decode(Application.GetResourceStream(new Uri("pack://application:,,,/Resources/T_DamagePerBullet_Weapon_Stats.png")).Stream),
Description = $"{Localizations.GetLocalization(string.Empty, "BF7E3CF34A9ACFF52E95EAAD4F09F133", "Damage to Player")} : {dmgPB.Value}".ToUpper()
});
}
}
}
}
}
public static void GetHeroStats(BaseIcon icon, ObjectProperty heroGameplayDefinition)
{
PakPackage p = Utils.GetPropertyPakPackage(heroGameplayDefinition.Value.Resource.OuterIndex.Resource.ObjectName.String);
if (p.HasExport() && !p.Equals(default))
{
var obj = p.GetExport<UObject>();
if (obj != null)
{
if (obj.TryGetValue("HeroPerk", out var v1) && v1 is StructProperty s1 && s1.Value is UObject heroPerk)
{
GetAbilityKit(icon, heroPerk);
}
if (obj.TryGetValue("TierAbilityKits", out var v2) && v2 is ArrayProperty tierAbilityKits)
{
foreach (StructProperty abilityKit in tierAbilityKits.Value)
{
if (abilityKit.Value is UObject kit)
{
GetAbilityKit(icon, kit);
}
}
}
}
}
}
private static void GetAbilityKit(BaseIcon icon, UObject parent)
{
if (parent.TryGetValue("GrantedAbilityKit", out var v) && v is SoftObjectProperty grantedAbilityKit)
{
PakPackage k = Utils.GetPropertyPakPackage(grantedAbilityKit.Value.AssetPathName.String);
if (k.HasExport() && !k.Equals(default))
{
var kit = k.GetExport<UObject>();
if (kit != null &&
kit.GetExport<TextProperty>("DisplayName") is TextProperty displayName &&
kit.GetExport<StructProperty>("IconBrush") is StructProperty brush && brush.Value is UObject iconBrush &&
iconBrush.TryGetValue("ResourceObject", out var s) && s is ObjectProperty resourceObject)
{
icon.Stats.Add(new Statistic
{
Icon = Utils.GetObjectTexture(resourceObject),
Description = Text.GetTextPropertyBase(displayName).ToUpper()
});
}
}
}
}
public static void DrawStats(SKCanvas c, BaseIcon icon)
{
int size = 48;
int iconSize = 40;
int textSize = 25;
int y = icon.Size;
foreach (Statistic stat in icon.Stats)
{
c.DrawRect(new SKRect(0, y, icon.Size, y + size),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateLinearGradient(
new SKPoint(icon.Size / 2, icon.Size),
new SKPoint(icon.Size, icon.Size / 4),
icon.RarityBorderColor,
SKShaderTileMode.Clamp)
});
if ((EIconDesign)Properties.Settings.Default.AssetsIconDesign == EIconDesign.Flat)
{
c.DrawRect(new SKRect(icon.Margin, y, icon.Size - icon.Margin, y + size - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = icon.RarityBackgroundColors[0]
});
}
else
{
c.DrawRect(new SKRect(icon.Margin, y, icon.Size - icon.Margin, y + size - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Shader = SKShader.CreateRadialGradient(
new SKPoint(icon.Size / 2, icon.Size / 2),
icon.Size / 5 * 4,
icon.RarityBackgroundColors,
SKShaderTileMode.Clamp)
});
}
c.DrawRect(new SKRect(icon.Margin, y, icon.Size - icon.Margin, y + size - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = new SKColor(0, 0, 50, 75)
});
c.DrawBitmap(stat.Icon.Resize(iconSize, iconSize), new SKPoint(icon.Margin * (int)2.5, y + 4), new SKPaint { FilterQuality = SKFilterQuality.High, IsAntialias = true });
var statPaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = Text.TypeFaces.DisplayNameTypeface,
TextSize = textSize,
Color = SKColors.White,
TextAlign = SKTextAlign.Center,
};
// resize if too long
while (statPaint.MeasureText(stat.Description) > (icon.Size - (icon.Margin * 2) - iconSize))
{
statPaint.TextSize = textSize -= 2;
}
c.DrawText(stat.Description, icon.Size / 2, y + 32, statPaint);
y += size;
}
}
}
}

View File

@ -0,0 +1,9 @@
namespace FModel.Creator.Texts
{
public enum ETextSide
{
Center,
Right,
Left
}
}

View File

@ -0,0 +1,72 @@
using FModel.Creator.Icons;
using FModel.Utils;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
namespace FModel.Creator.Texts
{
static class GameplayTag
{
public static void GetGameplayTags(BaseIcon icon, StructProperty s, string exportType)
{
if (s.Value is FGameplayTagContainer g)
{
if (g.GameplayTags.TryGetGameplayTag("Cosmetics.Source.", out var source))
icon.CosmeticSource = source.String.Substring("Cosmetics.Source.".Length);
else if(g.GameplayTags.TryGetGameplayTag("Athena.ItemAction.", out var action))
icon.CosmeticSource = action.String.Substring("Athena.ItemAction.".Length);
if (g.GameplayTags.TryGetGameplayTag("Cosmetics.Set.", out var set))
icon.Description += GetCosmeticSet(set.String);
if (g.GameplayTags.TryGetGameplayTag("Cosmetics.Filter.Season.", out var season))
icon.Description += GetCosmeticSeason(season.String);
UserFacingFlag.GetUserFacingFlags(
g.GameplayTags.GetAllGameplayTag("Cosmetics.UserFacingFlags.", "Homebase.Class.", "NPC.CharacterType.Survivor.Defender."),
icon, exportType);
}
}
private static string GetCosmeticSet(string setName)
{
PakPackage p = Utils.GetPropertyPakPackage("/Game/Athena/Items/Cosmetics/Metadata/CosmeticSets");
if (p.HasExport() && !p.Equals(default))
{
var d = p.GetExport<UDataTable>();
if (d != null && d.TryGetValue(setName, out var obj) && obj is UObject o)
{
if (o.TryGetValue("DisplayName", out var displayName) && displayName is TextProperty t)
{
(string n, string k, string s) = Text.GetTextPropertyBases(t);
string set = Localizations.GetLocalization(n, k, s);
string format = Localizations.GetLocalization("Fort.Cosmetics", "CosmeticItemDescription_SetMembership_NotRich", "\nPart of the {0} set.");
return string.Format(format, set);
}
}
}
return string.Empty;
}
private static string GetCosmeticSeason(string seasonNumber)
{
string s = seasonNumber.Substring("Cosmetics.Filter.Season.".Length);
int number = int.Parse(s);
if (number == 10)
s = "X";
string season = Localizations.GetLocalization("AthenaSeasonItemDefinitionInternal", "SeasonTextFormat", "Season {0}");
string introduced = Localizations.GetLocalization("Fort.Cosmetics", "CosmeticItemDescription_Season", "\nIntroduced in <SeasonText>{0}</>.")
.Replace("<SeasonText>", string.Empty).Replace("</>", string.Empty);
if (number > 10)
{
string chapter = Localizations.GetLocalization("AthenaSeasonItemDefinitionInternal", "ChapterTextFormat", "Chapter {0}");
string chapterFormat = Localizations.GetLocalization("AthenaSeasonItemDefinitionInternal", "ChapterSeasonTextFormat", "{0}, {1}");
string d = string.Format(chapterFormat, string.Format(chapter, number / 10 + 1), string.Format(season, s[^1..]));
return string.Format(introduced, d);
}
else return string.Format(introduced, string.Format(season, s));
}
}
}

View File

@ -0,0 +1,110 @@
using SkiaSharp;
using System;
using System.Collections.Generic;
using System.Text;
namespace FModel.Creator.Texts
{
static class Helper
{
public class Line
{
public string Value { get; set; }
public float Width { get; set; }
}
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, BaseIcon icon, ETextSide side, SKRect area, SKPaint paint)
=> DrawCenteredMultilineText(canvas, text, maxLineCount, icon.Size, icon.Margin, side, area, paint);
public static void DrawCenteredMultilineText(SKCanvas canvas, string text, int maxLineCount, int size, int margin, ETextSide side, SKRect area, SKPaint paint)
{
float lineHeight = paint.TextSize * 1.2f;
Line[] lines = SplitLines(text, paint, area.Width - margin);
if (lines == null)
return;
if (lines.Length <= maxLineCount)
maxLineCount = lines.Length;
float height = maxLineCount * lineHeight;
float y = area.MidY - height / 2;
for (int i = 0; i < maxLineCount; i++)
{
y += lineHeight;
float x = side switch
{
ETextSide.Center => area.MidX - lines[i].Width / 2,
ETextSide.Right => size - margin - lines[i].Width,
ETextSide.Left => margin,
_ => area.MidX - lines[i].Width / 2
};
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);
}
}
public static void DrawMultilineText(SKCanvas canvas, string text, int size, int margin, ETextSide side, SKRect area, SKPaint paint, out int yPos)
{
float lineHeight = paint.TextSize * 1.2f;
Line[] lines = SplitLines(text, paint, area.Width - margin);
if (lines == null)
{
yPos = (int)area.Top;
return;
}
float y = area.Top;
for (int i = 0; i < lines.Length; i++)
{
float x = side switch
{
ETextSide.Center => area.MidX - lines[i].Width / 2,
ETextSide.Right => size - margin - lines[i].Width,
ETextSide.Left => margin,
_ => area.MidX - lines[i].Width / 2
};
canvas.DrawText(lines[i].Value.TrimEnd(), x, y, paint);
y += lineHeight;
}
yPos = (int)area.Top + ((int)lineHeight * lines.Length);
}
public static Line[] SplitLines(string text, SKPaint paint, float maxWidth)
{
if (string.IsNullOrEmpty(text))
return null;
float spaceWidth = paint.MeasureText(" ");
string[] lines = text.Split('\n', StringSplitOptions.RemoveEmptyEntries);
List<Line> ret = new List<Line>(lines.Length);
for (int i = 0; i < lines.Length; i++)
{
if (string.IsNullOrWhiteSpace(lines[i]))
continue;
float width = 0;
var lineResult = new StringBuilder();
string[] words = lines[i].Split(' ', StringSplitOptions.None);
foreach (var word in words)
{
float wordWidth = paint.MeasureText(word);
float wordWithSpaceWidth = wordWidth + spaceWidth;
string wordWithSpace = word + " ";
if (width + wordWidth > maxWidth)
{
ret.Add(new Line { Value = lineResult.ToString(), Width = width });
lineResult = new StringBuilder(wordWithSpace);
width = wordWithSpaceWidth;
}
else
{
lineResult.Append(wordWithSpace);
width += wordWithSpaceWidth;
}
}
ret.Add(new Line { Value = lineResult.ToString(), Width = width });
}
return ret.ToArray();
}
}
}

View File

@ -0,0 +1,217 @@
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.Objects;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System.Collections.Generic;
namespace FModel.Creator.Texts
{
static class Text
{
public static Typefaces TypeFaces = new Typefaces();
private const int _STARTER_TEXT_POSITION = 380;
private static int _BOTTOM_TEXT_SIZE = 15;
private static int _NAME_TEXT_SIZE = 45;
public static string GetTextPropertyBase(TextProperty t)
{
if (t.Value is FText text)
if (text.Text is FTextHistory.Base b)
return b.SourceString.Replace("<Emphasized>", string.Empty).Replace("</>", string.Empty);
else if (text.Text is FTextHistory.StringTableEntry s)
{
PakPackage p = Utils.GetPropertyPakPackage(s.TableId.String);
if (p.HasExport() && !p.Equals(default))
{
var table = p.GetExport<UStringTable>();
if (table != null)
{
if (table.TryGetValue("StringTable", out var v1) && v1 is FStringTable stringTable &&
stringTable.KeysToMetadata.TryGetValue(stringTable.TableNamespace, out var v2) && v2 is Dictionary<string, string> dico &&
dico.TryGetValue(s.Key, out var ret))
{
return ret;
}
}
}
}
return string.Empty;
}
public static string GetTextPropertyBase(ArrayProperty a)
{
if (a.Value.Length > 0 && a.Value[0] is TextProperty t)
return GetTextPropertyBase(t);
return string.Empty;
}
public static (string, string, string) GetTextPropertyBases(TextProperty t)
{
if (t.Value is FText text && text.Text is FTextHistory.Base b)
return (b.Namespace, b.Key, b.SourceString);
return (string.Empty, string.Empty, string.Empty);
}
public static string GetMaxStackSize(StructProperty maxStackSize)
{
if (maxStackSize.Value is UObject o1)
{
if (o1.TryGetValue("Value", out var c) && c is FloatProperty value && value.Value != -1) // old way
return $"MaxStackSize : {value.Value}";
else if (
o1.TryGetValue("Curve", out var c1) && c1 is StructProperty curve && curve.Value is UObject o2 &&
o2.TryGetValue("CurveTable", out var c2) && c2 is ObjectProperty curveTable &&
o2.TryGetValue("RowName", out var c3) && c3 is NameProperty rowName) // new way
{
PakPackage p = Utils.GetPropertyPakPackage(curveTable.Value.Resource.OuterIndex.Resource.ObjectName.String);
if (p.HasExport() && !p.Equals(default))
{
var table = p.GetExport<UCurveTable>();
if (table != null)
{
if (table.TryGetValue(rowName.Value.String, out var v1) && v1 is UObject maxStackAmount &&
maxStackAmount.TryGetValue("Keys", out var v2) && v2 is ArrayProperty keys &&
keys.Value.Length > 0 && (keys.Value[0] as StructProperty).Value is FSimpleCurveKey amount &&
amount.KeyValue != -1)
{
return $"MaxStackSize : {amount.KeyValue}";
}
}
}
}
}
return string.Empty;
}
public static void DrawBackground(SKCanvas c, BaseIcon icon)
{
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
{
case EIconDesign.Flat:
{
var pathBottom = new SKPath { FillType = SKPathFillType.EvenOdd };
pathBottom.MoveTo(icon.Margin, icon.Size - icon.Margin);
pathBottom.LineTo(icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 2.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin - (icon.Size / 17 * 4.5f));
pathBottom.LineTo(icon.Size - icon.Margin, icon.Size - icon.Margin);
pathBottom.Close();
c.DrawPath(pathBottom, new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = new SKColor(0, 0, 50, 75),
});
break;
}
default:
{
c.DrawRect(
new SKRect(icon.Margin, _STARTER_TEXT_POSITION, icon.Size - icon.Margin, icon.Size - icon.Margin),
new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Color = new SKColor(0, 0, 50, 75),
});
break;
}
}
}
public static void DrawDisplayName(SKCanvas c, BaseIcon icon)
{
_NAME_TEXT_SIZE = 45;
string text = icon.DisplayName;
SKTextAlign side = SKTextAlign.Center;
int x = icon.Size / 2;
int y = _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE;
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
{
case EIconDesign.Mini:
{
_NAME_TEXT_SIZE = 47;
text = text.ToUpper();
break;
}
case EIconDesign.Flat:
{
_NAME_TEXT_SIZE = 47;
side = SKTextAlign.Right;
x = icon.Size - icon.Margin * 2;
break;
}
}
SKPaint namePaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = TypeFaces.DisplayNameTypeface,
TextSize = _NAME_TEXT_SIZE,
Color = SKColors.White,
TextAlign = side,
};
// resize if too long
while (namePaint.MeasureText(text) > (icon.Size - (icon.Margin * 2)))
{
namePaint.TextSize = _NAME_TEXT_SIZE -= 2;
}
c.DrawText(text, x, y, namePaint);
}
public static void DrawDescription(SKCanvas c, BaseIcon icon)
{
int maxLine = 4;
_BOTTOM_TEXT_SIZE = 15;
string text = icon.Description;
ETextSide side = ETextSide.Center;
switch ((EIconDesign)Properties.Settings.Default.AssetsIconDesign)
{
case EIconDesign.Mini:
{
maxLine = 5;
_BOTTOM_TEXT_SIZE = icon.Margin;
text = text.ToUpper();
break;
}
case EIconDesign.Flat:
{
side = ETextSide.Right;
break;
}
}
SKPaint descriptionPaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = TypeFaces.DescriptionTypeface,
TextSize = 13,
Color = SKColors.White,
};
// wrap if too long
Helper.DrawCenteredMultilineText(c, text, maxLine, icon, side,
new SKRect(icon.Margin, _STARTER_TEXT_POSITION + _NAME_TEXT_SIZE, icon.Size - icon.Margin, icon.Size - _BOTTOM_TEXT_SIZE),
descriptionPaint);
}
public static void DrawToBottom(SKCanvas c, BaseIcon icon, ETextSide side, string text)
{
SKPaint shortDescriptionPaint = new SKPaint
{
IsAntialias = true,
FilterQuality = SKFilterQuality.High,
Typeface = side == ETextSide.Left ? TypeFaces.DisplayNameTypeface : TypeFaces.DefaultTypeface,
TextSize = 15,
Color = SKColors.White,
TextAlign = side == ETextSide.Left ? SKTextAlign.Left : SKTextAlign.Right,
};
c.DrawText(text, side == ETextSide.Left ? icon.Margin * 2.5f : icon.Size - (icon.Margin * 2.5f), icon.Size - (icon.Margin * 2.5f), shortDescriptionPaint);
}
}
}

View File

@ -0,0 +1,105 @@
using FModel.Utils;
using FModel.ViewModels.DataGrid;
using SkiaSharp;
using System;
using System.Windows;
namespace FModel.Creator.Texts
{
public class Typefaces
{
#pragma warning disable IDE0051
private const string _BASE_PATH = "/Game/UI/Foundation/Fonts/";
private const string _ASIA_ERINM = "AsiaERINM"; // korean fortnite
private const string _BURBANK_BIG_CONDENSED_BLACK = "BurbankBigCondensed-Black";
private readonly Uri _BURBANK_BIG_CONDENSED_BOLD = new Uri("pack://application:,,,/Resources/BurbankBigCondensed-Bold.ttf"); // other languages fortnite unofficial
private const string _BURBANK_BIG_REGULAR_BLACK = "BurbankBigRegular-Black";
private const string _BURBANK_BIG_REGULAR_BOLD = "BurbankBigRegular-Bold"; // official fortnite but it's too big so i use it for russian only
private const string _BURBANK_SMALL_MEDIUM = "BurbankSmall-Medium";
private const string _DROID_SANS_FORTNITE_SUBSET = "DroidSans-Fortnite-Subset";
private const string _NIS_JYAU = "NIS_JYAU"; // japanese fortnite
private const string _NOTO_COLOR_EMOJI = "NotoColorEmoji";
private const string _NOTO_SANS_BOLD = "NotoSans-Bold";
private const string _NOTO_SANS_FORTNITE_BOLD = "NotoSans-Fortnite-Bold";
private const string _NOTO_SANS_FORTNITE_ITALIC = "NotoSans-Fortnite-Italic";
private const string _NOTO_SANS_FORTNITE_REGULAR = "NotoSans-Fortnite-Regular";
private const string _NOTO_SANS_ITALIC = "NotoSans-Italic";
private const string _NOTO_SANS_REGULAR = "NotoSans-Regular";
private const string _NOTO_SANS_ARABIC_BLACK = "NotoSansArabic-Black"; // arabic fortnite
private const string _NOTO_SANS_ARABIC_BOLD = "NotoSansArabic-Bold";
private const string _NOTO_SANS_ARABIC_REGULAR = "NotoSansArabic-Regular";
private const string _NOTO_SANS_JP_BOLD = "NotoSansJP-Bold";
private const string _NOTO_SANS_KR_REGULAR = "NotoSansKR-Regular";
private const string _NOTO_SANS_SC_BLACK = "NotoSansSC-Black"; // traditional chinese fortnite
private const string _NOTO_SANS_SC_REGULAR = "NotoSansSC-Regular";
private const string _NOTO_SANS_TC_BLACK = "NotoSansTC-Black"; // simplified chinese fortnite
private const string _NOTO_SANS_TC_REGULAR = "NotoSansTC-Regular";
private const string _BURBANK_SMALL_BLACK = "burbanksmall-black";
private const string _BURBANK_SMALL_BOLD = "burbanksmall-bold";
#pragma warning restore IDE0051
public SKTypeface DefaultTypeface; // used as default font for all untranslated strings (item source, ...)
public SKTypeface BundleDefaultTypeface; // used for the last folder string
public SKTypeface DisplayNameTypeface;
public SKTypeface DescriptionTypeface;
public SKTypeface BundleDisplayNameTypeface;
public Typefaces()
{
DefaultTypeface = SKTypeface.FromStream(Application.GetResourceStream(_BURBANK_BIG_CONDENSED_BOLD).Stream);
ArraySegment<byte>[] t = Utils.GetPropertyArraySegmentByte(_BASE_PATH + _BURBANK_BIG_CONDENSED_BLACK);
if (t != null && t.Length == 3)
BundleDefaultTypeface = SKTypeface.FromStream(t[2].AsStream());
else BundleDefaultTypeface = DefaultTypeface;
string namePath = _BASE_PATH + (
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_REGULAR_BOLD :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_SC_BLACK :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_TC_BLACK :
string.Empty);
if (!namePath.Equals(_BASE_PATH))
{
t = Utils.GetPropertyArraySegmentByte(namePath);
if (t != null && t.Length == 3)
DisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
}
else DisplayNameTypeface = DefaultTypeface;
string descriptionPath = _BASE_PATH + (
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _NOTO_SANS_KR_REGULAR :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NOTO_SANS_JP_BOLD :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_REGULAR :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_SC_REGULAR :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_TC_REGULAR :
_NOTO_SANS_REGULAR);
t = Utils.GetPropertyArraySegmentByte(descriptionPath);
if (t != null && t.Length == 3)
DescriptionTypeface = SKTypeface.FromStream(t[2].AsStream());
else DescriptionTypeface = DefaultTypeface;
string bundleNamePath = _BASE_PATH + (
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Korean ? _ASIA_ERINM :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Russian ? _BURBANK_BIG_REGULAR_BOLD :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Japanese ? _NIS_JYAU :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Arabic ? _NOTO_SANS_ARABIC_BLACK :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.TraditionalChinese ? _NOTO_SANS_SC_BLACK :
Properties.Settings.Default.AssetsLanguage == (long)ELanguage.Chinese ? _NOTO_SANS_TC_BLACK :
string.Empty);
if (!bundleNamePath.Equals(_BASE_PATH))
{
t = Utils.GetPropertyArraySegmentByte(bundleNamePath);
if (t != null && t.Length == 3)
BundleDisplayNameTypeface = SKTypeface.FromStream(t[2].AsStream());
}
else BundleDisplayNameTypeface = BundleDefaultTypeface;
}
public bool NeedReload(bool forceReload) => forceReload ?
DataGridVm.dataGridViewModel.Count > 0 : //reload only if at least one pak is loaded
DataGridVm.dataGridViewModel.Count > 0 && (BundleDefaultTypeface == DefaultTypeface && DisplayNameTypeface == DefaultTypeface && DescriptionTypeface == DefaultTypeface && BundleDisplayNameTypeface == BundleDefaultTypeface);
}
}

78
FModel/Creator/Utils.cs Normal file
View File

@ -0,0 +1,78 @@
using FModel.Utils;
using PakReader.Pak;
using PakReader.Parsers.Class;
using PakReader.Parsers.PropertyTagData;
using SkiaSharp;
using System;
namespace FModel.Creator
{
static class Utils
{
public static string GetFullPath(string partialPath)
{
foreach (var fileReader in Globals.CachedPakFiles.Values)
if (fileReader.TryGetPartialKey(partialPath, out var fullPath))
{
return fullPath;
}
return string.Empty;
}
public static PakPackage GetPropertyPakPackage(string value)
{
string path = Strings.FixPath(value);
foreach (var fileReader in Globals.CachedPakFiles.Values)
if (fileReader.TryGetValue(path, out var entry))
{
// kinda sad to use Globals.CachedPakFileMountPoint when the mount point is already in the path ¯\_(ツ)_/¯
string mount = path.Substring(0, path.Length - entry.Name.Substring(0, entry.Name.LastIndexOf(".")).Length);
return Assets.GetPakPackage(entry, mount);
}
return default;
}
public static ArraySegment<byte>[] GetPropertyArraySegmentByte(string value)
{
string path = Strings.FixPath(value);
foreach (var fileReader in Globals.CachedPakFiles.Values)
if (fileReader.TryGetValue(path, out var entry))
{
// kinda sad to use Globals.CachedPakFileMountPoint when the mount point is already in the path ¯\_(ツ)_/¯
string mount = path.Substring(0, path.Length - entry.Name.Substring(0, entry.Name.LastIndexOf(".")).Length);
return Assets.GetArraySegmentByte(entry, mount);
}
return default;
}
public static SKBitmap NewZeroedBitmap(int width, int height) => new SKBitmap(new SKImageInfo(width, height), SKBitmapAllocFlags.ZeroPixels);
public static SKBitmap Resize(this SKBitmap me, int width, int height)
{
var bmp = NewZeroedBitmap(width, height);
using var pixmap = bmp.PeekPixels();
me.ScalePixels(pixmap, SKFilterQuality.Medium);
return bmp;
}
public static SKBitmap GetObjectTexture(ObjectProperty o) => GetTexture(o.Value.Resource.OuterIndex.Resource.ObjectName.String);
public static SKBitmap GetSoftObjectTexture(SoftObjectProperty s) => GetTexture(s.Value.AssetPathName.String);
public static SKBitmap GetTexture(string s)
{
PakPackage p = GetPropertyPakPackage(s);
if (p.HasExport() && !p.Equals(default))
{
var i = p.GetExport<UTexture2D>();
if (i != null)
return SKBitmap.Decode(i.Image.Encode());
var u = p.GetExport<UObject>();
if (u != null)
if (u.TryGetValue("TextureParameterValues", out var v) && v is ArrayProperty a)
if (a.Value.Length > 0 && a.Value[0] is StructProperty str && str.Value is UObject o)
if (o.TryGetValue("ParameterValue", out var obj) && obj is ObjectProperty parameterValue)
return GetObjectTexture(parameterValue);
}
return null;
}
}
}

View File

@ -0,0 +1,66 @@
using DiscordRPC;
using DiscordRPC.Logging;
using FModel.Logger;
using System;
using System.Reflection;
namespace FModel.Discord
{
static class DiscordIntegration
{
private const string _DISCORD_APP_ID = "684489366189768767";
private static readonly Timestamps _baseTimestamp = new Timestamps { Start = DateTime.UtcNow };
private static readonly Assets _assets = new Assets
{
LargeImageKey = "official_logo",
SmallImageKey = "verified",
SmallImageText = $"v{Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 5)}"
};
private static readonly DiscordRpcClient _client = new DiscordRpcClient(_DISCORD_APP_ID);
private static RichPresence _presence;
public static void Dispose() => _client.Dispose();
private static void Initialize()
{
_client.Logger = new ConsoleLogger() { Level = LogLevel.Warning };
_client.OnReady += (sender, e) =>
{
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Discord RPC]", $"Ready for {e.User.Username}#{e.User.Discriminator} ({e.User.ID})");
};
_client.Initialize();
}
public static void StartClient()
{
_client.SetPresence(new RichPresence
{
Assets = _assets,
Timestamps = _baseTimestamp,
State = Properties.Resources.Idling
});
Initialize();
SaveCurrentPresence();
}
public static void Update(string detail = null, string state = null)
{
_client.SetPresence(new RichPresence
{
Assets = _assets,
Timestamps = _baseTimestamp,
Details = string.IsNullOrEmpty(detail) ? _presence.Details : detail,
State = string.IsNullOrEmpty(state) ? _presence.State : state
});
_client.Invoke();
}
public static void Restore()
{
_client.SetPresence(_presence);
_client.Invoke();
}
public static void SaveCurrentPresence() => _presence = _client.CurrentPresence;
}
}

60
FModel/Enums.cs Normal file
View File

@ -0,0 +1,60 @@
namespace FModel
{
public enum EGame
{
Unknown,
Fortnite,
Valorant
}
public enum EFModel
{
Debug,
Release,
Unknown
}
public enum EPakLoader
{
Single,
All,
New,
Modified,
NewModified
}
public enum ECopy
{
Path,
PathNoExt,
File,
FileNoExt
}
public enum ELanguage : long
{
English,
French,
German,
Italian,
Spanish,
SpanishLatin,
Arabic,
Japanese,
Korean,
Polish,
PortugueseBrazil,
Russian,
Turkish,
Chinese,
TraditionalChinese
}
public enum EIconDesign : long
{
Default,
NoText,
Mini,
Flat
}
}

View File

@ -1,634 +1,236 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk.WindowsDesktop">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{8AAB27BD-18D7-4164-8BBC-AB534D55D30F}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>FModel</RootNamespace>
<AssemblyName>FModel</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<WarningLevel>4</WarningLevel>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
<TargetFrameworkProfile />
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<IsWebBootstrapper>false</IsWebBootstrapper>
<PublishUrl>publish\</PublishUrl>
<Install>true</Install>
<InstallFrom>Disk</InstallFrom>
<UpdateEnabled>false</UpdateEnabled>
<UpdateMode>Foreground</UpdateMode>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>Days</UpdateIntervalUnits>
<UpdatePeriodically>false</UpdatePeriodically>
<UpdateRequired>false</UpdateRequired>
<MapFileExtensions>true</MapFileExtensions>
<ApplicationRevision>0</ApplicationRevision>
<ApplicationVersion>1.0.0.%2a</ApplicationVersion>
<UseApplicationTrust>false</UseApplicationTrust>
<BootstrapperEnabled>true</BootstrapperEnabled>
<TargetFramework>netcoreapp3.1</TargetFramework>
<UseWPF>true</UseWPF>
<ApplicationIcon>FModel.ico</ApplicationIcon>
<StartupObject>FModel.App</StartupObject>
<Authors>Asval</Authors>
<Company></Company>
<AssemblyVersion>3.1.0.0</AssemblyVersion>
<FileVersion>3.1.0.0</FileVersion>
<PackageIcon>FModel.ico</PackageIcon>
<PackageIconUrl />
<PackageProjectUrl>https://github.com/iAmAsval/FModel</PackageProjectUrl>
<Description></Description>
<Version>3.1.0</Version>
<Platforms>x64</Platforms>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<PlatformTarget>x64</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<LangVersion>7.1</LangVersion>
<NoWarn>1701;1702;NU1701</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<PlatformTarget>x64</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Prefer32Bit>false</Prefer32Bit>
<LangVersion>7.1</LangVersion>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>Logo.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup>
<StartupObject>FModel.Program</StartupObject>
<NoWarn>1701;1702;NU1701</NoWarn>
</PropertyGroup>
<ItemGroup>
<Reference Include="AutoUpdater.NET, Version=1.5.8.0, Culture=neutral, PublicKeyToken=501435c91b35f4bc, processorArchitecture=MSIL">
<HintPath>..\packages\Autoupdater.NET.Official.1.5.8\lib\net40\AutoUpdater.NET.dll</HintPath>
</Reference>
<Reference Include="HtmlAgilityPack, Version=1.11.17.0, Culture=neutral, PublicKeyToken=bd319b19eaf3b43a, processorArchitecture=MSIL">
<HintPath>..\packages\HtmlAgilityPack.1.11.17\lib\Net45\HtmlAgilityPack.dll</HintPath>
</Reference>
<Reference Include="ICSharpCode.AvalonEdit, Version=6.0.0.0, Culture=neutral, PublicKeyToken=9cc39be672370310, processorArchitecture=MSIL">
<HintPath>..\packages\AvalonEdit.6.0.0\lib\net45\ICSharpCode.AvalonEdit.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=12.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.12.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Ookii.Dialogs.Wpf, Version=1.0.0.0, Culture=neutral, PublicKeyToken=66aa232afad40158, processorArchitecture=MSIL">
<HintPath>..\packages\Ookii.Dialogs.Wpf.1.1.0\lib\net45\Ookii.Dialogs.Wpf.dll</HintPath>
</Reference>
<Reference Include="RestSharp, Version=106.6.10.0, Culture=neutral, PublicKeyToken=598062e77f915f75, processorArchitecture=MSIL">
<HintPath>..\packages\RestSharp.106.6.10\lib\net452\RestSharp.dll</HintPath>
</Reference>
<Reference Include="SkiaSharp, Version=1.68.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756, processorArchitecture=MSIL">
<HintPath>..\packages\SkiaSharp.1.68.1\lib\net45\SkiaSharp.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Buffers, Version=4.0.3.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Buffers.4.5.0\lib\netstandard2.0\System.Buffers.dll</HintPath>
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Design" />
<Reference Include="System.Drawing" />
<Reference Include="System.Memory, Version=4.0.1.1, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\packages\System.Memory.4.5.3\lib\netstandard2.0\System.Memory.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Numerics.Vectors, Version=4.1.5.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Numerics.Vectors.4.6.0-preview5.19224.8\lib\net46\System.Numerics.Vectors.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.CompilerServices.Unsafe, Version=4.0.6.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\packages\System.Runtime.CompilerServices.Unsafe.4.7.0\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll</HintPath>
</Reference>
<Reference Include="System.Security" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xaml">
<RequiredTargetFramework>4.0</RequiredTargetFramework>
</Reference>
<Reference Include="WindowsBase" />
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="WriteableBitmapEx.Wpf, Version=1.6.3.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\WriteableBitmapEx.1.6.3\lib\net40\WriteableBitmapEx.Wpf.dll</HintPath>
</Reference>
<None Remove="FModel.ico" />
<None Remove="Resources\alert.ico" />
<None Remove="Resources\alpha-a-box.png" />
<None Remove="Resources\api-off.ico" />
<None Remove="Resources\api.ico" />
<None Remove="Resources\backup-restore.png" />
<None Remove="Resources\bug.png" />
<None Remove="Resources\BurbankBigCondensed-Bold.ttf" />
<None Remove="Resources\cast-audio.png" />
<None Remove="Resources\challenge-theme-creator.png" />
<None Remove="Resources\check-circle.ico" />
<None Remove="Resources\ColorPickerOne.png" />
<None Remove="Resources\ColorPickerTwo.png" />
<None Remove="Resources\content-copy.png" />
<None Remove="Resources\content-save.png" />
<None Remove="Resources\delete-forever.png" />
<None Remove="Resources\discord.png" />
<None Remove="Resources\egl2.ico" />
<None Remove="Resources\EIconDesign_Default.png" />
<None Remove="Resources\EIconDesign_Flat.png" />
<None Remove="Resources\EIconDesign_Mini.png" />
<None Remove="Resources\EIconDesign_NoText.png" />
<None Remove="Resources\file-export.png" />
<None Remove="Resources\file-image.ico" />
<None Remove="Resources\file-multiple.png" />
<None Remove="Resources\file-restore.png" />
<None Remove="Resources\file.png" />
<None Remove="Resources\fmodel.png" />
<None Remove="Resources\folder-download.png" />
<None Remove="Resources\folder-open.png" />
<None Remove="Resources\fortnite.ico" />
<None Remove="Resources\gamepad-variant.png" />
<None Remove="Resources\github-circle.png" />
<None Remove="Resources\icon-creator.png" />
<None Remove="Resources\image-filter-black-white.png" />
<None Remove="Resources\image-move.png" />
<None Remove="Resources\image-plus.png" />
<None Remove="Resources\image-remove.png" />
<None Remove="Resources\information.png" />
<None Remove="Resources\Ini.xshd" />
<None Remove="Resources\Json.xshd" />
<None Remove="Resources\key.png" />
<None Remove="Resources\lock-open-variant.ico" />
<None Remove="Resources\magnify.png" />
<None Remove="Resources\open-in-new.png" />
<None Remove="Resources\pause.png" />
<None Remove="Resources\paypal.png" />
<None Remove="Resources\pencil.png" />
<None Remove="Resources\play.png" />
<None Remove="Resources\playlist-plus.png" />
<None Remove="Resources\power.png" />
<None Remove="Resources\progress-download.png" />
<None Remove="Resources\refresh.png" />
<None Remove="Resources\settings.png" />
<None Remove="Resources\share-all.png" />
<None Remove="Resources\share.png" />
<None Remove="Resources\sign-direction-plus.png" />
<None Remove="Resources\sign-direction-remove.png" />
<None Remove="Resources\sign-direction.png" />
<None Remove="Resources\stop.png" />
<None Remove="Resources\T-Icon-Pets-64.png" />
<None Remove="Resources\T-Icon-Quests-64.png" />
<None Remove="Resources\T_ClipSize_Weapon_Stats.png" />
<None Remove="Resources\T_DamagePerBullet_Weapon_Stats.png" />
<None Remove="Resources\T_Placeholder_Challenge_Image.png" />
<None Remove="Resources\T_Placeholder_Item_Image.png" />
<None Remove="Resources\T_ReloadTime_Weapon_Stats.png" />
<None Remove="Resources\valorant.live.ico" />
<None Remove="Resources\view-dashboard.png" />
<None Remove="Resources\volume-minus.png" />
<None Remove="Resources\volume-mute.png" />
<None Remove="Resources\volume-plus.png" />
<None Remove="Resources\wifi-strength-off.ico" />
<None Remove="Resources\zip-box.png" />
<None Include="FModel.ico">
<Pack>True</Pack>
<PackagePath></PackagePath>
</None>
</ItemGroup>
<ItemGroup>
<ApplicationDefinition Include="App.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="Commands\FModel_Commands.cs" />
<Compile Include="Forms\AESManager.xaml.cs">
<DependentUpon>AESManager.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\ColorPicker\Code\ColorPalette.cs" />
<Compile Include="Forms\ColorPicker\Code\ColorPickerDialogOptions.cs" />
<Compile Include="Forms\ColorPicker\Code\ColorSwatchItem.cs" />
<Compile Include="Forms\ColorPicker\Code\Util.cs" />
<Compile Include="Forms\ColorPicker\ColorPickerControl.xaml.cs">
<DependentUpon>ColorPickerControl.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\ColorPicker\ColorPickerSettings.cs" />
<Compile Include="Forms\ColorPicker\ColorPickerSwatch.xaml.cs">
<DependentUpon>ColorPickerSwatch.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\ColorPicker\ColorPickerWindow.xaml.cs">
<DependentUpon>ColorPickerWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\ColorPicker\ColorPickRow.xaml.cs">
<DependentUpon>ColorPickRow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\ColorPicker\SliderRow.xaml.cs">
<DependentUpon>SliderRow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FModel_About.xaml.cs">
<DependentUpon>FModel_About.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FModel_CustomMB.xaml.cs">
<DependentUpon>FModel_CustomMB.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FModel_ImagesMerger.xaml.cs">
<DependentUpon>FModel_ImagesMerger.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FModel_SearchFiles.xaml.cs">
<DependentUpon>FModel_SearchFiles.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FModel_Settings.xaml.cs">
<DependentUpon>FModel_Settings.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\FModel_UpdateMode.xaml.cs">
<DependentUpon>FModel_UpdateMode.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\BaseByte.cs" />
<Compile Include="Forms\HexViewer\Core\BookMark.cs" />
<Compile Include="Forms\HexViewer\Core\Bytes\ByteConverters.cs" />
<Compile Include="Forms\HexViewer\Core\Bytes\ByteModified.cs" />
<Compile Include="Forms\HexViewer\Core\Bytes\ByteProvider.cs" />
<Compile Include="Forms\HexViewer\Core\Caret.cs" />
<Compile Include="Forms\HexViewer\Core\CharacterTable\DTE.cs" />
<Compile Include="Forms\HexViewer\Core\CharacterTable\Enum.cs" />
<Compile Include="Forms\HexViewer\Core\CharacterTable\TBLStream.cs" />
<Compile Include="Forms\HexViewer\Core\ConstantReadOnly.cs" />
<Compile Include="Forms\HexViewer\Core\Converters\BooleanToVisibilityConverter.cs" />
<Compile Include="Forms\HexViewer\Core\Converters\BoolInverterConverter.cs" />
<Compile Include="Forms\HexViewer\Core\Converters\HexToLongStringConverter.cs" />
<Compile Include="Forms\HexViewer\Core\Converters\LongToHexStringConverter.cs" />
<Compile Include="Forms\HexViewer\Core\Converters\PathToFilenameConverter.cs" />
<Compile Include="Forms\HexViewer\Core\Enumeration.cs" />
<Compile Include="Forms\HexViewer\Core\GenericStaticInstance.cs" />
<Compile Include="Forms\HexViewer\Core\Interfaces\IByteControl.cs" />
<Compile Include="Forms\HexViewer\Core\Interfaces\IByteModified.cs" />
<Compile Include="Forms\HexViewer\Core\KeyValidator.cs" />
<Compile Include="Forms\HexViewer\Core\MethodExtention\ApplicationExtention.cs" />
<Compile Include="Forms\HexViewer\Core\MethodExtention\ByteArrayExtention.cs" />
<Compile Include="Forms\HexViewer\Core\MethodExtention\DoubleExtension.cs" />
<Compile Include="Forms\HexViewer\Core\MethodExtention\StringExtension.cs" />
<Compile Include="Forms\HexViewer\Core\MethodExtention\TrackExtention.cs" />
<Compile Include="Forms\HexViewer\Core\Native\NativeMethods.cs" />
<Compile Include="Forms\HexViewer\Core\Xcbb\CustomBackgroundBlock.cs" />
<Compile Include="Forms\HexViewer\Core\Xcbb\ExeFile.cs" />
<Compile Include="Forms\HexViewer\Core\Xcbb\XcbbExpressionParser.cs" />
<Compile Include="Forms\HexViewer\Core\Xcbb\XcbbFileParser.cs" />
<Compile Include="Forms\HexViewer\FastTextLine.cs" />
<Compile Include="Forms\HexViewer\FindReplaceWindow.xaml.cs">
<DependentUpon>FindReplaceWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\FindWindow.xaml.cs">
<DependentUpon>FindWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\GiveByteWindow.xaml.cs">
<DependentUpon>GiveByteWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\HexBox.xaml.cs">
<DependentUpon>HexBox.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\HexByte.cs" />
<Compile Include="Forms\HexViewer\HexEditor.xaml.cs">
<DependentUpon>HexEditor.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\HexViewer.xaml.cs">
<DependentUpon>HexViewer.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\ReplaceByteWindow.xaml.cs">
<DependentUpon>ReplaceByteWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Forms\HexViewer\StringByte.cs" />
<Compile Include="Methods\AESManager\DynamicKeysChecker.cs" />
<Compile Include="Methods\AESManager\KeysManager.cs" />
<Compile Include="Methods\Assets\AssetInformations.cs" />
<Compile Include="Methods\Assets\AssetsLoader.cs" />
<Compile Include="Methods\Assets\AssetTranslations.cs" />
<Compile Include="Methods\Assets\IconCreator\AthenaID\CosmeticSeason.cs" />
<Compile Include="Methods\Assets\IconCreator\AthenaID\CosmeticSet.cs" />
<Compile Include="Methods\Assets\IconCreator\AthenaID\IconUserFacingFlags.cs" />
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeBundleInfos.cs" />
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeCompletionRewards.cs" />
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeIconDesign.cs" />
<Compile Include="Methods\Assets\IconCreator\ChallengeID\ChallengeRewards.cs" />
<Compile Include="Methods\Assets\IconCreator\HeroID\HeroGameplayDefinition.cs" />
<Compile Include="Methods\Assets\IconCreator\IconCreator.cs" />
<Compile Include="Methods\Assets\IconCreator\IconImage.cs" />
<Compile Include="Methods\Assets\IconCreator\IconText.cs" />
<Compile Include="Methods\Assets\IconCreator\IconWatermark.cs" />
<Compile Include="Methods\Assets\IconCreator\Rarity.cs" />
<Compile Include="Methods\Assets\IconCreator\WeaponID\IconAmmoData.cs" />
<Compile Include="Methods\Assets\IconCreator\WeaponID\WeaponStats.cs" />
<Compile Include="Methods\Auth\AuthFlow.cs" />
<Compile Include="Methods\Auth\Requests.cs" />
<Compile Include="Methods\BackupsManager\RegisterDownloadedBackups.cs" />
<Compile Include="Methods\FindReplace\FindReplace.cs" />
<Compile Include="Methods\FindReplace\FindReplaceDialog.xaml.cs">
<DependentUpon>FindReplaceDialog.xaml</DependentUpon>
</Compile>
<Compile Include="Methods\FVar.cs" />
<Compile Include="Methods\MessageBox\DarkMessageBox.cs" />
<Compile Include="Methods\PakReader\AESDecryptor.cs" />
<Compile Include="Methods\PakReader\AssetRegReader.cs" />
<Compile Include="Methods\PakReader\ExportObject\AssetReader.cs" />
<Compile Include="Methods\PakReader\ExportObject\ExportObject.cs" />
<Compile Include="Methods\PakReader\ExportObject\UDictionary\FDictionaryHeader\FDictionaryHeader.cs" />
<Compile Include="Methods\PakReader\ExportObject\UDictionary\FDictionaryHeader\FOodleCompressedData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FObjectExport.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FPackageIndex.cs" />
<Compile Include="Methods\PakReader\DDSDecoder.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FAnimKeyHeader.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FCompressedOffsetData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FCompressedSegment.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptArray.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptMap.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FDateTime.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FLevelSequenceObjectReferenceMap\FLevelSequenceLegacyObjectReference.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FLevelSequenceObjectReferenceMap\FLevelSequenceObjectReferenceMap.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FRichCurveKey.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FScriptDelegate.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSimpleCurveKey.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSmartName.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FTrack.cs" />
<Compile Include="Methods\PakReader\ExportObject\UAnimSequence\UAnimSequence.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FPropertyTag\FPropertyTag.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FPropertyTag\FPropertyTagType.cs" />
<Compile Include="Methods\PakReader\ExportObject\UObject\UObject.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FColor.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FGameplayTagContainer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FGuid.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FIntPoint.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FLinearColor.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSoftObjectPath.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSoftObjectPathMap.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStructFallback.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FText.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FVector2D.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\UScriptStruct.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FQuat.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FRotator.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSkeletalMeshLODInfo.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FColorVertexBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FMultisizeIndexContainer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FPositionVertexBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FGPUVert4Float.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FGPUVert4Half.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FMeshUV\FMeshUVFloat.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FMeshUV\FMeshUVHalf.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FGPUVert4\FPackedNormal.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightVertexBuffer\FSkinWeightInfo.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightVertexBuffer\FSkinWeightVertexBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticMeshVertexBuffer\FStaticMeshUVItem4\FPackedRGBA16N.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticMeshVertexBuffer\FStaticMeshUVItem4\FStaticMeshUVItem4.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexBuffer\FSkeletalMeshVertexBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkeletalMeshVertexClothBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightProfilesData\FRuntimeSkinWeightProfileData\FRuntimeSkinWeightProfileData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightProfilesData\FRuntimeSkinWeightProfileData\FSkinWeightOverrideInfo.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkinWeightProfilesData\FSkinWeightProfilesData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticMeshVertexBuffer\FStaticMeshVertexBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FVector.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferencePose.cs" />
<Compile Include="Methods\PakReader\ExportObject\USkeleton\USkeleton.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSoundFormatData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStreamedAudioChunk.cs" />
<Compile Include="Methods\PakReader\ExportObject\USoundWave\USoundWave.cs" />
<Compile Include="Methods\PakReader\Extensions.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FByteBulkData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FByteBulkDataHeader.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FNameEntrySerialized.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FObjectImport.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStripDataFlags.cs" />
<Compile Include="Methods\PakReader\ExportObject\FontFace\FontFace.cs" />
<Compile Include="Methods\PakReader\ImageExporter.cs" />
<Compile Include="Methods\PakReader\LocReader.cs" />
<Compile Include="Methods\PakReader\MeshExporter.cs" />
<Compile Include="Methods\PakReader\Objects.cs" />
<Compile Include="Methods\PakReader\PakReader.cs" />
<Compile Include="Methods\PakReader\SigReader.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FTexturePlatformData\FTexture2DMipMap.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FTexturePlatformData\FTexturePlatformData.cs" />
<Compile Include="Methods\PakReader\ExportObject\Texture2D\Texture2D.cs" />
<Compile Include="Methods\PakReader\ExportObject\UCurveTable\ECurveTableMode.cs" />
<Compile Include="Methods\PakReader\ExportObject\UCurveTable\UCurveTable.cs" />
<Compile Include="Methods\PakReader\ExportObject\UDataTable\UDataTable.cs" />
<Compile Include="Methods\PakReader\ExportObject\UDictionary\UDictionary.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FBoxSphereBounds.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferenceSkeleton\FMeshBoneInfo.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSkeletalMaterial\FMeshUVChannelInfo.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferenceSkeleton\FReferenceSkeleton.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FSkeletalMaterial\FSkeletalMaterial.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FApexClothPhysToRenderVertData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FClothingSectionData.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FDuplicatedVerticesBuffer\FDuplicatedVerticesBuffer.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FDuplicatedVerticesBuffer\FIndexLengthPair.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FSkelMeshSection\FSkelMeshSection.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FVector4.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FStaticLODModel\FStaticLODModel.cs" />
<Compile Include="Methods\PakReader\ExportObject\UScript\UScriptStruct\FReferenceSkeleton\FTransform.cs" />
<Compile Include="Methods\PakReader\ExportObject\USkeletalMesh\USkeletalMesh.cs" />
<Compile Include="Methods\PAKs\BackupPAKs.cs" />
<Compile Include="Methods\PAKs\PAKsLoader.cs" />
<Compile Include="Methods\PAKs\RegisterFromPath.cs" />
<Compile Include="Methods\SyntaxHighlighter\ResourceLoader.cs" />
<Compile Include="Methods\TreeViewModel\PropertyChangedBase.cs" />
<Compile Include="Methods\TreeViewModel\SortedTreeViewWindowViewModel.cs" />
<Compile Include="Methods\TreeViewModel\TreeViewItemBehavior.cs" />
<Compile Include="Methods\TreeViewModel\TreeViewModel.cs" />
<Compile Include="Methods\Utilities\AESUtility.cs" />
<Compile Include="Methods\Utilities\AssetsUtility.cs" />
<Compile Include="Methods\Utilities\ChallengesUtility.cs" />
<Compile Include="Methods\Utilities\DebugHelper.cs" />
<Compile Include="Methods\Utilities\EndpointsUtility.cs" />
<Compile Include="Methods\Utilities\FoldersUtility.cs" />
<Compile Include="Methods\Utilities\FormsUtility.cs" />
<Compile Include="Methods\Utilities\ImagesUtility.cs" />
<Compile Include="Methods\Utilities\ListBoxUtility.cs" />
<Compile Include="Methods\Utilities\Logger.cs" />
<Compile Include="Methods\Utilities\MBoxesUtility.cs" />
<Compile Include="Methods\Utilities\PAKsUtility.cs" />
<Compile Include="Methods\Utilities\TasksUtility.cs" />
<Compile Include="Methods\Utilities\TextsUtility.cs" />
<Compile Include="Methods\Utilities\TreeViewUtility.cs" />
<Compile Include="Methods\Utilities\UIUtility.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen>
<EmbeddedResource Include="Resources\Ini.xshd" />
<EmbeddedResource Include="Resources\Json.xshd" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Autoupdater.NET.Official" Version="1.6.0" />
<PackageReference Include="AvalonEdit" Version="6.0.1" />
<PackageReference Include="CSCore" Version="1.2.1.2" />
<PackageReference Include="DiscordRichPresence" Version="1.0.150" />
<PackageReference Include="Extended.Wpf.Toolkit" Version="3.8.1" />
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.1.11" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
<PackageReference Include="NVorbis" Version="0.10.1" />
<PackageReference Include="Ookii.Dialogs.Wpf" Version="1.1.0" />
<PackageReference Include="SkiaSharp" Version="1.68.2.1" />
<PackageReference Include="ToastNotifications" Version="2.5.1" />
<PackageReference Include="ToastNotifications.Messages" Version="2.5.1" />
<PackageReference Include="WriteableBitmapEx" Version="1.6.5" />
</ItemGroup>
<ItemGroup>
<Resource Include="FModel.ico" />
<Resource Include="Resources\alert.ico" />
<Resource Include="Resources\alpha-a-box.png" />
<Resource Include="Resources\api-off.ico" />
<Resource Include="Resources\api.ico" />
<Resource Include="Resources\backup-restore.png" />
<Resource Include="Resources\bug.png" />
<Resource Include="Resources\BurbankBigCondensed-Bold.ttf" />
<Resource Include="Resources\cast-audio.png" />
<Resource Include="Resources\challenge-theme-creator.png" />
<Resource Include="Resources\check-circle.ico" />
<Resource Include="Resources\ColorPickerOne.png" />
<Resource Include="Resources\ColorPickerTwo.png" />
<Resource Include="Resources\content-copy.png" />
<Resource Include="Resources\content-save.png" />
<Resource Include="Resources\delete-forever.png" />
<Resource Include="Resources\discord.png" />
<Resource Include="Resources\egl2.ico" />
<Resource Include="Resources\EIconDesign_Default.png" />
<Resource Include="Resources\EIconDesign_Flat.png" />
<Resource Include="Resources\EIconDesign_Mini.png" />
<Resource Include="Resources\EIconDesign_NoText.png" />
<Resource Include="Resources\file-export.png" />
<Resource Include="Resources\file-image.ico" />
<Resource Include="Resources\file-multiple.png" />
<Resource Include="Resources\file-restore.png" />
<Resource Include="Resources\file.png" />
<Resource Include="Resources\fmodel.png" />
<Resource Include="Resources\folder-download.png" />
<Resource Include="Resources\folder-open.png" />
<Resource Include="Resources\fortnite.ico" />
<Resource Include="Resources\gamepad-variant.png" />
<Resource Include="Resources\github-circle.png" />
<Resource Include="Resources\icon-creator.png" />
<Resource Include="Resources\image-filter-black-white.png" />
<Resource Include="Resources\image-move.png" />
<Resource Include="Resources\image-plus.png" />
<Resource Include="Resources\image-remove.png" />
<Resource Include="Resources\information.png" />
<Resource Include="Resources\key.png" />
<Resource Include="Resources\lock-open-variant.ico" />
<Resource Include="Resources\magnify.png" />
<Resource Include="Resources\open-in-new.png" />
<Resource Include="Resources\pause.png" />
<Resource Include="Resources\paypal.png" />
<Resource Include="Resources\pencil.png" />
<Resource Include="Resources\play.png" />
<Resource Include="Resources\playlist-plus.png" />
<Resource Include="Resources\power.png" />
<Resource Include="Resources\progress-download.png" />
<Resource Include="Resources\refresh.png" />
<Resource Include="Resources\settings.png" />
<Resource Include="Resources\share-all.png" />
<Resource Include="Resources\share.png" />
<Resource Include="Resources\sign-direction-plus.png" />
<Resource Include="Resources\sign-direction-remove.png" />
<Resource Include="Resources\sign-direction.png" />
<Resource Include="Resources\stop.png" />
<Resource Include="Resources\T-Icon-Pets-64.png" />
<Resource Include="Resources\T-Icon-Quests-64.png" />
<Resource Include="Resources\T_ClipSize_Weapon_Stats.png" />
<Resource Include="Resources\T_DamagePerBullet_Weapon_Stats.png" />
<Resource Include="Resources\T_Placeholder_Challenge_Image.png" />
<Resource Include="Resources\T_Placeholder_Item_Image.png" />
<Resource Include="Resources\T_ReloadTime_Weapon_Stats.png" />
<Resource Include="Resources\valorant.live.ico" />
<Resource Include="Resources\view-dashboard.png" />
<Resource Include="Resources\volume-minus.png" />
<Resource Include="Resources\volume-mute.png" />
<Resource Include="Resources\volume-plus.png" />
<Resource Include="Resources\wifi-strength-off.ico" />
<Resource Include="Resources\zip-box.png" />
</ItemGroup>
<ItemGroup>
<Compile Update="Properties\Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<Compile Include="Themes\LeftMarginMultiplierConverter.cs" />
<Compile Include="Themes\TreeViewItemExtensions.cs" />
<Page Include="FModel_Main.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="FModel_Main.xaml.cs">
<DependentUpon>FModel_Main.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="Forms\AESManager.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\ColorPicker\ColorPickerControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\ColorPicker\ColorPickerSwatch.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\ColorPicker\ColorPickerWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\ColorPicker\ColorPickRow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\ColorPicker\SliderRow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\FModel_About.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\FModel_CustomMB.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\FModel_ImagesMerger.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\FModel_SearchFiles.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\FModel_Settings.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\FModel_UpdateMode.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\BrushesDictionary.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Forms\HexViewer\FindReplaceWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\FindWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\GiveByteWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\HexBox.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\HexEditor.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\HexViewer.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\MiscelanousDictionary.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Forms\HexViewer\ReplaceByteWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Forms\HexViewer\ToolTipDictionary.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Methods\FindReplace\FindReplaceDialog.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Styles.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">
<SubType>Code</SubType>
</Compile>
<Compile Include="Properties\Settings.Designer.cs">
<Compile Update="Properties\Settings.Designer.cs">
<DesignTimeSharedInput>True</DesignTimeSharedInput>
<AutoGen>True</AutoGen>
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<EmbeddedResource Include="Properties\Resources.resx">
</ItemGroup>
<ItemGroup>
<EmbeddedResource Update="Properties\Resources.resx">
<Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Include="Methods\SyntaxHighlighter\Json.xshd" />
<EmbeddedResource Include="Methods\SyntaxHighlighter\Ini.xshd" />
<None Include="Forms\HexViewer\Core\Xcbb\Exefile.xcbb" />
<None Include="Methods\PakReader\LICENSE" />
<None Include="packages.config" />
<None Include="Properties\Settings.settings">
<Generator>SettingsSingleFileGenerator</Generator>
</ItemGroup>
<ItemGroup>
<None Update="Properties\Settings.settings">
<Generator>PublicSettingsSingleFileGenerator</Generator>
<LastGenOutput>Settings.Designer.cs</LastGenOutput>
</None>
<Resource Include="Resources\TT-JTCじゃんけんU &amp; TT-JTCじゃんけんUP.TTC" />
<Resource Include="Resources\EBCDIC-NoSpecialChar.tbl" />
<Resource Include="Resources\EBCDIC.tbl" />
<Resource Include="Resources\BurbankBigCondensed-Black.ttf" />
<Resource Include="Resources\BurbankBigCondensed-Bold.ttf" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<Resource Include="Logo.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Logo.png" />
</ItemGroup>
<ItemGroup>
<BootstrapperPackage Include=".NETFramework,Version=v4.7.2">
<Visible>False</Visible>
<ProductName>Microsoft .NET Framework 4.7.2 %28x86 et x64%29</ProductName>
<Install>true</Install>
</BootstrapperPackage>
<BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
<Visible>False</Visible>
<ProductName>.NET Framework 3.5 SP1</ProductName>
<Install>false</Install>
</BootstrapperPackage>
</ItemGroup>
<ItemGroup>
<Folder Include="Methods\Assets\IconCreator\DefenderID\" />
<Folder Include="Methods\Assets\IconCreator\SchematicID\" />
<Folder Include="Methods\Assets\IconCreator\VariantID\" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_D_F.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_D_N.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_F_F.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_F_N.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_M_F.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_M_N.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\T-Icon-Pets-64.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\T-Icon-Quests-64.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\clipSize64.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\dmg64.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\reload64.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\unknown512.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_Challenge.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\colorpicker1.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\colorpicker2.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Logo-Icon.ico" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\close_file_16x.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\folder_16x.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\info_16x.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\open_16x.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\save_16x.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\settings_16x.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_AC_F.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Resources\Template_AC_N.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Target Name="AfterResolveReferences">
<ItemGroup>
<EmbeddedResource Include="@(ReferenceCopyLocalPaths)" Condition="'%(ReferenceCopyLocalPaths.Extension)' == '.dll'">
<LogicalName>%(ReferenceCopyLocalPaths.DestinationSubDirectory)%(ReferenceCopyLocalPaths.Filename)%(ReferenceCopyLocalPaths.Extension)</LogicalName>
</EmbeddedResource>
</ItemGroup>
</Target>
<Import Project="..\packages\SkiaSharp.1.68.1\build\net45\SkiaSharp.targets" Condition="Exists('..\packages\SkiaSharp.1.68.1\build\net45\SkiaSharp.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>Ce projet fait référence à des packages NuGet qui sont manquants sur cet ordinateur. Utilisez l'option de restauration des packages NuGet pour les télécharger. Pour plus d'informations, consultez http://go.microsoft.com/fwlink/?LinkID=322105. Le fichier manquant est : {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\SkiaSharp.1.68.1\build\net45\SkiaSharp.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\SkiaSharp.1.68.1\build\net45\SkiaSharp.targets'))" />
</Target>
</Project>

BIN
FModel/FModel.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@ -1,196 +0,0 @@
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel"
xmlns:commands="clr-namespace:FModel.Commands"
xmlns:properties="clr-namespace:FModel.Properties"
xmlns:TreeViewModel="clr-namespace:FModel.Methods.TreeViewModel"
xmlns:avalonedit="http://icsharpcode.net/sharpdevelop/avalonedit"
x:Class="FModel.MainWindow"
mc:Ignorable="d"
Title="FModel"
Height="744"
MinHeight="744"
Width="1207"
MinWidth="1207"
Style="{StaticResource {x:Type Window}}"
WindowStartupLocation="CenterScreen"
Icon="Logo.ico"
Loaded="Window_Loaded"
UseLayoutRounding="True">
<Window.CommandBindings>
<CommandBinding Command="{x:Static commands:FModel_Commands.OpenSettings}" Executed="MI_Settings_Click"/>
<CommandBinding Command="{x:Static commands:FModel_Commands.OpenSearch}" Executed="MI_Search_Click"/>
<CommandBinding Command="{x:Static commands:FModel_Commands.OpenOutput}" Executed="MI_OpenOutputFolder_Click"/>
<CommandBinding Command="{x:Static commands:FModel_Commands.MergeImages}" Executed="MI_MergeImages_Click"/>
</Window.CommandBindings>
<Window.InputBindings>
<KeyBinding Key="F1" Command="{x:Static commands:FModel_Commands.OpenSettings}"/>
<KeyBinding Key="F2" Command="{x:Static commands:FModel_Commands.OpenSearch}"/>
<KeyBinding Key="F3" Command="{x:Static commands:FModel_Commands.OpenOutput}"/>
<KeyBinding Key="F4" Command="{x:Static commands:FModel_Commands.MergeImages}"/>
</Window.InputBindings>
<Grid>
<Menu Height="25" VerticalAlignment="Top" RenderTransformOrigin="0.5,0.5">
<MenuItem Header="Load">
<MenuItem x:Name="MI_LoadOnePAK" Header="Load One PAK" IsEnabled="False"/>
<MenuItem x:Name="MI_LoadAllPAKs" Header="Load All PAKs" Padding="2,4,2,2" IsEnabled="False" Click="MI_LoadAllPAKs_Click"/>
<Separator/>
<MenuItem x:Name="MI_ReloadAESs" Header="Reload AES Keys" Click="MI_ReloadAESs_Click"/>
<Separator/>
<MenuItem x:Name="MI_DownloadBackups" Header="Download Backups"/>
<MenuItem x:Name="MI_BackupPAKs" Header="Backup PAKs" Click="MI_BackupPAKs_Click" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="MI_DifferenceMode" Header="Difference Mode" IsCheckable="True" Checked="MI_Change_Header" Unchecked="MI_Change_Header"/>
<MenuItem x:Name="MI_UpdateMode" Header="Update Mode" IsCheckable="True" Checked="MI_Change_Header" Unchecked="MI_Change_Header" IsEnabled="False"/>
<Separator/>
<MenuItem x:Name="MI_Settings" Header="Settings" InputGestureText="F1" Command="{x:Static commands:FModel_Commands.OpenSettings}">
<MenuItem.Icon>
<Image Source="Resources/settings_16x.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="Files">
<MenuItem x:Name="MI_Search" Header="Search" InputGestureText="F2" Command="{x:Static commands:FModel_Commands.OpenSearch}"/>
<MenuItem x:Name="MI_HexViewer" Header="Hex Viewer" Click="MI_HexViewer_Click">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/Logo-Icon.ico" Width="19"/>
</MenuItem.Icon>
</MenuItem>
<Separator/>
<MenuItem x:Name="MI_ExportRaw" Header="Export RAW Data" Click="MI_ExportRaw_Click">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/save_16x.png" Height="15" Width="15"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem x:Name="MI_AutoExportRaw" Header="Auto Export RAW Data" IsCheckable="True" IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=FAutoExtractRaw, Mode=TwoWay}"/>
<Separator/>
<MenuItem x:Name="MI_SaveJson" Header="Save JSON Data" Click="MI_SaveJson_Click">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/save_16x.png" Height="15" Width="15"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem x:Name="MI_AutoSaveJson" Header="Auto Save JSON Data" IsCheckable="True" IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=FAutoSaveJson, Mode=TwoWay}"/>
<Separator/>
<MenuItem Header="Open Output Folder" InputGestureText="F3" Command="{x:Static commands:FModel_Commands.OpenOutput}">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/folder_16x.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
<MenuItem Header="Image">
<MenuItem x:Name="MI_Save_Image" Header="Save Image" Click="MI_Save_Image_Click">
<MenuItem.Icon>
<Image Source="Resources/save_16x.png" Height="15" Width="15"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem x:Name="MI_Auto_Save_Images" Header="Auto Save Images" IsCheckable="True" IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=FAutoSaveImg, Mode=TwoWay}"/>
<Separator/>
<MenuItem Header="Images Merger" InputGestureText="F4" Command="{x:Static commands:FModel_Commands.MergeImages}"/>
</MenuItem>
<MenuItem Header="Help">
<MenuItem x:Name="MI_Changelog" Header="Changelog" Click="MI_Changelog_Click"/>
<MenuItem x:Name="MI_BugReports" Header="Bugs Report" Click="MI_BugReports_Click"/>
<MenuItem x:Name="MI_About" Header="About FModel" Click="MI_About_Click">
<MenuItem.Icon>
<Image Source="Resources/info_16x.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
</MenuItem>
</Menu>
<StatusBar Height="22" Margin="0" VerticalAlignment="Bottom" Background="#FF1C2026" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.Row="1">
<StatusBar.ItemsPanel>
<ItemsPanelTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
</Grid>
</ItemsPanelTemplate>
</StatusBar.ItemsPanel>
<StatusBarItem Grid.Column="0">
<TextBlock x:Name="FModelVersionLabel" Text="FModel "/>
</StatusBarItem>
<StatusBarItem Grid.Column="1" HorizontalContentAlignment="Center">
<TextBlock x:Name="PEventTextBlock" Text="Process Events"/>
</StatusBarItem>
<StatusBarItem Grid.Column="2" HorizontalContentAlignment="Right">
<TextBlock x:Name="StateTextBlock" Text="State" Margin="0" Padding="5,0"/>
</StatusBarItem>
</StatusBar>
<Grid Margin="0,25,0,22">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="359*"/>
<ColumnDefinition Width="840*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition Height="30"/>
</Grid.RowDefinitions>
<Button x:Name="Button_Extract" Content="Extract" HorizontalAlignment="Right" Margin="0,0,10,6" Grid.Row="2" VerticalAlignment="Bottom" Width="80" Grid.Column="1" Height="19" IsEnabled="False" Click="Button_Extract_Click"/>
<Button x:Name="Button_Stop" Content="Stop" HorizontalAlignment="Right" Margin="0,0,95,6" Grid.Row="2" VerticalAlignment="Bottom" Width="80" Grid.Column="1" Height="19" IsEnabled="False" Click="Button_Stop_Click"/>
<Button x:Name="Button_OpenImage" Content="Open Image" HorizontalAlignment="Right" Margin="0,0,180,6" Grid.Row="2" VerticalAlignment="Bottom" Width="80" Grid.Column="1" Height="19" Click="Button_OpenImage_Click"/>
<Button x:Name="Button_AESManager" Content="AES Manager" HorizontalAlignment="Right" Margin="0,0,300,6" Grid.Row="2" VerticalAlignment="Bottom" Width="180" Grid.Column="1" Height="19" Click="Button_AESManager_Click"/>
<TextBox x:Name="FilterTextBox_Main" Height="19" Margin="40,0,0,6" Grid.Row="2" TextWrapping="NoWrap" VerticalAlignment="Bottom" Foreground="#FFEFEFEF" TextChanged="FilterTextBox_Main_TextChanged"/>
<Label Content="Filter:" HorizontalAlignment="Left" Margin="2,0,0,3" Grid.Row="2" VerticalAlignment="Bottom" Height="25" Width="38" Padding="5,7,5,5"/>
<TreeView x:Name="TreeView_Main" TreeViewItem.Selected="NodeSelected" Margin="2,1,0,0" ItemsSource="{Binding ItemsView}" VirtualizingPanel.IsVirtualizing="True" VirtualizingPanel.VirtualizationMode="Recycling">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate DataType="{x:Type TreeViewModel:TreeViewModel}" ItemsSource="{Binding ItemsView}">
<TextBlock Text="{Binding Value}"/>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
<TreeView.ContextMenu>
<ContextMenu>
<MenuItem x:Name="RC_ExtractFolders" Header="Extract Folder and Subfolders" Click="RC_ExtractFolders_Click"/>
</ContextMenu>
</TreeView.ContextMenu>
</TreeView>
<ListBox x:Name="ListBox_Main" Margin="2,1,0,2" Grid.Row="1" SelectionMode="Extended" SelectionChanged="ListBox_Main_SelectionChanged" MouseDoubleClick="ListBox_Main_MouseDoubleClick">
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem x:Name="RC_Extract" Header="Extract Asset" Click="RC_Extract_Click"/>
<MenuItem x:Name="RC_ExportData" Header="Export RAW Data" Click="RC_ExportData_Click"/>
<MenuItem x:Name="RC_SaveData" Header="Save JSON Data" Click="RC_SaveData_Click"/>
<Separator/>
<MenuItem Header="Copy File">
<MenuItem x:Name="RC_Copy_FPath" Header="Copy File Path" Click="RC_Copy_FPath_Click"/>
<MenuItem x:Name="RC_Copy_FName" Header="Copy File Name" Click="RC_Copy_FName_Click"/>
<MenuItem x:Name="RC_Copy_FPath_NoExt" Header="Copy File Path w/o Extension" Click="RC_Copy_FPath_NoExt_Click"/>
<MenuItem x:Name="RC_Copy_FName_NoExt" Header="Copy File Name w/o Extension" Click="RC_Copy_FName_NoExt_Click"/>
</MenuItem>
<Separator/>
<MenuItem x:Name="RC_Properties" Header="Properties" Click="RC_Properties_Click">
<MenuItem.Icon>
<Image Source="Resources/info_16x.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
<RichTextBox x:Name="ConsoleBox_Main" Grid.Column="1" Margin="1,1,1,2" Grid.Row="1" Background="#FF252D36" Foreground="#FFEFEFEF" BorderBrush="#7F748198" ScrollViewer.CanContentScroll="True" VerticalScrollBarVisibility="Auto" IsReadOnly="True">
<RichTextBox.Resources>
<Style TargetType="{x:Type Paragraph}">
<Setter Property="Margin" Value="0" />
</Style>
</RichTextBox.Resources>
</RichTextBox>
<Grid Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="523*"/>
<ColumnDefinition Width="317*"/>
</Grid.ColumnDefinitions>
<Border BorderBrush="#7F748198" BorderThickness="1" Grid.Column="1" Margin="1,1,1,0" Background="#FF252D36">
<Image x:Name="ImageBox_Main" UseLayoutRounding="True"/>
</Border>
<Border BorderBrush="#7F748198" BorderThickness="1" Margin="1,1,0,0" Background="#FF252D36">
<avalonedit:TextEditor x:Name="AssetPropertiesBox_Main" FontFamily="Consolas" FontSize="8pt" ShowLineNumbers="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" IsReadOnly="True" Foreground="#FFEFEFEF"/>
</Border>
</Grid>
</Grid>
</Grid>
</Window>

View File

@ -1,385 +0,0 @@
using AutoUpdaterDotNET;
using FModel.Forms;
using FModel.Forms.HexViewer;
using FModel.Methods;
using FModel.Methods.AESManager;
using FModel.Methods.Assets;
using FModel.Methods.BackupsManager;
using FModel.Methods.PAKs;
using FModel.Methods.TreeViewModel;
using FModel.Methods.Utilities;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace FModel
{
/// <summary>
/// Logique d'interaction pour MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public SortedTreeViewWindowViewModel ViewModel { get { return DataContext as SortedTreeViewWindowViewModel; } set { DataContext = value; } }
public MainWindow()
{
InitializeComponent();
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
FWindow.FMain = this;
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
FModelVersionLabel.Text += Assembly.GetExecutingAssembly().GetName().Version.ToString().Substring(0, 5);
DebugHelper.WriteLine("AutoUpdater: Checking for updates");
AutoUpdater.CheckForUpdateEvent += UIHelper.AutoUpdaterOnCheckForUpdateEvent;
AutoUpdater.Start("https://cdn.asval.tk/d/FModel/FModel.xml");
DebugHelper.WriteUserSettings();
await Task.Run(() =>
{
FoldersUtility.CheckWatermark();
RegisterFromPath.CheckFortniteVersion();
RegisterFromPath.FilterPAKs();
DynamicKeysChecker.SetDynamicKeys();
RegisterDownloadedBackups.LoadBackupFiles();
}).ContinueWith(TheTask =>
{
TasksUtility.TaskCompleted(TheTask.Exception);
Dispatcher.InvokeAsync(() => AvalonEdit.SetAEConfig());
Program.StartTimer.Stop();
DebugHelper.WriteLine("Startup time: {0} ms", Program.StartTimer.ElapsedMilliseconds);
});
}
#region BUTTON EVENTS
private void Button_AESManager_Click(object sender, RoutedEventArgs e)
{
DebugHelper.WriteLine("FWindow: AES Manager");
if (!FormsUtility.IsWindowOpen<Window>("AES Manager"))
{
new AESManager().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("AES Manager").Focus(); }
}
private void Button_OpenImage_Click(object sender, RoutedEventArgs e)
{
if (ImageBox_Main.Source != null)
{
DebugHelper.WriteLine("FWindow: Opening image of " + FWindow.FCurrentAsset);
if (!FormsUtility.IsWindowOpen<Window>(FWindow.FCurrentAsset))
{
Window win = new Window();
win.Title = FWindow.FCurrentAsset;
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
win.Width = ImageBox_Main.Source.Width;
win.Height = ImageBox_Main.Source.Height;
if (ImageBox_Main.Source.Height > 1000)
{
win.WindowState = WindowState.Maximized;
}
DockPanel dockPanel = new DockPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
Image img = new Image();
img.UseLayoutRounding = true;
img.Source = ImageBox_Main.Source;
dockPanel.Children.Add(img);
win.Content = dockPanel;
win.Show();
}
else { FormsUtility.GetOpenedWindow<Window>(FWindow.FCurrentAsset).Focus(); }
}
}
private void Button_Stop_Click(object sender, RoutedEventArgs e)
{
if (TasksUtility.CancellableTaskTokenSource != null)
{
DebugHelper.WriteLine("Thread canceled by user");
TasksUtility.CancellableTaskTokenSource.Cancel();
if (TasksUtility.CancellableTaskTokenSource.IsCancellationRequested)
{
new UpdateMyProcessEvents("Canceled!", "Yikes").Update();
}
else { new UpdateMyProcessEvents("This is odd!\tCanceled but not requested. You should never see this tbh", "Yikes").Update(); }
}
}
private async void Button_Extract_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
await AssetsLoader.LoadSelectedAsset();
}
}
#endregion
#region MENU ITEM EVENTS
public async void MI_Pak_Click(object sender, RoutedEventArgs e)
{
FWindow.FCurrentPAK = (sender as MenuItem).Header.ToString();
await PAKsLoader.LoadOnePAK();
}
private async void MI_LoadAllPAKs_Click(object sender, RoutedEventArgs e)
{
FWindow.FCurrentPAK = string.Empty;
//LOAD ALL
if (!MI_DifferenceMode.IsChecked && !MI_UpdateMode.IsChecked)
{
await PAKsLoader.LoadAllPAKs();
}
//LOAD DIFF
if (MI_DifferenceMode.IsChecked && !MI_UpdateMode.IsChecked)
{
await PAKsLoader.LoadDifference();
}
//LOAD AND EXTRACT DIFF
if (MI_DifferenceMode.IsChecked && MI_UpdateMode.IsChecked)
{
await PAKsLoader.LoadDifference(true);
if (PAKsLoader.umIsOk)
await AssetsLoader.ExtractUpdateMode();
}
}
private void MI_ReloadAESs_Click(object sender, RoutedEventArgs e)
{
DynamicKeysChecker.SetDynamicKeys(true);
}
private async void MI_BackupPAKs_Click(object sender, RoutedEventArgs e)
{
await BackupPAKs.CreateBackupFile();
}
private void MI_Settings_Click(object sender, RoutedEventArgs e)
{
DebugHelper.WriteLine("FWindow: Settings");
if (!FormsUtility.IsWindowOpen<Window>("Settings"))
{
new FModel_Settings().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Settings").Focus(); }
}
private void MI_Search_Click(object sender, RoutedEventArgs e)
{
DebugHelper.WriteLine("FWindow: Search Files");
if (!FormsUtility.IsWindowOpen<Window>("Search"))
{
new FModel_SearchFiles().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Search").Focus(); }
}
private void MI_HexViewer_Click(object sender, RoutedEventArgs e)
{
DebugHelper.WriteLine("FWindow: Hex Viewer");
if (!FormsUtility.IsWindowOpen<Window>("Hex Viewer"))
{
new HexViewer().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Hex Viewer").Focus(); }
}
private void MI_ExportRaw_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
AssetsUtility.ExportAssetData();
}
}
private void MI_SaveJson_Click(object sender, RoutedEventArgs e)
{
AssetsUtility.SaveAssetProperties();
}
private void MI_OpenOutputFolder_Click(object sender, RoutedEventArgs e)
{
FoldersUtility.OpenOutputFolder();
}
private void MI_Save_Image_Click(object sender, RoutedEventArgs e)
{
if (ImageBox_Main.Source != null)
{
ImagesUtility.SaveImageDialog();
}
}
private void MI_MergeImages_Click(object sender, RoutedEventArgs e)
{
DebugHelper.WriteLine("FWindow: Images Merger");
if (!FormsUtility.IsWindowOpen<Window>("Images Merger"))
{
new FModel_ImagesMerger().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Images Merger").Focus(); }
}
private void MI_Changelog_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start("https://github.com/iAmAsval/FModel/releases/latest");
}
private void MI_BugReports_Click(object sender, RoutedEventArgs e)
{
System.Diagnostics.Process.Start("https://github.com/iAmAsval/FModel/issues/new");
}
private void MI_About_Click(object sender, RoutedEventArgs e)
{
DebugHelper.WriteLine("FWindow: About");
if (!FormsUtility.IsWindowOpen<Window>("About"))
{
new FModel_About().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("About").Focus(); }
}
private void MI_Change_Header(object sender, RoutedEventArgs e)
{
//DIFFERENCE MODE
if (MI_DifferenceMode.IsChecked)
{
MI_LoadOnePAK.IsEnabled = false;
MI_LoadAllPAKs.Header = "Load Difference";
MI_UpdateMode.IsEnabled = true;
}
if (!MI_DifferenceMode.IsChecked)
{
MI_LoadOnePAK.IsEnabled = true;
MI_UpdateMode.IsEnabled = false;
MI_UpdateMode.IsChecked = false;
}
//UPDATE MODE
if (MI_UpdateMode.IsChecked)
{
MI_LoadAllPAKs.Header = "Load And Extract Difference";
MI_UpdateMode.IsEnabled = true;
MI_Auto_Save_Images.IsChecked = true; //auto save images
if (MI_DifferenceMode.IsChecked && MI_UpdateMode.IsChecked)
{
if (!FormsUtility.IsWindowOpen<Window>("Update Mode"))
{
new FModel_UpdateMode().Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Update Mode").Focus(); }
}
}
if (!MI_UpdateMode.IsChecked)
{
MI_LoadAllPAKs.Header = "Load Difference";
MI_Auto_Save_Images.IsChecked = false;
}
//BOTH
if (!MI_DifferenceMode.IsChecked && !MI_UpdateMode.IsChecked)
{
MI_LoadAllPAKs.Header = "Load All PAKs";
}
}
#endregion
#region TREEVIEW EVENTS
private async void NodeSelected(object sender, RoutedEventArgs e)
{
TreeViewItem currContainer = e.OriginalSource as TreeViewItem;
if (currContainer != null)
{
FWindow.TVItem = currContainer;
await ListBoxUtility.PopulateListBox(currContainer);
}
}
private async void RC_ExtractFolders_Click(object sender, RoutedEventArgs e)
{
if (TreeView_Main.SelectedItem != null)
{
string path = TreeViewUtility.GetFullPath(FWindow.TVItem);
await AssetsLoader.ExtractFoldersAndSub(path);
}
}
#endregion
#region LISTBOX EVENTS
private void ListBox_Main_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0) { ((ListBox)sender).ScrollIntoView(e.AddedItems[0]); }
if (!AssetsLoader.isRunning) { Button_Extract.IsEnabled = ListBox_Main.SelectedIndex >= 0; }
}
private async void ListBox_Main_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
if (!AssetsLoader.isRunning && ListBox_Main.SelectedIndex >= 0)
{
await AssetsLoader.LoadSelectedAsset();
}
}
private async void FilterTextBox_Main_TextChanged(object sender, TextChangedEventArgs e)
{
await ListBoxUtility.FilterListBox();
}
private async void RC_Extract_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
await AssetsLoader.LoadSelectedAsset();
}
}
private void RC_ExportData_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
AssetsUtility.ExportAssetData();
}
}
private void RC_SaveData_Click(object sender, RoutedEventArgs e)
{
AssetsUtility.SaveAssetProperties();
}
private void RC_Copy_FPath_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy());
}
}
private void RC_Copy_FName_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy(true));
}
}
private void RC_Copy_FPath_NoExt_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy(false, false));
}
}
private void RC_Copy_FName_NoExt_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
Clipboard.SetText(AssetsUtility.GetAssetPathToCopy(true, false));
}
}
private void RC_Properties_Click(object sender, RoutedEventArgs e)
{
if (ListBox_Main.SelectedIndex >= 0)
{
FWindow.FCurrentAsset = ListBox_Main.SelectedItem.ToString();
AssetInformations.OpenAssetInfos();
}
}
#endregion
}
}

View File

@ -1,40 +0,0 @@
<Window x:Class="FModel.Forms.AESManager"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel.Forms"
mc:Ignorable="d"
Title="AES Manager"
Height="370"
MinHeight="370"
Width="600"
MinWidth="600"
Style="{StaticResource {x:Type Window}}"
ResizeMode="NoResize"
WindowStartupLocation="CenterScreen"
Icon="/FModel;component/Logo.ico" Loaded="Window_Loaded"
>
<Grid>
<GroupBox Header="Static Key" Height="48" Margin="10,10,10,0" VerticalAlignment="Top" BorderBrush="#7F748198">
<Grid>
<Label Content="Main PAKs:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,0"/>
<TextBox x:Name="MAesTextBox" Height="18" Margin="65,4,5,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
</Grid>
</GroupBox>
<GroupBox Header="Dynamic Keys" Height="232" Margin="10,63,10,0" VerticalAlignment="Top" BorderBrush="#7F748198">
<Grid>
<ScrollViewer Background="{x:Null}">
<Grid x:Name="Grid_DynamicKeys"/>
</ScrollViewer>
</Grid>
</GroupBox>
<Button Content="OK" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/>
<Label HorizontalAlignment="Left" Margin="10,0,0,11" VerticalAlignment="Bottom" Padding="0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Cursor="Hand">
<TextBlock>
<Hyperlink NavigateUri="https://benbotfn.tk/api/v1/aes" RequestNavigate="Hyperlink_RequestNavigate" Foreground="#FFEFEFEF">Latest Fortnite AES Keys</Hyperlink>
</TextBlock>
</Label>
</Grid>
</Window>

View File

@ -1,145 +0,0 @@
using FModel.Methods;
using FModel.Methods.AESManager;
using FModel.Methods.Utilities;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Navigation;
using FProp = FModel.Properties.Settings;
namespace FModel.Forms
{
/// <summary>
/// Logique d'interaction pour AESManager.xaml
/// </summary>
public partial class AESManager : Window
{
private static readonly string AESManager_PATH = FProp.Default.FOutput_Path + "\\FAESManager.xml";
public AESManager()
{
InitializeComponent();
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
AddLblTxtForDynamicPAKs();
GetUserSettings();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SetUserSettings();
PAKsUtility.DisableNonKeyedPAKs();
Close();
}
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}
private void AddLblTxtForDynamicPAKs()
{
if (PAKEntries.PAKEntriesList != null && PAKEntries.PAKEntriesList.Any())
{
if (AESEntries.AESEntriesList == null) { KeysManager.Deserialize(); }
int yPos = 4;
foreach (PAKInfosEntry Pak in PAKEntries.PAKEntriesList.Where(x => x.bTheDynamicPAK))
{
Label PakLabel = new Label
{
Content = Path.GetFileNameWithoutExtension(Pak.ThePAKPath),
HorizontalAlignment = HorizontalAlignment.Left,
Margin = new Thickness(2, yPos - 2, 0, 0),
VerticalAlignment = VerticalAlignment.Top,
Foreground = new SolidColorBrush(Color.FromRgb(239, 239, 239))
};
TextBox PakTextBox = new TextBox
{
Height = 19,
TextWrapping = TextWrapping.NoWrap,
AcceptsReturn = false,
Margin = new Thickness(160, yPos, 5, 0),
VerticalAlignment = VerticalAlignment.Top,
Foreground = new SolidColorBrush(Color.FromRgb(239, 239, 239)),
Name = $"TxtBox_{Regex.Match(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), @"\d+").Value}"
};
string PAKKeyFromXML = string.Empty;
if (AESEntries.AESEntriesList != null && AESEntries.AESEntriesList.Any())
{
PAKKeyFromXML = AESEntries.AESEntriesList.Where(x => string.Equals(x.ThePAKName, Path.GetFileNameWithoutExtension(Pak.ThePAKPath))).Select(x => x.ThePAKKey).FirstOrDefault();
PakTextBox.Text = $"0x{PAKKeyFromXML}";
}
yPos += 28;
Grid_DynamicKeys.Children.Add(PakLabel);
Grid_DynamicKeys.Children.Add(PakTextBox);
DebugHelper.WriteLine($"AESManager GET: {Pak.ThePAKPath} with key: {PAKKeyFromXML}");
}
}
}
private void GetUserSettings()
{
MAesTextBox.Text = $"0x{FProp.Default.FPak_MainAES}";
DebugHelper.WriteLine($"AESManager GET: Main PAKs with key: {FProp.Default.FPak_MainAES}");
}
private void SetUserSettings()
{
//MAIN AES
if (!string.IsNullOrEmpty(MAesTextBox.Text))
{
if (MAesTextBox.Text.StartsWith("0x"))
{
FProp.Default.FPak_MainAES = Regex.Replace(MAesTextBox.Text.Substring(2).ToUpper(), @"\s+", string.Empty);
}
else { FProp.Default.FPak_MainAES = Regex.Replace(MAesTextBox.Text.ToUpper(), @"\s+", string.Empty); }
}
else { FProp.Default.FPak_MainAES = string.Empty; }
DebugHelper.WriteLine($"AESManager SET: Main PAKs with key: {MAesTextBox.Text}");
//DYNAMIC AESs
AESEntries.AESEntriesList = new List<AESInfosEntry>();
if (PAKEntries.PAKEntriesList != null && PAKEntries.PAKEntriesList.Any())
{
foreach (PAKInfosEntry Pak in PAKEntries.PAKEntriesList.Where(x => x.bTheDynamicPAK))
{
TextBox PakTextBox = UIHelper.FindChild<TextBox>(this, $"TxtBox_{Regex.Match(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), @"\d+").Value}");
if (!string.IsNullOrEmpty(PakTextBox.Text))
{
if (PakTextBox.Text.StartsWith("0x"))
{
KeysManager.Serialize(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), Regex.Replace(PakTextBox.Text.Substring(2).ToUpper(), @"\s+", string.Empty));
}
else { KeysManager.Serialize(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), Regex.Replace(PakTextBox.Text.ToUpper(), @"\s+", string.Empty)); }
}
else { KeysManager.Serialize(Path.GetFileNameWithoutExtension(Pak.ThePAKPath), string.Empty); }
DebugHelper.WriteLine($"AESManager SET: {Pak.ThePAKPath} with key: {PakTextBox.Text}");
}
Directory.CreateDirectory(Path.GetDirectoryName(AESManager_PATH));
using (var fileStream = new FileStream(AESManager_PATH, FileMode.Create))
{
KeysManager.serializer.Serialize(fileStream, AESEntries.AESEntriesList);
}
}
//SAVE
FProp.Default.Save();
DebugHelper.WriteLine($"AESManager: Saved");
}
}
}

View File

@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
namespace ColorPickerWPF.Code
{
public class ColorSwatchItem
{
public Color Color { get; set; }
public string HexString { get; set; }
}
}

View File

@ -1,26 +0,0 @@
<UserControl
x:Class="ColorPickerWPF.ColorPickRow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="28" d:DesignWidth="188" Height="28" VerticalContentAlignment="Center">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="28" />
<ColumnDefinition Width="*" MinWidth="76" />
<ColumnDefinition Width="84" />
</Grid.ColumnDefinitions>
<Grid>
<Border BorderBrush="Black" BorderThickness="1">
<Grid x:Name="ColorDisplayGrid" Background="#FFFFFFFF" />
</Border>
</Grid>
<TextBlock x:Name="HexLabel" Grid.Column="1" Text="#FFFFFFFF" HorizontalAlignment="Left" Margin="8,0,4,0" VerticalAlignment="Center"></TextBlock>
<Button x:Name="PickColorButton" Content="Pick..." Grid.Column="2" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" Height="28"
Click="PickColorButton_OnClick"/>
</Grid>
</UserControl>

View File

@ -1,89 +0,0 @@
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:colorPickerWpf="clr-namespace:ColorPickerWPF"
x:Class="ColorPickerWPF.ColorPickerControl"
mc:Ignorable="d" d:DesignWidth="560" d:DesignHeight="380" MinHeight="380">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="326" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="286" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid>
<TabControl x:Name="TabControl" Margin="0,0,0,0"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="#7F748198">
<TabItem Header="Picker 1" BorderBrush="#7F748198">
<Grid>
<Image x:Name="SampleImage" Source="pack://application:,,,/Resources/colorpicker1.png" HorizontalAlignment="Center" Margin="0" VerticalAlignment="Bottom"
Width="320" Height="240"
MouseDown="SampleImage_OnMouseDown"/>
</Grid>
</TabItem>
<TabItem Header="Picker 2" BorderBrush="#7F748198">
<Grid>
<Image x:Name="SampleImage2" Source="pack://application:,,,/Resources/colorpicker2.png" HorizontalAlignment="Left" Margin="2" VerticalAlignment="Top"
Width="254" Height="254"
MouseDown="SampleImage2_OnMouseDown"/>
<Label x:Name="label" Content="Hue" HorizontalAlignment="Left" Margin="261,2,0,0" VerticalAlignment="Top"/>
<Slider x:Name="PickerHueSlider" HorizontalAlignment="Left" Margin="268,33,0,0" VerticalAlignment="Top"
Orientation="Vertical" Height="199" ValueChanged="PickerHueSlider_OnValueChanged" Maximum="360" SmallChange="1" Minimum="1" LargeChange="30"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
<Grid Grid.Column="1" Grid.RowSpan="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Label x:Name="rgbLabel" Content="Red, Green, Blue, Alpha" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<colorPickerWpf:SliderRow x:Name="RSlider" HorizontalAlignment="Stretch" Margin="0,26,0,0" VerticalAlignment="Top"
OnValueChanged="RSlider_OnOnValueChanged" FormatString="F0" />
<colorPickerWpf:SliderRow x:Name="GSlider" HorizontalAlignment="Stretch" Margin="0,54,0,0" VerticalAlignment="Top"
OnValueChanged="GSlider_OnOnValueChanged" FormatString="F0"/>
<colorPickerWpf:SliderRow x:Name="BSlider" HorizontalAlignment="Stretch" Margin="0,82,0,0" VerticalAlignment="Top"
OnValueChanged="BSlider_OnOnValueChanged" FormatString="F0"/>
<colorPickerWpf:SliderRow x:Name="ASlider" HorizontalAlignment="Stretch" Margin="0,110,0,0" VerticalAlignment="Top"
OnValueChanged="ASlider_OnOnValueChanged" FormatString="F0"/>
<Label x:Name="hsvLabel" Content="Hue, Saturation, Value" HorizontalAlignment="Left" Margin="0,143,0,0" VerticalAlignment="Top"/>
<colorPickerWpf:SliderRow x:Name="HSlider" HorizontalAlignment="Stretch" Margin="0,169,0,0" VerticalAlignment="Top"
OnValueChanged="HSlider_OnOnValueChanged" FormatString="F0"/>
<colorPickerWpf:SliderRow x:Name="SSlider" HorizontalAlignment="Stretch" Margin="0,197,0,0" VerticalAlignment="Top"
OnValueChanged="SSlider_OnOnValueChanged"/>
<colorPickerWpf:SliderRow x:Name="LSlider" HorizontalAlignment="Stretch" Margin="0,225,0,0" VerticalAlignment="Top"
OnValueChanged="LSlider_OnOnValueChanged"/>
<colorPickerWpf:ColorPickerSwatch x:Name="CustomColorSwatch" HorizontalAlignment="Left" Margin="4,289,0,0" VerticalAlignment="Stretch" Width="230"
Editable="true" OnPickColor="Swatch_OnOnPickColor"/>
<Label x:Name="customColorsLabel" Content="Custom Colors (Ctrl+Click to set)" HorizontalAlignment="Left" Margin="0,258,0,0" VerticalAlignment="Top"/>
</Grid>
<Grid Grid.Row="1" Grid.Column="0" Margin="3">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Grid.Row="0">
<Border x:Name="ColorDisplayBorder" HorizontalAlignment="Left" VerticalAlignment="Top"
BorderBrush="Black" Background="White" BorderThickness="2" Width="58" Height="58" Margin="0,0,0,0"/>
<colorPickerWpf:ColorPickerSwatch x:Name="Swatch1" HorizontalAlignment="Left" Height="60" Margin="60,0,0,0" VerticalAlignment="Top" Width="260"
OnPickColor="Swatch_OnOnPickColor"/>
</Grid>
<colorPickerWpf:ColorPickerSwatch x:Name="Swatch2" HorizontalAlignment="Stretch" Margin="0,0,0,0" Grid.Row="1" VerticalAlignment="Stretch"
OnPickColor="Swatch_OnOnPickColor"/>
</Grid>
</Grid>
</UserControl>

View File

@ -1,27 +0,0 @@
<UserControl x:Class="ColorPickerWPF.ColorPickerSwatch"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<ItemsControl x:Name="SwatchListBox"
Margin="0"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" Background="{Binding HexString}" BorderThickness="0" Width="20" Height="20" Margin="0,0,0,0" MouseDown="UIElement_OnMouseDown">
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>

View File

@ -1,23 +0,0 @@
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:colorPickerWpf="clr-namespace:ColorPickerWPF"
x:Class="ColorPickerWPF.ColorPickerWindow"
mc:Ignorable="d"
Style="{StaticResource {x:Type Window}}"
Title="Color Picker" Width="574" MinWidth="342" SizeToContent="Height" MinHeight="450" Icon="/FModel;component/Logo.ico" ResizeMode="CanMinimize">
<DockPanel LastChildFill="False">
<colorPickerWpf:ColorPickerControl x:Name="ColorPicker" DockPanel.Dock="Top" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" MinHeight="372"/>
<Grid DockPanel.Dock="Bottom" MinHeight="47">
<Button x:Name="CloseButton" Content="Close" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="90,10,0,0" Height="27" Click="CloseButton_Click" IsCancel="True"/>
<Button x:Name="OKButton" Content="OK" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="10,10,0,10" Height="27" Click="OKButton_Click" IsDefault="True"/>
<Button x:Name="MinMaxViewButton" Content="&lt;&lt; Simple" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Margin="243,10,0,0" Height="27" Click="MinMaxViewButton_OnClick"/>
</Grid>
</DockPanel>
</Window>

View File

@ -1,15 +0,0 @@
using System.Windows;
namespace FModel.Forms
{
/// <summary>
/// Logique d'interaction pour FModel_About.xaml
/// </summary>
public partial class FModel_About : Window
{
public FModel_About()
{
InitializeComponent();
}
}
}

View File

@ -1,34 +0,0 @@
<Window x:Class="FModel.Forms.FModel_ImagesMerger"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel.Forms"
mc:Ignorable="d"
Title="Images Merger" Height="467.333" Width="800"
Style="{StaticResource {x:Type Window}}" WindowStartupLocation="CenterScreen" Icon="/FModel;component/Logo.ico"
UseLayoutRounding="True" ResizeMode="CanMinimize" Loaded="Window_Loaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="143*"/>
<ColumnDefinition Width="123*"/>
</Grid.ColumnDefinitions>
<GroupBox Header="Images" Margin="10,10,0,0" BorderBrush="#7F748198" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="401" Height="409">
<Grid>
<ListBox x:Name="ImagesListBox" Margin="0,40,0,0" SelectionMode="Extended"/>
<Button x:Name="AddImages_Button" Content="Add" HorizontalAlignment="Left" Margin="0,10,0,0" VerticalAlignment="Top" Width="100" Click="AddImages_Button_Click"/>
<Button x:Name="Up_Button" Content="🡹" HorizontalAlignment="Left" Margin="110,10,0,0" VerticalAlignment="Top" Width="30" Click="Up_Button_Click"/>
<Button x:Name="Down_Button" Content="🡻" HorizontalAlignment="Left" Margin="145,10,0,0" VerticalAlignment="Top" Width="30" Click="Down_Button_Click"/>
<Button x:Name="RemoveImage_Button" Content="Remove" HorizontalAlignment="Center" Margin="184,10,105,0" VerticalAlignment="Top" Width="100" Click="RemoveImage_Button_Click"/>
<Button x:Name="ClearImages_Button" Content="Clear" HorizontalAlignment="Right" Margin="0,10,0,0" VerticalAlignment="Top" Width="100" Click="ClearImages_Button_Click"/>
</Grid>
</GroupBox>
<Border BorderBrush="#7F748198" BorderThickness="1" Grid.Column="1" Background="#FF252D36" Margin="0,19,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Height="350" Width="350">
<Image x:Name="MergerPreview_Image" UseLayoutRounding="True"/>
</Border>
<Slider x:Name="ImagesPerRow_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdatePreview" HorizontalAlignment="Left" VerticalAlignment="Top" Maximum="20" Minimum="1" Value="7" Width="350" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" Grid.Column="1" Margin="0,374,0,0" IsSnapToTickEnabled="True"/>
<Button x:Name="SaveImage_Button" Content="Save Image" Grid.Column="1" HorizontalAlignment="Left" Margin="250,400,0,0" VerticalAlignment="Top" Width="100" Click="SaveImage_Button_Click"/>
<Button x:Name="OpenImage_Button" Content="Open Image" Grid.Column="1" HorizontalAlignment="Left" Margin="0,400,0,0" VerticalAlignment="Top" Width="100" Click="OpenImage_Button_Click"/>
</Grid>
</Window>

View File

@ -1,308 +0,0 @@
using FModel.Methods.Utilities;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using FProp = FModel.Properties.Settings;
namespace FModel.Forms
{
/// <summary>
/// Logique d'interaction pour FModel_ImagesMerger.xaml
/// </summary>
public partial class FModel_ImagesMerger : Window
{
private static List<string> _imagePath { get; set; }
public FModel_ImagesMerger()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
ImagesListBox.Items.Clear();
}
private async void UpdatePreview(object sender, RoutedEventArgs e)
{
if (MergerPreview_Image.Source != null)
{
await UpdateMergerPreview();
}
}
private async Task UpdateMergerPreview()
{
DebugHelper.WriteLine("Merger: Merging images of the listbox");
AddImages_Button.IsEnabled = false;
RemoveImage_Button.IsEnabled = false;
ClearImages_Button.IsEnabled = false;
ImagesPerRow_Slider.IsEnabled = false;
OpenImage_Button.IsEnabled = false;
SaveImage_Button.IsEnabled = false;
if ((_imagePath != null && _imagePath.Count > 0) || ImagesListBox.Items.Count > 0)
{
_imagePath = new List<string>();
for (int i = 0; i < ImagesListBox.Items.Count; ++i)
{
_imagePath.Add(((ListBoxItem)ImagesListBox.Items[i]).ContentStringFormat);
}
}
int imageCount = _imagePath.Count;
int numperrow = Convert.ToInt32(ImagesPerRow_Slider.Value);
await Task.Run(() =>
{
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
//INITIALIZATION
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(515, 515)));
int num = 1;
int curW = 0;
int curH = 0;
int maxHeight = 0;
for (int i = 0; i < imageCount; i++)
{
BitmapImage source = new BitmapImage(new Uri(_imagePath[i]));
source.DecodePixelWidth = 515;
double width = source.Width;
double height = source.Height;
if (height > maxHeight) { maxHeight = Convert.ToInt32(height); }
drawingContext.DrawImage(source, new Rect(new Point(curW, curH), new Size(width, height)));
if (num % numperrow == 0)
{
curW = 0;
curH += maxHeight + 5;
num += 1;
maxHeight = 0; //reset max height for each new row
}
else
{
curW += Convert.ToInt32(width) + 5;
num += 1;
}
}
}
RenderTargetBitmap RTB = new RenderTargetBitmap((int)Math.Floor(drawingVisual.DescendantBounds.Width), (int)Math.Floor(drawingVisual.DescendantBounds.Height), 96, 96, PixelFormats.Pbgra32);
RTB.Render(drawingVisual);
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
this.Dispatcher.InvokeAsync(() =>
{
MergerPreview_Image.Source = BitmapFrame.Create(RTB); //thread safe and fast af
});
}).ContinueWith(TheTask =>
{
TasksUtility.TaskCompleted(TheTask.Exception);
});
GC.Collect();
GC.WaitForPendingFinalizers();
AddImages_Button.IsEnabled = true;
RemoveImage_Button.IsEnabled = true;
ClearImages_Button.IsEnabled = true;
ImagesPerRow_Slider.IsEnabled = true;
OpenImage_Button.IsEnabled = true;
SaveImage_Button.IsEnabled = true;
DebugHelper.WriteLine("Merger: Images of the listbox merged successfully");
}
private async void AddImages_Button_Click(object sender, RoutedEventArgs e)
{
OpenFileDialog openFiledialog = new OpenFileDialog();
openFiledialog.Title = "Choose your images";
openFiledialog.InitialDirectory = FProp.Default.FOutput_Path + "\\Icons\\";
openFiledialog.Multiselect = true;
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
if (openFiledialog.ShowDialog() == true)
{
AddFiles(openFiledialog.FileNames);
await UpdateMergerPreview();
}
}
private void AddFiles(string[] files)
{
if (files.Length > 0)
{
foreach (string file in files)
{
ListBoxItem itm = new ListBoxItem();
itm.ContentStringFormat = file;
itm.Content = Path.GetFileNameWithoutExtension(file);
ImagesListBox.Items.Add(itm);
DebugHelper.WriteLine($"Merger: {file} added to the listbox");
}
}
}
private async void RemoveImage_Button_Click(object sender, RoutedEventArgs e)
{
if (ImagesListBox.Items.Count > 0 && ImagesListBox.SelectedItems.Count > 0)
{
for (int i = ImagesListBox.SelectedItems.Count - 1; i >= 0; --i)
{
ImagesListBox.Items.Remove(ImagesListBox.SelectedItems[i]);
}
await UpdateMergerPreview();
}
}
private void ClearImages_Button_Click(object sender, RoutedEventArgs e)
{
ImagesListBox.Items.Clear();
MergerPreview_Image.Source = null;
}
private void OpenImage_Button_Click(object sender, RoutedEventArgs e)
{
if (MergerPreview_Image.Source != null)
{
DebugHelper.WriteLine("Merger: Opening preview of the merged image");
if (!FormsUtility.IsWindowOpen<Window>("Merged Image"))
{
Window win = new Window();
win.Title = "Merged Image";
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
win.Width = MergerPreview_Image.Source.Width;
win.Height = MergerPreview_Image.Source.Height;
if (MergerPreview_Image.Source.Height > 1000)
{
win.WindowState = WindowState.Maximized;
}
DockPanel dockPanel = new DockPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
Image img = new Image();
img.UseLayoutRounding = true;
img.Source = MergerPreview_Image.Source;
dockPanel.Children.Add(img);
win.Content = dockPanel;
win.Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Merged Image").Focus(); }
}
}
private void SaveImage_Button_Click(object sender, RoutedEventArgs e)
{
if (MergerPreview_Image.Source != null)
{
DebugHelper.WriteLine("Merger: Saving image...");
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Title = "Save Image";
saveFileDialog.FileName = "Merger";
saveFileDialog.InitialDirectory = FProp.Default.FOutput_Path;
saveFileDialog.Filter = "PNG Files (*.png)|*.png";
if (saveFileDialog.ShowDialog() == true)
{
string path = saveFileDialog.FileName;
using (var fileStream = new FileStream(path, FileMode.Create))
{
PngBitmapEncoder encoder = new PngBitmapEncoder();
encoder.Frames.Add(BitmapFrame.Create((BitmapSource)MergerPreview_Image.Source));
encoder.Save(fileStream);
if (File.Exists(path))
{
DebugHelper.WriteLine("Merger: Image saved at " + path);
new UpdateMyConsole(Path.GetFileNameWithoutExtension(path), CColors.Blue).Append();
new UpdateMyConsole(" successfully saved", CColors.White, true).Append();
}
else //just in case
{
DebugHelper.WriteLine("Merger: Image couldn't be saved at " + path);
new UpdateMyConsole("Bruh moment\nCouldn't save ", CColors.White).Append();
new UpdateMyConsole(Path.GetFileNameWithoutExtension(path), CColors.Blue, true).Append();
}
}
}
}
}
private async void Up_Button_Click(object sender, RoutedEventArgs e)
{
if (ImagesListBox.Items.Count > 0 && ImagesListBox.SelectedItems.Count > 0)
{
bool reloadImage = false;
int[] indices = ImagesListBox.SelectedItems.Cast<object>().Select(i => ImagesListBox.Items.IndexOf(i)).ToArray();
if (indices.Length > 0 && indices[0] > 0)
{
for (int i = 0; i < ImagesListBox.Items.Count; i++)
{
if (indices.Contains(i))
{
object moveItem = ImagesListBox.Items[i];
ImagesListBox.Items.Remove(moveItem);
ImagesListBox.Items.Insert(i - 1, moveItem);
((ListBoxItem)moveItem).IsSelected = true;
reloadImage = true;
}
}
}
ImagesListBox.SelectedItems.Add(indices);
if (reloadImage)
await UpdateMergerPreview();
}
}
private async void Down_Button_Click(object sender, RoutedEventArgs e)
{
if (ImagesListBox.Items.Count > 0 && ImagesListBox.SelectedItems.Count > 0)
{
bool reloadImage = false;
int[] indices = ImagesListBox.SelectedItems.Cast<object>().Select(i => ImagesListBox.Items.IndexOf(i)).ToArray();
if (indices.Length > 0 && indices[indices.Length - 1] < ImagesListBox.Items.Count - 1)
{
for (int i = ImagesListBox.Items.Count - 1; i > -1; --i)
{
if (indices.Contains(i))
{
object moveItem = ImagesListBox.Items[i];
ImagesListBox.Items.Remove(moveItem);
ImagesListBox.Items.Insert(i + 1, moveItem);
((ListBoxItem)moveItem).IsSelected = true;
reloadImage = true;
}
}
}
if (reloadImage)
await UpdateMergerPreview();
}
}
}
}

View File

@ -1,50 +0,0 @@
<Window x:Class="FModel.Forms.FModel_SearchFiles"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel.Forms"
mc:Ignorable="d"
Title="Search"
Height="700"
Width="1100"
Style="{StaticResource {x:Type Window}}"
WindowStartupLocation="CenterScreen"
Icon="/FModel;component/Logo.ico"
UseLayoutRounding="True" Loaded="Window_Loaded">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60*"/>
<ColumnDefinition Width="20*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="7*"/>
<RowDefinition Height="103*"/>
</Grid.RowDefinitions>
<Label Content="Filter:" VerticalAlignment="Center" Height="24" Grid.Row="0" Grid.Column="0" HorizontalAlignment="Left"/>
<TextBox x:Name="FilterTextBox_Search" Height="20" Margin="38,12,10,11" TextWrapping="NoWrap" VerticalAlignment="Center" Foreground="#FFEFEFEF" Grid.Row="0" Grid.Column="0" TextChanged="FilterTextBox_Search_TextChanged"/>
<DataGrid x:Name="DataGrid_Search" Margin="0,0,0,0" HeadersVisibility="Column" ItemsSource="{Binding FileNames}" IsReadOnly="True" BorderBrush="#7F748198" ColumnHeaderHeight="25" AutoGenerateColumns="True" ColumnWidth="*" Grid.Row="1" Grid.ColumnSpan="2">
<DataGrid.ContextMenu>
<ContextMenu>
<MenuItem x:Name="RC_GoTo" Header="Go To" Click="GoTo_Button_Click"/>
<MenuItem x:Name="RC_ExportData" Header="Export RAW Data" Click="RC_ExportData_Click"/>
<Separator/>
<MenuItem Header="Copy File">
<MenuItem x:Name="RC_Copy_FPath" Header="Copy File Path" Click="RC_Copy_FPath_Click"/>
<MenuItem x:Name="RC_Copy_FName" Header="Copy File Name" Click="RC_Copy_FName_Click"/>
<MenuItem x:Name="RC_Copy_FPath_NoExt" Header="Copy File Path w/o Extension" Click="RC_Copy_FPath_NoExt_Click"/>
<MenuItem x:Name="RC_Copy_FName_NoExt" Header="Copy File Name w/o Extension" Click="RC_Copy_FName_NoExt_Click"/>
</MenuItem>
<Separator/>
<MenuItem x:Name="RC_Properties" Header="Properties" Click="RC_Properties_Click">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/info_16x.png" Width="16" Height="16"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</DataGrid.ContextMenu>
</DataGrid>
<Button x:Name="GoTo_Button" Content="Go To Selected Asset" Grid.Column="1" HorizontalAlignment="Left" VerticalAlignment="Center" Width="120" Click="GoTo_Button_Click" Margin="10,0,0,0"/>
<Label x:Name="FoundNumber_Label" Content="Found 0 asset" Grid.Column="1" HorizontalAlignment="Right" VerticalAlignment="Center" Margin="0,0,10,0" Padding="0"/>
</Grid>
</Window>

View File

@ -1,284 +0,0 @@
using FModel.Methods;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows;
using PakReader;
using FModel.Methods.Utilities;
using System.IO;
using FModel.Methods.Assets;
using FProp = FModel.Properties.Settings;
using System;
using System.Globalization;
namespace FModel.Forms
{
/// <summary>
/// Logique d'interaction pour FModel_SearchFiles.xaml
/// </summary>
public partial class FModel_SearchFiles : Window
{
private static List<FileInfo> FileNames { get; set; }
public class FileInfo
{
public string Name { get; set; }
public string Extension { get; set; }
public string PAK { get; set; }
}
public class GridViewItem : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string name)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
public FModel_SearchFiles()
{
InitializeComponent();
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
if (PAKEntries.PAKToDisplay != null)
{
DebugHelper.WriteLine("SearchFiles: Populating DataGrid...");
FilterTextBox_Search.IsReadOnly = true;
FileNames = new List<FileInfo>();
await PopulateDataGrid();
DataGrid_Search.ItemsSource = FileNames;
FilterTextBox_Search.IsReadOnly = false;
DebugHelper.WriteLine("SearchFiles: Populated DataGrid");
}
}
private async Task PopulateDataGrid()
{
Dictionary<string, string> IfExistChecker = new Dictionary<string, string>();
int i = 0;
await Task.Run(() =>
{
if (!string.IsNullOrEmpty(FWindow.FCurrentPAK))
{
FPakEntry[] ohyeah = PAKEntries.PAKToDisplay[FWindow.FCurrentPAK];
FillList(ohyeah, IfExistChecker);
i = ohyeah.Length;
}
else
{
foreach (FPakEntry[] PAKsFileInfos in PAKEntries.PAKToDisplay.Values)
{
FillList(PAKsFileInfos, IfExistChecker);
i += PAKsFileInfos.Length;
}
}
}).ContinueWith(TheTask =>
{
TasksUtility.TaskCompleted(TheTask.Exception);
});
//max = million
string number = i.ToString("# ### ###", new NumberFormatInfo { NumberGroupSeparator = " " }).Trim();
DebugHelper.WriteLine($"SearchFiles: Loaded {number} assets");
FoundNumber_Label.Content = $"Found {number} assets";
}
private static void FillList(FPakEntry[] EntryArray, Dictionary<string, string> ExistChecker)
{
foreach (FPakEntry entry in EntryArray)
{
string filename = entry.Name;
string ext = Path.GetExtension(entry.Name);
string pak = Path.GetFileName(AssetEntries.AssetEntriesDict[entry.Name].Name);
if (filename.EndsWith(".uasset") || filename.EndsWith(".uexp") || filename.EndsWith(".ubulk"))
{
filename = filename.Substring(0, filename.LastIndexOf('.'));
if (AssetEntries.ArraySearcher.ContainsKey(filename + ".uexp"))
{
ext += " .uexp";
}
if (AssetEntries.ArraySearcher.ContainsKey(filename + ".ubulk"))
{
ext += " .ubulk";
}
filename += ".uasset";
}
if (!ExistChecker.ContainsKey(filename))
{
ExistChecker.Add(filename, pak);
FileNames.Add(new FileInfo
{
Name = filename,
Extension = ext,
PAK = pak
});
}
}
}
private async void FilterTextBox_Search_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
if (PAKEntries.PAKToDisplay != null && FileNames != null)
{
List<FileInfo> filtered = new List<FileInfo>();
string[] filters = FilterTextBox_Search.Text.Trim().Split(' ');
await Task.Run(() =>
{
foreach (FileInfo fi in FileNames)
{
bool checkSearch = false;
if (filters.Length > 1)
{
foreach (string filter in filters)
{
checkSearch = ListBoxUtility.CaseInsensitiveContains(fi.Name, filter);
if (!checkSearch) { break; }
}
}
else { checkSearch = ListBoxUtility.CaseInsensitiveContains(fi.Name, filters[0]); }
if (checkSearch)
{
filtered.Add(fi);
}
}
});
DataGrid_Search.ItemsSource = filtered;
}
}
#region RIGHT CLICK
private void RC_Copy_FPath_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
Clipboard.SetText(selectedName.Substring(1));
}
}
private void RC_Copy_FName_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
Clipboard.SetText(Path.GetFileName(selectedName));
}
}
private void RC_Copy_FPath_NoExt_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
Clipboard.SetText(FoldersUtility.GetFullPathWithoutExtension(selectedName).Substring(1));
}
}
private void RC_Copy_FName_NoExt_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
Clipboard.SetText(Path.GetFileNameWithoutExtension(selectedName));
}
}
private void RC_Properties_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
if (selectedName.EndsWith(".uasset"))
{
selectedName = selectedName.Substring(0, selectedName.LastIndexOf('.'));
}
FWindow.FCurrentAsset = selectedName;
AssetInformations.OpenAssetInfos(true);
}
}
private void GoTo_Button_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
if (selectedName.EndsWith(".uasset"))
{
selectedName = selectedName.Substring(0, selectedName.LastIndexOf('.'));
}
FWindow.FCurrentAsset = selectedName;
TreeViewUtility.JumpToFolder(selectedName.Substring(1, selectedName.LastIndexOf("/") - 1));
FWindow.FMain.ListBox_Main.SelectedValue = selectedName.Substring(selectedName.LastIndexOf("/") + 1);
Close();
}
}
private void RC_ExportData_Click(object sender, RoutedEventArgs e)
{
if (DataGrid_Search.SelectedIndex >= 0)
{
FileInfo item = (FileInfo)DataGrid_Search.SelectedItem;
string selectedName = item.Name;
if (selectedName.EndsWith(".uasset"))
{
selectedName = selectedName.Substring(0, selectedName.LastIndexOf('.'));
}
PakReader.PakReader reader = AssetsUtility.GetPakReader(selectedName);
if (reader != null)
{
List<FPakEntry> entriesList = AssetsUtility.GetPakEntries(selectedName);
foreach (FPakEntry entry in entriesList)
{
string path = FProp.Default.FOutput_Path + "\\Exports\\" + entry.Name;
string pWExt = FoldersUtility.GetFullPathWithoutExtension(entry.Name);
string subfolders = pWExt.Substring(0, pWExt.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase));
Directory.CreateDirectory(FProp.Default.FOutput_Path + "\\Exports\\" + subfolders);
Stream stream = reader.GetPackageStream(entry);
using (var fStream = File.OpenWrite(path))
using (stream)
{
stream.CopyTo(fStream);
}
if (File.Exists(path))
{
new UpdateMyConsole(Path.GetFileName(path), CColors.Blue).Append();
new UpdateMyConsole(" successfully exported", CColors.White, true).Append();
}
else //just in case
{
new UpdateMyConsole("Bruh moment\nCouldn't export ", CColors.White).Append();
new UpdateMyConsole(Path.GetFileName(path), CColors.Blue, true).Append();
}
}
}
}
}
#endregion
}
}

View File

@ -1,107 +0,0 @@
<Window x:Class="FModel.Forms.FModel_Settings"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel.Forms"
mc:Ignorable="d"
Title="Settings"
Height="581.5"
Width="610"
Style="{StaticResource {x:Type Window}}"
WindowStartupLocation="CenterScreen"
Icon="/FModel;component/Logo.ico"
ResizeMode="CanMinimize" Loaded="Window_Loaded"
>
<Grid>
<GroupBox Header=".PAK Files" HorizontalAlignment="Left" Height="70" Margin="10,10,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
<Grid>
<Label Content="Input:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,1,0,0"/>
<TextBox x:Name="InputTextBox" Height="19" Margin="41,4,35,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
<Button x:Name="BrowseInput_Button" Content="..." HorizontalAlignment="Left" Margin="532,4,0,0" VerticalAlignment="Top" Width="20" Click="BrowseInput_Button_Click"/>
<CheckBox x:Name="bDiffFileSize" Content="Diff w/ File Size" HorizontalAlignment="Left" Margin="10,31,0,0" VerticalAlignment="Top"/>
<CheckBox x:Name="bReloadAES" Content="Reload AES Keys at Launch" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="124,31,0,0" IsChecked="True"/>
<CheckBox x:Name="bOpenSounds" Content="Auto Open Sounds" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="292,31,0,0" IsChecked="True"/>
</Grid>
</GroupBox>
<GroupBox Header="Extraction" HorizontalAlignment="Left" Height="48" Margin="10,85,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
<Grid>
<Label Content="Output:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,-1"/>
<TextBox x:Name="OutputTextBox" Height="19" Margin="50,4,35,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
<Button x:Name="BrowseOutput_Button" Content="..." HorizontalAlignment="Left" Margin="532,4,0,0" VerticalAlignment="Top" Width="20" Click="BrowseOutput_Button_Click"/>
</Grid>
</GroupBox>
<GroupBox Header="Icon Creator" HorizontalAlignment="Left" Height="206" Margin="10,138,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
<Grid>
<Label Content="Language:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,0"/>
<ComboBox x:Name="ComboBox_Language" HorizontalAlignment="Left" Margin="61,5,0,0" VerticalAlignment="Top" Width="332" BorderBrush="#7F748198" Background="#FF333C46">
<ComboBoxItem Content="English"/>
<ComboBoxItem Content="French"/>
<ComboBoxItem Content="German"/>
<ComboBoxItem Content="Italian"/>
<ComboBoxItem Content="Spanish"/>
<ComboBoxItem Content="Spanish (LA)"/>
<ComboBoxItem Content="Arabic"/>
<ComboBoxItem Content="Japanese"/>
<ComboBoxItem Content="Korean"/>
<ComboBoxItem Content="Polish"/>
<ComboBoxItem Content="Portuguese (Brazil)"/>
<ComboBoxItem Content="Russian"/>
<ComboBoxItem Content="Turkish"/>
<ComboBoxItem Content="Chinese (S)"/>
<ComboBoxItem Content="Traditional Chinese"/>
</ComboBox>
<Label Content="Rarity Design:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,32,0,0"/>
<ComboBox x:Name="ComboBox_Design" HorizontalAlignment="Left" Margin="78,35,0,0" VerticalAlignment="Top" Width="315" BorderBrush="#7F748198" Background="#FF333C46" IsReadOnly="True" SelectionChanged="UpdateImageBox">
<ComboBoxItem Content="Default"/>
<ComboBoxItem Content="Flat"/>
<ComboBoxItem Content="Minimalist"/>
<ComboBoxItem Content="Accurate Colors"/>
</ComboBox>
<Border BorderThickness="1" BorderBrush="#7F748198" Background="#FF252D36" HorizontalAlignment="Right" Height="164" Margin="398,0,0,0" Width="164" VerticalAlignment="Top">
<Image x:Name="ImageBox_RarityPreview" Source="/FModel;component/Resources/Template_D_N.png" UseLayoutRounding="True"/>
</Border>
<CheckBox x:Name="bWatermarkIcon" Content="Watermark" HorizontalAlignment="Left" Margin="8,87,0,0" VerticalAlignment="Top" Checked="EnableDisableWatermark" Unchecked="EnableDisableWatermark"/>
<Button x:Name="OpenFile_Button" Content="+" HorizontalAlignment="Right" Margin="0,0,454,82" VerticalAlignment="Bottom" Width="19" IsEnabled="False" Click="OpenFile_Button_Click"/>
<Label x:Name="Watermark_Label" Content="File Name: " MaxWidth="240" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="108,83,0,0"/>
<Label Content="X Position:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,107,0,0"/>
<Slider x:Name="xPos_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="67,110,0,0" VerticalAlignment="Top" Maximum="509" Minimum="3" Width="326" Background="#FF525A63" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
<Label Content="Y Position:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,134,0,0"/>
<Slider x:Name="yPos_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="67,137,0,0" VerticalAlignment="Top" Maximum="509" Minimum="3" Width="326" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
<Label Content="Opacity:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,161,0,-2"/>
<Slider x:Name="Opacity_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="67,164,0,-1" VerticalAlignment="Top" Maximum="255" Width="138" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
<Label Content="Scale:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="212,161,0,-2"/>
<Slider x:Name="Scale_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="255,164,0,-1" VerticalAlignment="Top" Maximum="515" Width="138" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
<CheckBox x:Name="bFeaturedIcon" Content="Shop Item Icon" HorizontalAlignment="Left" Margin="305,59,0,0" VerticalAlignment="Top" Checked="UpdateImageBox" Unchecked="UpdateImageBox"/>
<Button x:Name="OpenIconCreator_Button" Content="Open Image" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="164" Click="OpenIconCreator_Button_Click"/>
</Grid>
</GroupBox>
<GroupBox Header="Challenges Theme" HorizontalAlignment="Left" Height="155" Margin="10,349,0,0" VerticalAlignment="Top" Width="574" BorderBrush="#7F748198">
<Grid>
<Label Content="Watermark:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,2,0,-1"/>
<TextBox x:Name="WatermarkChallenge_TextBox" Height="19" Margin="69,4,263,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF" TextChanged="UpdateChallengeCustomTheme"/>
<Label Content="Colors:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,82,0,0"/>
<Button x:Name="PrimaryColor_Button" Content="Primary" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="124" Margin="0,0,393,29" IsEnabled="False" Click="PrimaryColor_Button_Click"/>
<Button x:Name="SecondaryColor_Button" Content="Secondary" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="124" Margin="0,0,263,29" IsEnabled="False" Click="SecondaryColor_Button_Click"/>
<Button x:Name="AddBanner_Button" Content="+" HorizontalAlignment="Right" Margin="0,0,438,59" VerticalAlignment="Bottom" Width="19" IsEnabled="False" Click="AddBanner_Button_Click"/>
<Label x:Name="Banner_Label" Content="File Name: " MaxWidth="155" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="148,55,0,0"/>
<Button x:Name="DeleteBanner_Button" Content="-" HorizontalAlignment="Right" Margin="0,0,414,59" VerticalAlignment="Bottom" Width="19" IsEnabled="False" Click="DeleteBanner_Button_Click"/>
<Label Content="Opacity:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="2,111,0,-3"/>
<Slider x:Name="OpacityBanner_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateChallengeCustomTheme" HorizontalAlignment="Left" Margin="57,112,0,0" VerticalAlignment="Top" Maximum="255" Width="242" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
<CheckBox x:Name="bCustomChallenge" Content="Custom Theme" HorizontalAlignment="Left" Margin="6,59,0,0" VerticalAlignment="Top" Checked="EnableDisableCustomTheme" Unchecked="EnableDisableCustomTheme"/>
<Border BorderThickness="1" BorderBrush="#7F748198" Background="#FF252D36" HorizontalAlignment="Right" Height="105" Width="258" VerticalAlignment="Top" Margin="0,3,0,0">
<Image x:Name="ImageBox_ChallengePreview" Source="/FModel;component/Resources/Template_Challenge.png" UseLayoutRounding="True"/>
</Border>
<Button x:Name="OpenChallengeTheme_Button" Content="Open Image" HorizontalAlignment="Right" VerticalAlignment="Bottom" Width="258" Click="OpenChallengeTheme_Button_Click" Margin="0,0,0,3"/>
</Grid>
</GroupBox>
<Button Content="OK" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/>
</Grid>
</Window>

View File

@ -1,602 +0,0 @@
using FModel.Methods.MessageBox;
using System.Windows;
using System;
using System.Windows.Controls;
using System.ComponentModel;
using System.Reflection;
using System.Linq;
using System.Windows.Media;
using FModel.Methods.Assets;
using FModel.Methods;
using System.Windows.Media.Imaging;
using FModel.Methods.Utilities;
using System.IO;
using System.Threading.Tasks;
using Ookii.Dialogs.Wpf;
using System.Globalization;
using FModel.Methods.Assets.IconCreator;
using ColorPickerWPF;
using FProp = FModel.Properties.Settings;
namespace FModel.Forms
{
/// <summary>
/// Logique d'interaction pour FModel_Settings.xaml
/// </summary>
public partial class FModel_Settings : Window
{
private const string CHALLENGE_TEMPLATE_ICON = "pack://application:,,,/Resources/Template_Challenge.png";
private const string RARITY_DEFAULT_FEATURED = "pack://application:,,,/Resources/Template_D_F.png";
private const string RARITY_DEFAULT_NORMAL = "pack://application:,,,/Resources/Template_D_N.png";
private const string RARITY_FLAT_FEATURED = "pack://application:,,,/Resources/Template_F_F.png";
private const string RARITY_FLAT_NORMAL = "pack://application:,,,/Resources/Template_F_N.png";
private const string RARITY_MINIMALIST_FEATURED = "pack://application:,,,/Resources/Template_M_F.png";
private const string RARITY_MINIMALIST_NORMAL = "pack://application:,,,/Resources/Template_M_N.png";
private const string RARITY_ACCURATECOLORS_FEATURED = "pack://application:,,,/Resources/Template_AC_F.png";
private const string RARITY_ACCURATECOLORS_NORMAL = "pack://application:,,,/Resources/Template_AC_N.png";
public FModel_Settings()
{
InitializeComponent();
this.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
}
#region ENUMS
enum LIndexes
{
[Description("English")]
English = 0,
[Description("French")]
French = 1,
[Description("German")]
German = 2,
[Description("Italian")]
Italian = 3,
[Description("Spanish")]
Spanish = 4,
[Description("Spanish (LA)")]
Spanish_LA = 5,
[Description("Arabic")]
Arabic = 6,
[Description("Japanese")]
Japanese = 7,
[Description("Korean")]
Korean = 8,
[Description("Polish")]
Polish = 9,
[Description("Portuguese (Brazil)")]
Portuguese_Brazil = 10,
[Description("Russian")]
Russian = 11,
[Description("Turkish")]
Turkish = 12,
[Description("Chinese (S)")]
Chinese_S = 13,
[Description("Traditional Chinese")]
Traditional_Chinese = 14
}
enum RIndexes
{
[Description("Default")]
Default = 0,
[Description("Flat")]
Flat = 1,
[Description("Minimalist")]
Minimalist = 2,
[Description("Accurate Colors")]
Accurate = 3
}
public static T GetEnumValueFromDescription<T>(string description)
{
var type = typeof(T);
if (!type.IsEnum) { throw new ArgumentException("Enum type is null, bruh"); }
FieldInfo[] fields = type.GetFields();
var field = fields
.SelectMany(f => f.GetCustomAttributes(
typeof(DescriptionAttribute), false), (
f, a) => new { Field = f, Att = a })
.Where(a => ((DescriptionAttribute)a.Att)
.Description == description).SingleOrDefault();
return field == null ? default(T) : (T)field.Field.GetRawConstantValue();
}
#endregion
private void Window_Loaded(object sender, RoutedEventArgs e)
{
FoldersUtility.CheckWatermark();
GetUserSettings();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
SetUserSettings();
Close();
}
private async void GetUserSettings()
{
InputTextBox.Text = FProp.Default.FPak_Path;
bDiffFileSize.IsChecked = FProp.Default.FDiffFileSize;
OutputTextBox.Text = FProp.Default.FOutput_Path;
bReloadAES.IsChecked = FProp.Default.ReloadAES;
bOpenSounds.IsChecked = FProp.Default.FOpenSounds;
ComboBox_Language.SelectedIndex = (int)GetEnumValueFromDescription<LIndexes>(FProp.Default.FLanguage);
ComboBox_Design.SelectedIndex = (int)GetEnumValueFromDescription<RIndexes>(FProp.Default.FRarity_Design);
bFeaturedIcon.IsChecked = FProp.Default.FIsFeatured;
bWatermarkIcon.IsChecked = FProp.Default.FUseWatermark;
Watermark_Label.Content += Path.GetFileName(FProp.Default.FWatermarkFilePath);
Opacity_Slider.Value = FProp.Default.FWatermarkOpacity;
Scale_Slider.Value = FProp.Default.FWatermarkScale;
xPos_Slider.Value = FProp.Default.FWatermarkXPos;
yPos_Slider.Value = FProp.Default.FWatermarkYPos;
WatermarkChallenge_TextBox.Text = FProp.Default.FChallengeWatermark;
bCustomChallenge.IsChecked = FProp.Default.FUseChallengeWatermark;
Banner_Label.Content += Path.GetFileName(FProp.Default.FBannerFilePath);
OpacityBanner_Slider.Value = FProp.Default.FBannerOpacity;
await UpdateImageWithWatermark();
UpdateChallengeCustomTheme();
}
private void SetUserSettings()
{
bool restart = false;
if (!string.Equals(FProp.Default.FPak_Path, InputTextBox.Text))
{
FProp.Default.FPak_Path = InputTextBox.Text;
restart = true;
}
FProp.Default.FDiffFileSize = (bool)bDiffFileSize.IsChecked;
FProp.Default.ReloadAES = (bool)bReloadAES.IsChecked;
FProp.Default.FOpenSounds = (bool)bOpenSounds.IsChecked;
if (!string.Equals(FProp.Default.FOutput_Path, OutputTextBox.Text))
{
FProp.Default.FOutput_Path = OutputTextBox.Text;
restart = true;
}
if (AssetEntries.AssetEntriesDict != null && !string.Equals(FProp.Default.FLanguage, ((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString()))
{
AssetTranslations.SetAssetTranslation(((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString());
}
FProp.Default.FLanguage = ((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString();
FProp.Default.FRarity_Design = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
FProp.Default.FIsFeatured = (bool)bFeaturedIcon.IsChecked;
FProp.Default.FUseWatermark = (bool)bWatermarkIcon.IsChecked;
FProp.Default.FWatermarkOpacity = Convert.ToInt32(Opacity_Slider.Value);
FProp.Default.FWatermarkScale = Scale_Slider.Value;
FProp.Default.FWatermarkXPos = xPos_Slider.Value;
FProp.Default.FWatermarkYPos = yPos_Slider.Value;
FProp.Default.FChallengeWatermark = WatermarkChallenge_TextBox.Text;
FProp.Default.FUseChallengeWatermark = (bool)bCustomChallenge.IsChecked;
FProp.Default.FBannerOpacity = Convert.ToInt32(OpacityBanner_Slider.Value);
FProp.Default.Save();
if (restart)
{
DarkMessageBox.Show("FModel is about to restart because you applied your new path(s)", "FModel Path(s) Changed", MessageBoxButton.OK, MessageBoxImage.Information);
DebugHelper.WriteLine("FModel is restarting");
System.Windows.Forms.Application.Restart();
Application.Current.Shutdown();
}
else
DebugHelper.WriteUserSettings();
}
private async void UpdateImageBox(object sender, RoutedEventArgs e)
{
await UpdateImageWithWatermark();
}
private async void EnableDisableWatermark(object sender, RoutedEventArgs e)
{
OpenFile_Button.IsEnabled = (bool)bWatermarkIcon.IsChecked;
xPos_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
yPos_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
Opacity_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
Scale_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
await UpdateImageWithWatermark();
}
private void EnableDisableCustomTheme(object sender, RoutedEventArgs e)
{
AddBanner_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
DeleteBanner_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
PrimaryColor_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
SecondaryColor_Button.IsEnabled = (bool)bCustomChallenge.IsChecked;
OpacityBanner_Slider.IsEnabled = (bool)bCustomChallenge.IsChecked;
UpdateChallengeCustomTheme();
}
private async void UpdateImageWithWatermark(object sender, RoutedEventArgs e)
{
await UpdateImageWithWatermark();
}
private async Task UpdateImageWithWatermark()
{
bool watermarkEnabled = (bool)bWatermarkIcon.IsChecked;
string rarityDesign = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
bool isFeatured = (bool)bFeaturedIcon.IsChecked;
int opacity = Convert.ToInt32(Opacity_Slider.Value);
double scale = Scale_Slider.Value;
double xPos = xPos_Slider.Value;
double yPos = yPos_Slider.Value;
await Task.Run(() =>
{
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
//INITIALIZATION
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(515, 515)));
BitmapImage source = null;
switch (rarityDesign)
{
case "Default":
source = new BitmapImage(new Uri(isFeatured ? RARITY_DEFAULT_FEATURED : RARITY_DEFAULT_NORMAL));
break;
case "Flat":
source = new BitmapImage(new Uri(isFeatured ? RARITY_FLAT_FEATURED : RARITY_FLAT_NORMAL));
break;
case "Minimalist":
source = new BitmapImage(new Uri(isFeatured ? RARITY_MINIMALIST_FEATURED : RARITY_MINIMALIST_NORMAL));
break;
case "Accurate Colors":
source = new BitmapImage(new Uri(isFeatured ? RARITY_ACCURATECOLORS_FEATURED : RARITY_ACCURATECOLORS_NORMAL));
break;
}
drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(515, 515)));
if (!string.IsNullOrEmpty(FProp.Default.FWatermarkFilePath) && watermarkEnabled)
{
using (StreamReader image = new StreamReader(FProp.Default.FWatermarkFilePath))
{
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.StreamSource = image.BaseStream;
bmp.EndInit();
drawingContext.DrawImage(ImagesUtility.CreateTransparency(bmp, opacity), new Rect(xPos, yPos, bmp.Width * (scale / 515), bmp.Height * (scale / 515)));
}
}
}
RenderTargetBitmap RTB = new RenderTargetBitmap(515, 515, 96, 96, PixelFormats.Pbgra32);
RTB.Render(drawingVisual);
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
FWindow.FMain.Dispatcher.InvokeAsync(() =>
{
ImageBox_RarityPreview.Source = BitmapFrame.Create(RTB); //thread safe and fast af
});
}).ContinueWith(TheTask =>
{
TasksUtility.TaskCompleted(TheTask.Exception);
});
}
private void UpdateChallengeCustomTheme(object sender, RoutedEventArgs e)
{
UpdateChallengeCustomTheme();
}
private void UpdateChallengeCustomTheme()
{
bool watermarkEnabled = (bool)bCustomChallenge.IsChecked;
string watermark = WatermarkChallenge_TextBox.Text;
string path = FProp.Default.FBannerFilePath;
int opacity = Convert.ToInt32(OpacityBanner_Slider.Value);
string[] primaryParts = FProp.Default.FPrimaryColor.Split(':');
string[] secondaryParts = FProp.Default.FSecondaryColor.Split(':');
SolidColorBrush PrimaryColor = new SolidColorBrush(Color.FromRgb(Convert.ToByte(primaryParts[0]), Convert.ToByte(primaryParts[1]), Convert.ToByte(primaryParts[2])));
SolidColorBrush SecondaryColor = new SolidColorBrush(Color.FromRgb(Convert.ToByte(secondaryParts[0]), Convert.ToByte(secondaryParts[1]), Convert.ToByte(secondaryParts[2])));
if (watermarkEnabled)
{
DrawingVisual drawingVisual = new DrawingVisual();
double PPD = VisualTreeHelper.GetDpi(drawingVisual).PixelsPerDip;
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
//INITIALIZATION
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(1024, 410)));
Point dStart = new Point(0, 256);
LineSegment[] dSegments = new[]
{
new LineSegment(new Point(1024, 256), true),
new LineSegment(new Point(1024, 241), true),
new LineSegment(new Point(537, 236), true),
new LineSegment(new Point(547, 249), true),
new LineSegment(new Point(0, 241), true)
};
PathFigure dFigure = new PathFigure(dStart, dSegments, true);
PathGeometry dGeo = new PathGeometry(new[] { dFigure });
Typeface typeface = new Typeface(TextsUtility.Burbank, FontStyles.Normal, FontWeights.Black, FontStretches.Normal);
FormattedText formattedText =
new FormattedText(
"{BUNDLE DISPLAY NAME HERE}",
CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
typeface,
55,
Brushes.White,
PPD
);
formattedText.TextAlignment = TextAlignment.Left;
formattedText.MaxTextWidth = 768;
formattedText.MaxLineCount = 1;
Point textLocation = new Point(50, 165 - formattedText.Height);
drawingContext.DrawRectangle(PrimaryColor, null, new Rect(0, 0, 1024, 256));
if (!string.IsNullOrEmpty(path))
{
BitmapImage bmp = new BitmapImage(new Uri(path));
drawingContext.DrawImage(ImagesUtility.CreateTransparency(bmp, opacity), new Rect(0, 0, 1024, 256));
}
drawingContext.DrawGeometry(SecondaryColor, null, dGeo);
drawingContext.DrawText(formattedText, textLocation);
formattedText =
new FormattedText(
"{LAST FOLDER HERE}",
CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
typeface,
30,
SecondaryColor,
IconCreator.PPD
);
formattedText.TextAlignment = TextAlignment.Left;
formattedText.MaxTextWidth = 768;
formattedText.MaxLineCount = 1;
textLocation = new Point(50, 100 - formattedText.Height);
Geometry geometry = formattedText.BuildGeometry(textLocation);
Pen pen = new Pen(ChallengesUtility.DarkBrush(SecondaryColor, 0.3f), 1);
pen.LineJoin = PenLineJoin.Round;
drawingContext.DrawGeometry(SecondaryColor, pen, geometry);
typeface = new Typeface(TextsUtility.FBurbank, FontStyles.Normal, FontWeights.Normal, FontStretches.Normal);
formattedText =
new FormattedText(
watermark,
CultureInfo.CurrentUICulture,
FlowDirection.LeftToRight,
typeface,
20,
new SolidColorBrush(Color.FromArgb(150, 255, 255, 255)),
IconCreator.PPD
);
formattedText.TextAlignment = TextAlignment.Right;
formattedText.MaxTextWidth = 1014;
formattedText.MaxLineCount = 1;
textLocation = new Point(0, 205);
drawingContext.DrawText(formattedText, textLocation);
LinearGradientBrush linGrBrush = new LinearGradientBrush();
linGrBrush.StartPoint = new Point(0, 0);
linGrBrush.EndPoint = new Point(0, 1);
linGrBrush.GradientStops.Add(new GradientStop(Color.FromArgb(75, SecondaryColor.Color.R, SecondaryColor.Color.G, SecondaryColor.Color.B), 0));
linGrBrush.GradientStops.Add(new GradientStop(Color.FromArgb(25, PrimaryColor.Color.R, PrimaryColor.Color.G, PrimaryColor.Color.B), 0.15));
linGrBrush.GradientStops.Add(new GradientStop(Color.FromArgb(0, 0, 0, 0), 1));
drawingContext.DrawRectangle(ChallengesUtility.DarkBrush(PrimaryColor, 0.3f), null, new Rect(0, 256, 1024, 144));
drawingContext.DrawRectangle(linGrBrush, null, new Rect(0, 256, 1024, 144));
typeface = new Typeface(TextsUtility.Burbank, FontStyles.Normal, FontWeights.Black, FontStretches.Normal);
int y = 300;
drawingContext.DrawRectangle(ChallengesUtility.DarkBrush(PrimaryColor, 0.3f), null, new Rect(0, y, 1024, 90));
drawingContext.DrawRectangle(PrimaryColor, null, new Rect(25, y, 1024 - 50, 70));
dStart = new Point(32, y + 5);
dSegments = new[]
{
new LineSegment(new Point(29, y + 67), true),
new LineSegment(new Point(1024 - 160, y + 62), true),
new LineSegment(new Point(1024 - 150, y + 4), true)
};
dFigure = new PathFigure(dStart, dSegments, true);
dGeo = new PathGeometry(new[] { dFigure });
drawingContext.DrawGeometry(ChallengesUtility.LightBrush(PrimaryColor, 0.04f), null, dGeo);
drawingContext.DrawRectangle(SecondaryColor, null, new Rect(60, y + 47, 500, 7));
dStart = new Point(39, y + 35);
dSegments = new[]
{
new LineSegment(new Point(45, y + 32), true),
new LineSegment(new Point(48, y + 37), true),
new LineSegment(new Point(42, y + 40), true)
};
dFigure = new PathFigure(dStart, dSegments, true);
dGeo = new PathGeometry(new[] { dFigure });
drawingContext.DrawGeometry(SecondaryColor, null, dGeo);
}
if (drawingVisual != null)
{
RenderTargetBitmap RTB = new RenderTargetBitmap(1024, 410, 96, 96, PixelFormats.Pbgra32);
RTB.Render(drawingVisual);
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
FWindow.FMain.Dispatcher.InvokeAsync(() =>
{
ImageBox_ChallengePreview.Source = BitmapFrame.Create(RTB); //thread safe and fast af
});
}
}
else
{
BitmapImage source = new BitmapImage(new Uri(CHALLENGE_TEMPLATE_ICON));
ImageBox_ChallengePreview.Source = source;
}
}
private void OpenIconCreator_Button_Click(object sender, RoutedEventArgs e)
{
if (ImageBox_RarityPreview.Source != null)
{
if (!FormsUtility.IsWindowOpen<Window>("Icon Template"))
{
Window win = new Window();
win.Title = "Icon Template";
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
win.Width = ImageBox_RarityPreview.Source.Width;
win.Height = ImageBox_RarityPreview.Source.Height;
DockPanel dockPanel = new DockPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
Image img = new Image();
img.UseLayoutRounding = true;
img.Source = ImageBox_RarityPreview.Source;
dockPanel.Children.Add(img);
win.Content = dockPanel;
win.Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Icon Template").Focus(); }
}
}
private async void OpenFile_Button_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFiledialog = new Microsoft.Win32.OpenFileDialog();
openFiledialog.Title = "Choose your watermark";
openFiledialog.Multiselect = false;
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
if (openFiledialog.ShowDialog() == true)
{
Watermark_Label.Content = "File Name: " + Path.GetFileName(openFiledialog.FileName);
FProp.Default.FWatermarkFilePath = openFiledialog.FileName;
FProp.Default.Save();
await UpdateImageWithWatermark();
}
}
private void BrowseInput_Button_Click(object sender, RoutedEventArgs e)
{
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();
dialog.Description = "Please select a folder.";
dialog.UseDescriptionForTitle = true; // This applies to the Vista style dialog only, not the old dialog.
if ((bool)dialog.ShowDialog(this))
{
InputTextBox.Text = dialog.SelectedPath;
}
}
private void BrowseOutput_Button_Click(object sender, RoutedEventArgs e)
{
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog();
dialog.Description = "Please select a folder.";
dialog.UseDescriptionForTitle = true; // This applies to the Vista style dialog only, not the old dialog.
if ((bool)dialog.ShowDialog(this))
{
OutputTextBox.Text = dialog.SelectedPath;
}
}
private void OpenChallengeTheme_Button_Click(object sender, RoutedEventArgs e)
{
if (ImageBox_ChallengePreview.Source != null)
{
if (!FormsUtility.IsWindowOpen<Window>("Challenge Theme Template"))
{
Window win = new Window();
win.Title = "Challenge Theme Template";
win.SetValue(TextOptions.TextFormattingModeProperty, TextFormattingMode.Display);
win.WindowStartupLocation = WindowStartupLocation.CenterScreen;
win.Width = ImageBox_ChallengePreview.Source.Width;
win.Height = ImageBox_ChallengePreview.Source.Height;
DockPanel dockPanel = new DockPanel
{
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
};
Image img = new Image();
img.UseLayoutRounding = true;
img.Source = ImageBox_ChallengePreview.Source;
dockPanel.Children.Add(img);
win.Content = dockPanel;
win.Show();
}
else { FormsUtility.GetOpenedWindow<Window>("Challenge Theme Template").Focus(); }
}
}
private void PrimaryColor_Button_Click(object sender, RoutedEventArgs e)
{
Color color;
bool ok = ColorPickerWindow.ShowDialog(out color);
if (ok)
{
FProp.Default.FPrimaryColor = color.R + ":" + color.G + ":" + color.B;
FProp.Default.Save();
UpdateChallengeCustomTheme();
}
}
private void SecondaryColor_Button_Click(object sender, RoutedEventArgs e)
{
Color color;
bool ok = ColorPickerWindow.ShowDialog(out color);
if (ok)
{
FProp.Default.FSecondaryColor = color.R + ":" + color.G + ":" + color.B;
FProp.Default.Save();
UpdateChallengeCustomTheme();
}
}
private void AddBanner_Button_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFiledialog = new Microsoft.Win32.OpenFileDialog();
openFiledialog.Title = "Choose your banner";
openFiledialog.Multiselect = false;
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
if (openFiledialog.ShowDialog() == true)
{
Banner_Label.Content = "File Name: " + Path.GetFileName(openFiledialog.FileName);
FProp.Default.FBannerFilePath = openFiledialog.FileName;
FProp.Default.Save();
UpdateChallengeCustomTheme();
}
}
private void DeleteBanner_Button_Click(object sender, RoutedEventArgs e)
{
Banner_Label.Content = "File Name: ";
FProp.Default.FBannerFilePath = string.Empty;
FProp.Default.Save();
UpdateChallengeCustomTheme();
}
}
}

View File

@ -1,72 +0,0 @@
<Window x:Class="FModel.Forms.FModel_UpdateMode"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel.Forms"
mc:Ignorable="d"
Title="Update Mode" Height="315" Width="700" UseLayoutRounding="True"
Style="{StaticResource {x:Type Window}}" WindowStartupLocation="CenterScreen" Icon="/FModel;component/Logo.ico" ResizeMode="CanMinimize" Loaded="Window_Loaded">
<Grid>
<ListBox x:Name="AssetsListBox" HorizontalAlignment="Left" Height="225" Margin="10,10,0,0" VerticalAlignment="Top" Width="250" ItemsSource="{Binding Assets}" SelectionChanged="AssetsListBox_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Name}" IsChecked="{Binding IsChecked}"/>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ContextMenu>
<ContextMenu>
<MenuItem x:Name="RC_Properties" Header="Properties" Click="RC_Properties_Click">
<MenuItem.Icon>
<Image Width="16" Height="16" Source="/FModel;component/Resources/info_16x.png"/>
</MenuItem.Icon>
</MenuItem>
</ContextMenu>
</ListBox.ContextMenu>
</ListBox>
<Label Content="Name:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,10,0,0"/>
<TextBox x:Name="NameTextBox" Height="19" Margin="307,13,10,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
<Label Content="Path:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,35,0,0"/>
<TextBox x:Name="PathTextBox" Text="/FortniteGame/Content/Athena/..." Height="19" Margin="307,38,10,0" TextWrapping="NoWrap" VerticalAlignment="Top" Foreground="#FFEFEFEF"/>
<Button x:Name="Button_AddAssetType" Content="Add" HorizontalAlignment="Right" Margin="0,62,10,0" VerticalAlignment="Top" Width="80" Height="19" Click="Button_AddAssetType_Click"/>
<Button x:Name="Button_RemoveAssetType" Content="Remove Selected" HorizontalAlignment="Right" Margin="0,62,95,0" VerticalAlignment="Top" Width="110" Height="19" IsEnabled="False" Click="Button_RemoveAssetType_Click"/>
<Border BorderThickness="1" BorderBrush="#7F748198" Background="#FF252D36" HorizontalAlignment="Left" Height="144" Margin="265,91,0,0" Width="411" VerticalAlignment="Top">
<Image x:Name="ImageBox_RarityPreview" Source="/FModel;component/Resources/Template_D_N.png" UseLayoutRounding="True" HorizontalAlignment="Right" Height="140" Width="140" Margin="0,0,1,0"/>
</Border>
<Label Content="Language:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,91,0,0"/>
<ComboBox x:Name="ComboBox_Language" HorizontalAlignment="Left" Margin="324,94,0,0" VerticalAlignment="Top" Width="202" BorderBrush="#7F748198" Background="#FF333C46">
<ComboBoxItem Content="English"/>
<ComboBoxItem Content="French"/>
<ComboBoxItem Content="German"/>
<ComboBoxItem Content="Italian"/>
<ComboBoxItem Content="Spanish"/>
<ComboBoxItem Content="Spanish (LA)"/>
<ComboBoxItem Content="Arabic"/>
<ComboBoxItem Content="Japanese"/>
<ComboBoxItem Content="Korean"/>
<ComboBoxItem Content="Polish"/>
<ComboBoxItem Content="Portuguese (Brazil)"/>
<ComboBoxItem Content="Russian"/>
<ComboBoxItem Content="Turkish"/>
<ComboBoxItem Content="Chinese (S)"/>
<ComboBoxItem Content="Traditional Chinese"/>
</ComboBox>
<Label Content="Rarity Design:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,116,0,0"/>
<ComboBox x:Name="ComboBox_Design" HorizontalAlignment="Left" Margin="341,119,0,0" VerticalAlignment="Top" Width="185" BorderBrush="#7F748198" Background="#FF333C46" IsReadOnly="True" SelectionChanged="UpdateImageBox">
<ComboBoxItem Content="Default"/>
<ComboBoxItem Content="Flat"/>
<ComboBoxItem Content="Minimalist"/>
<ComboBoxItem Content="Accurate Colors"/>
</ComboBox>
<CheckBox x:Name="bFeaturedIcon" Content="Shop Item Icon" HorizontalAlignment="Left" Margin="438,143,0,0" VerticalAlignment="Top" Checked="UpdateImageBox" Unchecked="UpdateImageBox"/>
<CheckBox x:Name="bWatermarkIcon" Content="Watermark" HorizontalAlignment="Left" Margin="271,188,0,0" VerticalAlignment="Top" Checked="EnableDisableWatermark" Unchecked="EnableDisableWatermark"/>
<Button x:Name="OpenFile_Button" Content="+" HorizontalAlignment="Left" Margin="352,184,0,0" VerticalAlignment="Top" Width="19" IsEnabled="False" Click="OpenFile_Button_Click"/>
<Label x:Name="Watermark_Label" Content="File Name: " MaxWidth="240" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="376,183,0,0"/>
<Label Content="Opacity:" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="265,205,0,0"/>
<Slider x:Name="Opacity_Slider" Style="{StaticResource Horizontal_Slider}" Thumb.DragCompleted="UpdateImageWithWatermark" HorizontalAlignment="Left" Margin="330,208,0,0" VerticalAlignment="Top" Maximum="255" Width="196" Background="#FF333C46" BorderBrush="#7F748198" Foreground="{x:Null}" IsEnabled="False"/>
<Button Content="OK" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom" Width="80" Click="Button_Click"/>
</Grid>
</Window>

View File

@ -1,382 +0,0 @@
using FModel.Methods;
using FModel.Methods.Assets;
using FModel.Methods.MessageBox;
using FModel.Methods.Utilities;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using FProp = FModel.Properties.Settings;
namespace FModel.Forms
{
/// <summary>
/// Logique d'interaction pour FModel_UpdateMode.xaml
/// </summary>
public partial class FModel_UpdateMode : Window
{
private const string CHALLENGE_TEMPLATE_ICON = "pack://application:,,,/Resources/Template_Challenge.png";
private const string RARITY_DEFAULT_FEATURED = "pack://application:,,,/Resources/Template_D_F.png";
private const string RARITY_DEFAULT_NORMAL = "pack://application:,,,/Resources/Template_D_N.png";
private const string RARITY_FLAT_FEATURED = "pack://application:,,,/Resources/Template_F_F.png";
private const string RARITY_FLAT_NORMAL = "pack://application:,,,/Resources/Template_F_N.png";
private const string RARITY_MINIMALIST_FEATURED = "pack://application:,,,/Resources/Template_M_F.png";
private const string RARITY_MINIMALIST_NORMAL = "pack://application:,,,/Resources/Template_M_N.png";
private const string RARITY_ACCURATECOLORS_FEATURED = "pack://application:,,,/Resources/Template_AC_F.png";
private const string RARITY_ACCURATECOLORS_NORMAL = "pack://application:,,,/Resources/Template_AC_N.png";
#region CLASS
public class AssetProperties : INotifyPropertyChanged
{
public string Name { get; set; }
public string Path { get; set; }
//Provide change-notification for IsChecked
[JsonIgnore]
private bool _fIsChecked = false;
public bool IsChecked
{
get { return _fIsChecked; }
set
{
_fIsChecked = value;
this.OnPropertyChanged("IsChecked");
}
}
//Provide change-notification for IsSelected
[JsonIgnore]
private bool _fIsSelected = false;
public bool IsSelected
{
get { return _fIsSelected; }
set
{
_fIsSelected = value;
this.OnPropertyChanged("IsSelected");
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string strPropertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
}
}
#endregion
#region ENUMS
enum LIndexes
{
[Description("English")]
English = 0,
[Description("French")]
French = 1,
[Description("German")]
German = 2,
[Description("Italian")]
Italian = 3,
[Description("Spanish")]
Spanish = 4,
[Description("Spanish (LA)")]
Spanish_LA = 5,
[Description("Arabic")]
Arabic = 6,
[Description("Japanese")]
Japanese = 7,
[Description("Korean")]
Korean = 8,
[Description("Polish")]
Polish = 9,
[Description("Portuguese (Brazil)")]
Portuguese_Brazil = 10,
[Description("Russian")]
Russian = 11,
[Description("Turkish")]
Turkish = 12,
[Description("Chinese (S)")]
Chinese_S = 13,
[Description("Traditional Chinese")]
Traditional_Chinese = 14
}
enum RIndexes
{
[Description("Default")]
Default = 0,
[Description("Flat")]
Flat = 1,
[Description("Minimalist")]
Minimalist = 2,
[Description("Accurate Colors")]
Accurate = 3
}
public static T GetEnumValueFromDescription<T>(string description)
{
var type = typeof(T);
if (!type.IsEnum) { throw new ArgumentException("Enum type is null, bruh"); }
FieldInfo[] fields = type.GetFields();
var field = fields
.SelectMany(f => f.GetCustomAttributes(
typeof(DescriptionAttribute), false), (
f, a) => new { Field = f, Att = a })
.SingleOrDefault(a => ((DescriptionAttribute)a.Att)
.Description == description);
return field == null ? default(T) : (T)field.Field.GetRawConstantValue();
}
#endregion
public ObservableCollection<AssetProperties> Assets { get; set; }
public static Dictionary<string, Dictionary<string, string>> AssetsEntriesDict { get; set; }
public FModel_UpdateMode()
{
InitializeComponent();
}
private async void Window_Loaded(object sender, RoutedEventArgs e)
{
FoldersUtility.CheckWatermark();
ComboBox_Language.SelectedIndex = (int)GetEnumValueFromDescription<LIndexes>(FProp.Default.FLanguage);
ComboBox_Design.SelectedIndex = (int)GetEnumValueFromDescription<RIndexes>(FProp.Default.FRarity_Design);
bFeaturedIcon.IsChecked = FProp.Default.FIsFeatured;
bWatermarkIcon.IsChecked = FProp.Default.FUseWatermark;
Watermark_Label.Content += Path.GetFileName(FProp.Default.FWatermarkFilePath);
Opacity_Slider.Value = FProp.Default.FWatermarkOpacity;
AssetsEntriesDict = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, string>>>(FProp.Default.FUM_AssetsType);
Assets = new ObservableCollection<AssetProperties>();
foreach (KeyValuePair<string, Dictionary<string, string>> a in AssetsEntriesDict)
{
Assets.Add(new AssetProperties
{
Name = a.Key,
Path = a.Value["Path"],
IsChecked = bool.Parse(a.Value["isChecked"])
});
}
DataContext = this;
await UpdateImageWithWatermark();
}
private async void UpdateImageBox(object sender, RoutedEventArgs e)
{
await UpdateImageWithWatermark();
}
private async void UpdateImageWithWatermark(object sender, RoutedEventArgs e)
{
await UpdateImageWithWatermark();
}
private async Task UpdateImageWithWatermark()
{
bool watermarkEnabled = (bool)bWatermarkIcon.IsChecked;
bool isFeatured = (bool)bFeaturedIcon.IsChecked;
string rarityDesign = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
int opacity = Convert.ToInt32(Opacity_Slider.Value);
double scale = FProp.Default.FWatermarkScale;
await Task.Run(() =>
{
DrawingVisual drawingVisual = new DrawingVisual();
using (DrawingContext drawingContext = drawingVisual.RenderOpen())
{
//INITIALIZATION
drawingContext.DrawRectangle(Brushes.Transparent, null, new Rect(new Point(0, 0), new Size(515, 515)));
BitmapImage source = null;
switch (rarityDesign)
{
case "Default":
source = new BitmapImage(new Uri(isFeatured ? RARITY_DEFAULT_FEATURED : RARITY_DEFAULT_NORMAL));
break;
case "Flat":
source = new BitmapImage(new Uri(isFeatured ? RARITY_FLAT_FEATURED : RARITY_FLAT_NORMAL));
break;
case "Minimalist":
source = new BitmapImage(new Uri(isFeatured ? RARITY_MINIMALIST_FEATURED : RARITY_MINIMALIST_NORMAL));
break;
case "Accurate Colors":
source = new BitmapImage(new Uri(isFeatured ? RARITY_ACCURATECOLORS_FEATURED : RARITY_ACCURATECOLORS_NORMAL));
break;
}
drawingContext.DrawImage(source, new Rect(new Point(0, 0), new Size(515, 515)));
if (!string.IsNullOrEmpty(FProp.Default.FWatermarkFilePath) && watermarkEnabled)
{
using (StreamReader image = new StreamReader(FProp.Default.FWatermarkFilePath))
{
BitmapImage bmp = new BitmapImage();
bmp.BeginInit();
bmp.CacheOption = BitmapCacheOption.OnLoad;
bmp.StreamSource = image.BaseStream;
bmp.EndInit();
drawingContext.DrawImage(ImagesUtility.CreateTransparency(bmp, opacity), new Rect(FProp.Default.FWatermarkXPos, FProp.Default.FWatermarkYPos, scale, scale));
}
}
}
RenderTargetBitmap RTB = new RenderTargetBitmap(515, 515, 96, 96, PixelFormats.Pbgra32);
RTB.Render(drawingVisual);
RTB.Freeze(); //We freeze to apply the RTB to our imagesource from the UI Thread
FWindow.FMain.Dispatcher.InvokeAsync(() =>
{
ImageBox_RarityPreview.Source = BitmapFrame.Create(RTB); //thread safe and fast af
});
}).ContinueWith(TheTask =>
{
TasksUtility.TaskCompleted(TheTask.Exception);
});
}
private async void EnableDisableWatermark(object sender, RoutedEventArgs e)
{
OpenFile_Button.IsEnabled = (bool)bWatermarkIcon.IsChecked;
Opacity_Slider.IsEnabled = (bool)bWatermarkIcon.IsChecked;
await UpdateImageWithWatermark();
}
private async void OpenFile_Button_Click(object sender, RoutedEventArgs e)
{
Microsoft.Win32.OpenFileDialog openFiledialog = new Microsoft.Win32.OpenFileDialog();
openFiledialog.Title = "Choose your watermark";
openFiledialog.Multiselect = false;
openFiledialog.Filter = "PNG Files (*.png)|*.png|All Files (*.*)|*.*";
if (openFiledialog.ShowDialog() == true)
{
Watermark_Label.Content = "File Name: " + Path.GetFileName(openFiledialog.FileName);
FProp.Default.FWatermarkFilePath = openFiledialog.FileName;
FProp.Default.Save();
await UpdateImageWithWatermark();
}
}
private void Button_Click(object sender, RoutedEventArgs e)
{
AssetsEntriesDict = new Dictionary<string, Dictionary<string, string>>();
foreach (AssetProperties a in Assets)
{
AssetsEntriesDict[a.Name] = new Dictionary<string, string>();
AssetsEntriesDict[a.Name]["Path"] = a.Path;
AssetsEntriesDict[a.Name]["isChecked"] = a.IsChecked.ToString();
if (a.IsChecked)
DebugHelper.WriteLine("UpdateMode: User is about to extract everything in " + a.Path);
}
string selectedLang = ((ComboBoxItem)ComboBox_Language.SelectedItem).Content.ToString();
if (AssetEntries.AssetEntriesDict != null && !string.Equals(FProp.Default.FLanguage, selectedLang))
{
AssetTranslations.SetAssetTranslation(selectedLang);
}
FProp.Default.FLanguage = selectedLang;
FProp.Default.FRarity_Design = ((ComboBoxItem)ComboBox_Design.SelectedItem).Content.ToString();
FProp.Default.FIsFeatured = (bool)bFeaturedIcon.IsChecked;
FProp.Default.FUseWatermark = (bool)bWatermarkIcon.IsChecked;
FProp.Default.FWatermarkOpacity = Convert.ToInt32(Opacity_Slider.Value);
FProp.Default.FUM_AssetsType = JsonConvert.SerializeObject(AssetsEntriesDict, Formatting.Indented);
FProp.Default.Save();
DebugHelper.WriteLine("=============== UPDATE MODE ===============");
DebugHelper.WriteLine("FRarity_Design > " + FProp.Default.FRarity_Design);
DebugHelper.WriteLine("FLanguage > " + FProp.Default.FLanguage);
DebugHelper.WriteLine("FIsFeatured > " + FProp.Default.FIsFeatured);
DebugHelper.WriteLine("FUseWatermark > " + FProp.Default.FUseWatermark);
DebugHelper.WriteLine("FWatermarkFilePath > " + FProp.Default.FWatermarkFilePath);
DebugHelper.WriteLine("FWatermarkOpacity > " + FProp.Default.FWatermarkOpacity);
DebugHelper.WriteLine("FWatermarkScale > " + FProp.Default.FWatermarkScale);
DebugHelper.WriteLine("FWatermarkXPos > " + FProp.Default.FWatermarkXPos);
DebugHelper.WriteLine("FWatermarkYPos > " + FProp.Default.FWatermarkYPos);
DebugHelper.WriteLine("FOpenSounds > " + FProp.Default.FOpenSounds);
DebugHelper.WriteLine("FAutoExtractRaw > " + FProp.Default.FAutoExtractRaw);
DebugHelper.WriteLine("FAutoSaveJson > " + FProp.Default.FAutoSaveJson);
DebugHelper.WriteLine("FAutoSaveImg > " + FProp.Default.FAutoSaveImg);
DebugHelper.WriteLine("=============================================");
Close();
}
private void AssetsListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0) { ((ListBox)sender).ScrollIntoView(e.AddedItems[0]); }
Button_RemoveAssetType.IsEnabled = AssetsListBox.SelectedIndex >= 0;
}
private void Button_RemoveAssetType_Click(object sender, RoutedEventArgs e)
{
if (AssetsListBox.Items.Count > 0 && AssetsListBox.SelectedItems.Count > 0)
{
DebugHelper.WriteLine("UpdateMode: Removing " + (AssetsListBox.SelectedItem as AssetProperties).Path + " to the list of assets type");
Assets.Remove(AssetsListBox.SelectedItem as AssetProperties);
}
}
private void Button_AddAssetType_Click(object sender, RoutedEventArgs e)
{
string path = PathTextBox.Text.Trim();
if (!path.StartsWith("/"))
path = path.Insert(0, "/");
if (!path.EndsWith("/"))
path += "/";
DebugHelper.WriteLine("UpdateMode: Adding " + path + " to the list of assets type");
Assets.Add(new AssetProperties
{
Name = NameTextBox.Text,
Path = path,
IsSelected = true
});
}
private void RC_Properties_Click(object sender, RoutedEventArgs e)
{
if (AssetsListBox.SelectedIndex >= 0)
{
AssetProperties a = AssetsListBox.SelectedItem as AssetProperties;
string infos = GetAssetInfos(a);
if (DarkMessageBox.ShowYesNo(infos, a.Name, "Copy Properties", "OK") == MessageBoxResult.Yes)
{
Clipboard.SetText(infos);
new UpdateMyConsole(a.Name, CColors.Blue).Append();
new UpdateMyConsole("'s properties successfully copied", CColors.White, true).Append();
}
}
}
private static string GetAssetInfos(AssetProperties a)
{
StringBuilder sb = new StringBuilder();
sb.Append(
"\n- Name:\t\t" + a.Name +
"\n- Path:\t\t" + a.Path +
"\n- Checked:\t" + a.IsChecked +
"\n- Selected:\tTrue" +
"\n"
);
return sb.ToString();
}
}
}

View File

@ -1,559 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Base author : Derek Tremblay (derektremblay666@gmail.com)
// Contributor : emes30
// Notice : The idea to make a base class with common bytecontrol code is taken
// from emes30 fork (https://github.com/emes30/WpfHexEditorControl)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using WpfHexaEditor.Core;
using WpfHexaEditor.Core.Interfaces;
namespace WpfHexaEditor
{
/// <summary>
/// Base class for bytecontrol
/// </summary>
abstract class BaseByte : FrameworkElement, IByteControl
{
#region Global class variables
protected readonly HexEditor _parent;
private bool _isSelected;
private ByteAction _action = ByteAction.Nothing;
private byte? _byte;
private bool _isHighLight;
#endregion global class variables
#region Events
public event EventHandler ByteModified;
public event EventHandler MouseSelection;
public event EventHandler Click;
public event EventHandler RightClick;
public event EventHandler DoubleClick;
public event EventHandler MoveNext;
public event EventHandler MovePrevious;
public event EventHandler MoveRight;
public event EventHandler MoveLeft;
public event EventHandler MoveUp;
public event EventHandler MoveDown;
public event EventHandler MovePageDown;
public event EventHandler MovePageUp;
public event EventHandler ByteDeleted;
public event EventHandler EscapeKey;
public event EventHandler CtrlzKey;
public event EventHandler CtrlvKey;
public event EventHandler CtrlcKey;
public event EventHandler CtrlaKey;
public event EventHandler CtrlyKey;
#endregion Events
#region Constructor
protected BaseByte(HexEditor parent)
{
//Parent hexeditor
_parent = parent ?? throw new ArgumentNullException(nameof(parent));
#region Binding tooltip
LoadDictionary("/FModel;component/Forms/HexViewer/ToolTipDictionary.xaml");
var txtBinding = new Binding
{
Source = FindResource("ByteToolTip"),
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Mode = BindingMode.OneWay
};
// Load ressources dictionnary
void LoadDictionary(string url)
{
var ttRes = new ResourceDictionary { Source = new Uri(url, UriKind.Relative) };
Resources.MergedDictionaries.Add(ttRes);
}
SetBinding(ToolTipProperty, txtBinding);
#endregion
//Default properties
DataContext = this;
Focusable = true;
}
#endregion
#region Properties
/// <summary>
/// Position in file
/// </summary>
public long BytePositionInStream { get; set; } = -1L;
/// <summary>
/// Used for selection coloring
/// </summary>
public bool FirstSelected { protected get; set; }
/// <summary>
/// Used to prevent ByteModified event occurc when we dont want!
/// </summary>
public bool InternalChange { get; set; }
/// <summary>
/// Get or set if control as in read only mode
/// </summary>
public bool ReadOnlyMode { protected get; set; }
/// <summary>
/// Get or set the description to shown in tooltip
/// </summary>
public string Description { get; set; }
/// <summary>
/// Return true if mouse is over... (Used with traverse methods via IByteControl)
/// </summary>
public bool IsMouseOverMe { get; internal set; }
/// <summary>
/// Get or Set if control as selected
/// </summary>
public bool IsSelected
{
get => _isSelected;
set
{
if (value == _isSelected) return;
_isSelected = value;
UpdateVisual();
}
}
/// <summary>
/// Get of Set if control as marked as highlighted
/// </summary>
public bool IsHighLight
{
get => _isHighLight;
set
{
if (value == _isHighLight) return;
_isHighLight = value;
UpdateVisual();
}
}
/// <summary>
/// Byte used for this instance
/// </summary>
public byte? Byte
{
get => _byte;
set
{
_byte = value;
if (Action != ByteAction.Nothing && InternalChange == false)
ByteModified?.Invoke(this, new EventArgs());
UpdateTextRenderFromByte();
}
}
/// <summary>
/// Action with this byte
/// </summary>
public ByteAction Action
{
get => _action;
set
{
_action = value != ByteAction.All ? value : ByteAction.Nothing;
UpdateVisual();
}
}
protected FormattedText TextFormatted { get; private set; }
#endregion
#region Private base properties
/// <summary>
/// Definie the foreground
/// </summary>
private static readonly DependencyProperty ForegroundProperty =
TextElement.ForegroundProperty.AddOwner(
typeof(BaseByte));
protected Brush Foreground
{
get => (Brush)GetValue(ForegroundProperty);
set => SetValue(ForegroundProperty, value);
}
public static readonly DependencyProperty BackgroundProperty =
TextElement.BackgroundProperty.AddOwner(typeof(BaseByte),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// Defines the background
/// </summary>
protected Brush Background
{
get => (Brush)GetValue(BackgroundProperty);
set => SetValue(BackgroundProperty, value);
}
private static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(string), typeof(BaseByte),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
/// <summary>
/// Text to be displayed representation of Byte
/// </summary>
protected string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
private static readonly DependencyProperty FontWeightProperty = TextElement.FontWeightProperty.AddOwner(typeof(BaseByte));
/// <summary>
/// The FontWeight property specifies the weight of the font.
/// </summary>
protected FontWeight FontWeight
{
get => (FontWeight)GetValue(FontWeightProperty);
set => SetValue(FontWeightProperty, value);
}
#endregion Base properties
#region Methods
/// <summary>
/// Update Background,foreground and font property
/// </summary>
public virtual void UpdateVisual()
{
if (IsSelected)
{
FontWeight = _parent.FontWeight;
Foreground = _parent.ForegroundContrast;
Background = FirstSelected
? _parent.SelectionFirstColor
: _parent.SelectionSecondColor;
}
else if (IsHighLight)
{
FontWeight = _parent.FontWeight;
Foreground = _parent.Foreground;
Background = _parent.HighLightColor;
}
else if (Action != ByteAction.Nothing)
{
FontWeight = FontWeights.Bold;
Foreground = _parent.Foreground;
switch (Action)
{
case ByteAction.Modified:
Background = _parent.ByteModifiedColor;
break;
case ByteAction.Deleted:
Background = _parent.ByteDeletedColor;
break;
}
}
else
{
var cbb = _parent.GetCustomBackgroundBlock(BytePositionInStream);
Description = cbb != null ? cbb.Description : "";
Background = cbb != null ? cbb.Color : Brushes.Transparent;
Foreground = _parent.GetColumnNumber(BytePositionInStream) % 2 == 0
? _parent.Foreground
: _parent.ForegroundSecondColor;
FontWeight = _parent.FontWeight;
}
UpdateAutoHighLiteSelectionByteVisual();
InvalidateVisual();
}
/// <summary>
/// Auto highlite SelectionByte
/// </summary>
protected void UpdateAutoHighLiteSelectionByteVisual()
{
if (_parent.AllowAutoHighLightSelectionByte && _parent.SelectionByte != null &&
Byte == _parent.SelectionByte && !IsSelected)
Background = _parent.AutoHighLiteSelectionByteBrush;
}
/// <summary>
/// Update the render of text derived bytecontrol from byte property
/// </summary>
public abstract void UpdateTextRenderFromByte();
/// <summary>
/// Clear control
/// </summary>
public virtual void Clear()
{
InternalChange = true;
BytePositionInStream = -1;
Byte = null;
Action = ByteAction.Nothing;
IsSelected = false;
InternalChange = false;
Description = string.Empty;
}
#endregion
#region Events delegate
/// <summary>
/// Render the control
/// </summary>
protected override void OnRender(DrawingContext dc)
{
//Draw background
if (Background != null)
dc.DrawRectangle(Background, null, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
//Draw text
var typeface = new Typeface(_parent.FontFamily, _parent.FontStyle, FontWeight, _parent.FontStretch);
var formattedText = new FormattedText(Text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
typeface, _parent.FontSize, Foreground, VisualTreeHelper.GetDpi(this).PixelsPerDip);
dc.DrawText(formattedText, new Point(2, 2));
//#if DEBUG && NET47
// //FOR HELP TO DEBUG HIDEBYTEDELETED ONLY...
// if (_parent.HideByteDeleted && BytePositionInStream < 10000 && Core.Bytes.ByteConverters.IsHexValue(Text).success)
// {
// var formattedText2 = new FormattedText(BytePositionInStream.ToString(), CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
// typeface, 8, Brushes.Green, VisualTreeHelper.GetDpi(this).PixelsPerDip);
// dc.DrawText(formattedText2, new Point(0, 10));
// }
//#endif
//Update properties
TextFormatted = formattedText;
}
protected override void OnMouseEnter(MouseEventArgs e)
{
if (Byte != null && !IsSelected && !IsHighLight &&
Action != ByteAction.Modified &&
Action != ByteAction.Deleted &&
Action != ByteAction.Added)
Background = _parent.MouseOverColor;
UpdateAutoHighLiteSelectionByteVisual();
if (e.LeftButton == MouseButtonState.Pressed)
MouseSelection?.Invoke(this, e);
IsMouseOverMe = true;
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(MouseEventArgs e)
{
var cbb = _parent.GetCustomBackgroundBlock(BytePositionInStream);
if (Byte != null && !IsSelected && !IsHighLight &&
Action != ByteAction.Modified &&
Action != ByteAction.Deleted &&
Action != ByteAction.Added)
Background = Brushes.Transparent;
if (cbb != null && !IsSelected && !IsHighLight &&
Action != ByteAction.Modified &&
Action != ByteAction.Deleted &&
Action != ByteAction.Added)
Background = cbb.Color;
IsMouseOverMe = false;
UpdateAutoHighLiteSelectionByteVisual();
base.OnMouseLeave(e);
}
protected override void OnMouseDown(MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (!IsFocused)
Focus();
switch (e.ClickCount)
{
case 1:
Click?.Invoke(this, e);
break;
case 2:
DoubleClick?.Invoke(this, e);
break;
}
}
if (e.RightButton == MouseButtonState.Pressed)
RightClick?.Invoke(this, e);
base.OnMouseDown(e);
}
protected override void OnToolTipOpening(ToolTipEventArgs e)
{
if (Byte == null || !_parent.ShowByteToolTip)
e.Handled = true;
base.OnToolTipOpening(e);
}
protected override void OnLostFocus(RoutedEventArgs e)
{
_parent.HideCaret();
base.OnLostFocus(e);
}
protected void OnMoveNext(EventArgs e) => MoveNext?.Invoke(this, e);
protected bool KeyValidation(KeyEventArgs e)
{
#region Key validation and launch event if needed
if (KeyValidator.IsUpKey(e.Key))
{
e.Handled = true;
MoveUp?.Invoke(this, new EventArgs());
return true;
}
if (KeyValidator.IsDownKey(e.Key))
{
e.Handled = true;
MoveDown?.Invoke(this, new EventArgs());
return true;
}
if (KeyValidator.IsLeftKey(e.Key))
{
e.Handled = true;
MoveLeft?.Invoke(this, new EventArgs());
return true;
}
if (KeyValidator.IsRightKey(e.Key))
{
e.Handled = true;
MoveRight?.Invoke(this, new EventArgs());
return true;
}
if (KeyValidator.IsPageDownKey(e.Key))
{
e.Handled = true;
MovePageDown?.Invoke(this, new EventArgs());
return true;
}
if (KeyValidator.IsPageUpKey(e.Key))
{
e.Handled = true;
MovePageUp?.Invoke(this, new EventArgs());
return true;
}
if (KeyValidator.IsDeleteKey(e.Key))
{
if (!ReadOnlyMode)
{
e.Handled = true;
ByteDeleted?.Invoke(this, new EventArgs());
return true;
}
}
else if (KeyValidator.IsBackspaceKey(e.Key))
{
e.Handled = true;
ByteDeleted?.Invoke(this, new EventArgs());
MovePrevious?.Invoke(this, new EventArgs());
return true;
}
else if (KeyValidator.IsEscapeKey(e.Key))
{
e.Handled = true;
EscapeKey?.Invoke(this, new EventArgs());
return true;
}
else if (KeyValidator.IsCtrlZKey(e.Key))
{
e.Handled = true;
CtrlzKey?.Invoke(this, new EventArgs());
return true;
}
else if (KeyValidator.IsCtrlYKey(e.Key))
{
e.Handled = true;
CtrlyKey?.Invoke(this, new EventArgs());
return true;
}
else if (KeyValidator.IsCtrlVKey(e.Key))
{
e.Handled = true;
CtrlvKey?.Invoke(this, new EventArgs());
return true;
}
else if (KeyValidator.IsCtrlCKey(e.Key))
{
e.Handled = true;
CtrlcKey?.Invoke(this, new EventArgs());
return true;
}
else if (KeyValidator.IsCtrlAKey(e.Key))
{
e.Handled = true;
CtrlaKey?.Invoke(this, new EventArgs());
return true;
}
return false;
#endregion
}
}
#endregion
}

View File

@ -1,15 +0,0 @@
<!--
Apache 2.0 - 2016-2018
Author : Derek Tremblay (derektremblay666@gmail.com)
-->
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!-- THIS DICTIONARY IS USED FOR PUT CUSTOM BRUSH -->
<SolidColorBrush x:Key="BookMarkColor" Color="#B20000FF" />
<SolidColorBrush x:Key="SearchBookMarkColor" Color="#FFFF8B00" />
<SolidColorBrush x:Key="SelectionStartBookMarkColor" Color="Blue" />
<SolidColorBrush x:Key="ByteModifiedMarkColor" Color="#CC68717C" />
<SolidColorBrush x:Key="ByteDeletedMarkColor" Color="#B2FF0000" />
</ResourceDictionary>

View File

@ -1,40 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor.Core
{
/// <summary>
/// BookMark class
/// </summary>
public sealed class BookMark
{
public ScrollMarker Marker { get; set; } = ScrollMarker.Nothing;
public long BytePositionInStream { get; set; }
public string Description { get; set; } = string.Empty;
public BookMark() { }
public BookMark(string description, long position)
{
BytePositionInStream = position;
Description = description;
}
public BookMark(string description, long position, ScrollMarker marker)
{
BytePositionInStream = position;
Description = description;
Marker = marker;
}
/// <summary>
/// String representation
/// </summary>
/// <returns></returns>
public override string ToString() => $"({ByteConverters.LongToHex(BytePositionInStream)}h){Description}";
}
}

View File

@ -1,255 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Linq;
using System.Text;
namespace WpfHexaEditor.Core.Bytes
{
/// <summary>
/// ByteCharConverter for convert data
/// </summary>
public static class ByteConverters
{
/// <summary>
/// Convert long to hex value
/// </summary>
public static string LongToHex(long val, OffSetPanelFixedWidth offsetwight = OffSetPanelFixedWidth.Dynamic) =>
val.ToString(offsetwight == OffSetPanelFixedWidth.Dynamic
? ConstantReadOnly.HexStringFormat
: ConstantReadOnly.HexLineInfoStringFormat
, CultureInfo.InvariantCulture);
public static string LongToString(long val, int saveBits = -1)
{
if (saveBits == -1) return val.ToString();
//Char[] with fixed size is always
var chs = new char[saveBits];
for (int i = 1; i <= saveBits; i++)
{
chs[saveBits - i] = (char)(val % 10 + 48);
val /= 10;
}
return new string(chs);
}
/// <summary>
/// Convert Byte to Char (can be used as visible text)
/// </summary>
/// <remarks>
/// Code from : https://github.com/pleonex/tinke/blob/master/Be.Windows.Forms.HexBox/ByteCharConverters.cs
/// </remarks>
public static char ByteToChar(byte val) => val > 0x1F && !(val > 0x7E && val < 0xA0) ? (char)val : '.';
/// <summary>
/// Convert Char to Byte
/// </summary>
public static byte CharToByte(char val) => (byte)val;
/// <summary>
/// Converts a byte array to a hex string. For example: {10,11} = "0A 0B"
/// </summary>
public static string ByteToHex(byte[] data)
{
if (data == null) return string.Empty;
var sb = new StringBuilder();
foreach (var b in data)
{
var hex = ByteToHex(b);
sb.Append(hex);
sb.Append(" ");
}
if (sb.Length > 0)
sb.Remove(sb.Length - 1, 1);
return sb.ToString();
}
/// <summary>
/// Convert a byte to char[2].
/// </summary>
public static char[] ByteToHexCharArray(byte val)
{
var hexbyteArray = new char[2];
ByteToHexCharArray(val, hexbyteArray);
return hexbyteArray;
}
/// <summary>
/// Fill the <paramref name="charArr"/> with hex char;
/// </summary>
/// <param name="charArr">The length of this value should be 2.</param>
public static void ByteToHexCharArray(byte val, char[] charArr)
{
if (charArr == null)
throw new ArgumentNullException(nameof(charArr));
if (charArr.Length != 2)
throw new ArgumentException($"The length of {charArr} should be 2.");
charArr[0] = ByteToHexChar(val >> 4);
charArr[1] = ByteToHexChar(val - ((val >> 4) << 4));
}
/// <summary>
/// Convert a byte to Hex char,i.e,10 = 'A'
/// </summary>
public static char ByteToHexChar(int val)
{
if (val < 10)
{
return (char)(48 + val);
}
else
{
switch (val)
{
case 10:
return 'A';
case 11:
return 'B';
case 12:
return 'C';
case 13:
return 'D';
case 14:
return 'E';
case 15:
return 'F';
default:
return 's';
}
}
}
/// <summary>
/// Converts the byte to a hex string. For example: "10" = "0A";
/// </summary>
public static string ByteToHex(byte val) => new string(ByteToHexCharArray(val));
/// <summary>
/// Convert byte to ASCII string
/// </summary>
public static string BytesToString(byte[] buffer, ByteToString converter = ByteToString.ByteToCharProcess)
{
if (buffer == null) return string.Empty;
switch (converter)
{
case ByteToString.AsciiEncoding:
return Encoding.ASCII.GetString(buffer, 0, buffer.Length);
case ByteToString.ByteToCharProcess:
var builder = new StringBuilder();
foreach (var @byte in buffer)
builder.Append(ByteToChar(@byte));
return builder.ToString();
}
return string.Empty;
}
/// <summary>
/// Converts the hex string to an byte array. The hex string must be separated by a space char ' '. If there is any invalid hex information in the string the result will be null.
/// </summary>
public static byte[] HexToByte(string hex)
{
if (string.IsNullOrEmpty(hex)) return null;
hex = hex.Trim();
var hexArray = hex.Split(' ');
var byteArray = new byte[hexArray.Length];
for (var i = 0; i < hexArray.Length; i++)
{
var hexValue = hexArray[i];
var (isByte, val) = HexToUniqueByte(hexValue);
if (!isByte) return null;
byteArray[i] = val;
}
return byteArray;
}
/// <summary>
/// Return Tuple (bool, byte) that bool represent if is a byte
/// </summary>
public static (bool success, byte val) HexToUniqueByte(string hex) =>
(byte.TryParse(hex, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out var val), val);
/// <summary>
/// Convert a hex string to long.
/// </summary>
/// <return>
/// Return (true, [position])
/// Return (false, -1) on error
/// </return>
public static (bool success, long position) HexLiteralToLong(string hex)
{
if (string.IsNullOrEmpty(hex)) return (false, -1);
var i = hex.Length > 1 && hex[0] == '0' && (hex[1] == 'x' || hex[1] == 'X')
? 2
: 0;
long value = 0;
while (i < hex.Length)
{
#region convert
int x = hex[i++];
if
(x >= '0' && x <= '9') x -= '0';
else if
(x >= 'A' && x <= 'F') x -= 'A' + 10;
else if
(x >= 'a' && x <= 'f') x -= 'a' + 10;
else
return (false, -1);
value = 16 * value + x;
#endregion
}
return (true, value);
}
/// <summary>
/// Check if is an hexa string
/// </summary>
public static (bool success, long value) IsHexValue(string hexastring) => HexLiteralToLong(hexastring);
/// <summary>
/// Check if is an hexa byte string
/// </summary>
public static (bool success, byte[] value) IsHexaByteStringValue(string hexastring) =>
HexToByte(hexastring) == null
? (false, null)
: (true, byteArray: HexToByte(hexastring));
/// <summary>
/// Convert string to byte array
/// </summary>
public static byte[] StringToByte(string str) => str.Select(CharToByte).ToArray();
/// <summary>
/// Convert String to hex string For example: "barn" = "62 61 72 6e"
/// </summary>
public static string StringToHex(string str) => ByteToHex(StringToByte(str));
}
}

View File

@ -1,100 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using WpfHexaEditor.Core.Interfaces;
namespace WpfHexaEditor.Core.Bytes
{
public class ByteModified : IByteModified
{
#region Constructor
/// <summary>
/// Default contructor
/// </summary>
public ByteModified() { }
/// <summary>
/// complete contructor
/// </summary>
public ByteModified(byte? val, ByteAction action, long bytePositionInStream, long undoLength)
{
Byte = val;
Action = action;
BytePositionInStream = bytePositionInStream;
Length = undoLength;
}
#endregion constructor
#region properties
/// <summary>
/// Byte mofidied
/// </summary>
public byte? Byte { get; set; }
/// <summary>
/// Action have made in this byte
/// </summary>
public ByteAction Action { get; set; } = ByteAction.Nothing;
/// <summary>
/// Get of Set te position in file
/// </summary>
public long BytePositionInStream { get; set; } = -1;
/// <summary>
/// Number of byte to undo when this byte is reach
/// </summary>
public long Length { get; set; } = 1;
#endregion properties
#region Methods
/// <summary>
/// Check if the object is valid and data can be used for action
/// </summary>
public bool IsValid => BytePositionInStream > -1 && Action != ByteAction.Nothing && Byte != null;
/// <summary>
/// String representation of byte
/// </summary>
public override string ToString() =>
$"ByteModified - Action:{Action} Position:{BytePositionInStream} Byte:{Byte}";
/// <summary>
/// Clear object
/// </summary>
public void Clear()
{
Byte = null;
Action = ByteAction.Nothing;
BytePositionInStream = -1;
Length = 1;
}
/// <summary>
/// Copy Current instance to another
/// </summary>
/// <returns></returns>
public ByteModified GetCopy() => new ByteModified
{
Action = Action,
Byte = Byte,
Length = Length,
BytePositionInStream = BytePositionInStream
};
/// <summary>
/// Get if bytemodified is valid
/// </summary>
public static bool CheckIsValid(ByteModified byteModified) => byteModified != null && byteModified.IsValid;
#endregion Methods
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,277 +0,0 @@
//////////////////////////////////////////////
// Fork 2017 : Derek Tremblay (derektremblay666@gmail.com)
// Part of Wpf HexEditor control : https://github.com/abbaye/WPFHexEditorControl
// Reference : https://www.codeproject.com/Tips/431000/Caret-for-WPF-User-Controls
// Reference license : The Code Project Open License (CPOL) 1.02
// Contributor : emes30
//////////////////////////////////////////////
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Media;
using System.Threading;
namespace WpfHexaEditor.Core
{
/// <summary>
/// This class represent a visual caret on editor
/// </summary>
public sealed class Caret : FrameworkElement, INotifyPropertyChanged
{
#region Global class variables
private Timer _timer;
private Point _position;
private readonly Pen _pen = new Pen(Brushes.Black, 1);
private readonly Brush _brush = new SolidColorBrush(Colors.Black);
private int _blinkPeriod = 500;
private double _caretHeight = 18;
private double _caretWidth = 9;
private bool _hide;
private CaretMode _caretMode = CaretMode.Overwrite;
#endregion
#region Constructor
public Caret()
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
_pen.Freeze();
_brush.Opacity = .5;
IsHitTestVisible = false;
InitializeTimer();
Hide();
}
}
public Caret(Brush brush)
{
if (!DesignerProperties.GetIsInDesignMode(this))
{
_pen.Brush = brush;
_pen.Freeze();
_brush.Opacity = .5;
IsHitTestVisible = false;
InitializeTimer();
Hide();
}
}
#endregion
#region Properties
private static readonly DependencyProperty VisibleProperty =
DependencyProperty.Register(nameof(Visible), typeof(bool),
typeof(Caret), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// Get is caret is running
/// </summary>
public bool IsEnable => _timer != null;
/// <summary>
/// Propertie used when caret is blinking
/// </summary>
private bool Visible
{
get => (bool)GetValue(VisibleProperty);
set => SetValue(VisibleProperty, value);
}
/// <summary>
/// Height of the caret
/// </summary>
public double CaretHeight
{
get => _caretHeight;
set
{
if (_caretHeight == value) return;
_caretHeight = value;
//InitializeTimer();
OnPropertyChanged(nameof(CaretHeight));
}
}
/// <summary>
/// Width of the caret
/// </summary>
public double CaretWidth
{
get => _caretWidth;
set
{
if (_caretWidth == value) return;
_caretWidth = value;
OnPropertyChanged(nameof(CaretWidth));
}
}
/// <summary>
/// Get the relative position of the caret
/// </summary>
public Point Position => _position;
/// <summary>
/// Left position of the caret
/// </summary>
public double Left
{
get => _position.X;
private set
{
if (_position.X == value) return;
_position.X = Math.Floor(value);
if (Visible) Visible = false;
OnPropertyChanged(nameof(Position));
OnPropertyChanged(nameof(Left));
}
}
/// <summary>
/// Top position of the caret
/// </summary>
public double Top
{
get => _position.Y;
private set
{
if (_position.Y == value) return;
_position.Y = Math.Floor(value);
if (Visible) Visible = false;
OnPropertyChanged(nameof(Position));
OnPropertyChanged(nameof(Top));
}
}
/// <summary>
/// Properties return true if caret is visible
/// </summary>
public bool IsVisibleCaret => Left >= 0 && Top > 0 && _hide == false;
/// <summary>
/// Blick period in millisecond
/// </summary>
public int BlinkPeriod
{
get => _blinkPeriod;
set
{
_blinkPeriod = value;
InitializeTimer();
OnPropertyChanged(nameof(BlinkPeriod));
}
}
/// <summary>
/// Caret display mode. Line for Insert, Block for Overwrite
/// </summary>
public CaretMode CaretMode
{
get => _caretMode;
set
{
if (_caretMode == value) return;
_caretMode = value;
OnPropertyChanged(nameof(CaretMode));
}
}
#endregion
#region Methods
/// <summary>
/// Hide the caret
/// </summary>
public void Hide() => _hide = true;
/// <summary>
/// Method delegate for blink the caret
/// </summary>
private void BlinkCaret(Object state) => Dispatcher?.Invoke(() =>
{
Visible = !Visible && !_hide;
});
/// <summary>
/// Initialise the timer
/// </summary>
private void InitializeTimer() => _timer = new Timer(BlinkCaret, null, 0, BlinkPeriod);
/// <summary>
/// Move the caret over the position defined by point parameter
/// </summary>
public void MoveCaret(Point point) => MoveCaret(point.X, point.Y);
/// <summary>
/// Move the caret over the position defined by point parameter
/// </summary>
public void MoveCaret(double x, double y)
{
_hide = false;
Left = x;
Top = y;
}
/// <summary>
/// Start the caret
/// </summary>
public void Start()
{
InitializeTimer();
_hide = false;
OnPropertyChanged(nameof(IsEnable));
}
/// <summary>
/// Stop the carret
/// </summary>
public void Stop()
{
Hide();
_timer = null;
OnPropertyChanged(nameof(IsEnable));
}
/// <summary>
/// Render the caret
/// </summary>
protected override void OnRender(DrawingContext dc)
{
if (Visible)
switch (_caretMode)
{
case CaretMode.Insert:
dc.DrawLine(_pen, _position, new Point(Left, _position.Y + CaretHeight));
break;
case CaretMode.Overwrite:
dc.DrawRectangle(_brush, _pen, new Rect(Left, _position.Y, _caretWidth, CaretHeight));
break;
}
}
#endregion
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged([CallerMemberName] string propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}

View File

@ -1,164 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2003-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
namespace WpfHexaEditor.Core.CharacterTable
{
/// <summary>
/// Objet représentant un DTE.
/// </summary>
public sealed class Dte
{
/// <summary>Nom du DTE</summary>
private string _entry;
#region Constructeurs
/// <summary>
/// Constructeur principal
/// </summary>
public Dte()
{
_entry = string.Empty;
Type = DteType.Invalid;
Value = string.Empty;
}
/// <summary>
/// Contructeur permetant d'ajouter une entrée et une valeur
/// </summary>
/// <param name="entry">Nom du DTE</param>
/// <param name="value">Valeur du DTE</param>
public Dte(string entry, string value)
{
_entry = entry;
Value = value;
Type = DteType.DualTitleEncoding;
}
/// <summary>
/// Contructeur permetant d'ajouter une entrée, une valeur et une description
/// </summary>
/// <param name="entry">Nom du DTE</param>
/// <param name="value">Valeur du DTE</param>
/// <param name="type">Type de DTE</param>
public Dte(string entry, string value, DteType type)
{
_entry = entry;
Value = value;
Type = type;
}
#endregion Constructeurs
#region Propriétés
/// <summary>
/// Nom du DTE
/// </summary>
public string Entry
{
set => _entry = value != null ? value.ToUpper(): string.Empty;
get => _entry;
}
/// <summary>
/// Valeur du DTE
/// </summary>
public string Value { get; }
/// <summary>
/// Type de DTE
/// </summary>
public DteType Type { get; }
#endregion Propriétés
#region Méthodes
/// <summary>
/// Cette fonction permet de retourner le DTE sous forme : [Entry]=[Valeur]
/// </summary>
/// <returns>Retourne le DTE sous forme : [Entry]=[Valeur]</returns>
public override string ToString() => Type != DteType.EndBlock && Type != DteType.EndLine
? _entry + "=" + Value
: _entry;
#endregion Méthodes
#region Methodes Static
public static DteType TypeDte(Dte dteValue)
{
if (dteValue == null) return DteType.Invalid;
try
{
switch (dteValue._entry.Length)
{
case 2:
return dteValue.Value.Length == 2 ? DteType.Ascii : DteType.DualTitleEncoding;
case 4: // >2
return DteType.MultipleTitleEncoding;
}
}
catch (IndexOutOfRangeException)
{
switch (dteValue._entry)
{
case @"/":
return DteType.EndBlock;
case @"*":
return DteType.EndLine;
//case @"\":
}
}
catch (ArgumentOutOfRangeException)
{
//Du a une entre qui a 2 = de suite... EX: XX==
return DteType.DualTitleEncoding;
}
return DteType.Invalid;
}
public static DteType TypeDte(string dteValue)
{
if (dteValue == null) return DteType.Invalid;
try
{
if (dteValue == FModel.Properties.Resources.EndTagString)
return DteType.EndBlock; //<end>
if (dteValue == FModel.Properties.Resources.LineTagString)
return DteType.EndLine; //<ln>
switch (dteValue.Length)
{
case 1:
return DteType.Ascii;
case 2:
return DteType.DualTitleEncoding;
}
if (dteValue.Length > 2)
return DteType.MultipleTitleEncoding;
}
catch (ArgumentOutOfRangeException)
{
//Du a une entre qui a 2 = de suite... EX: XX==
return DteType.DualTitleEncoding;
}
return DteType.Invalid;
}
#endregion Methodes Static
}
}

View File

@ -1,30 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2003-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
namespace WpfHexaEditor.Core.CharacterTable
{
/// <summary>
/// Type of DTE used in TBL
/// </summary>
public enum DteType
{
Invalid = -1,
Ascii = 0,
Japonais,
DualTitleEncoding,
MultipleTitleEncoding,
EndLine,
EndBlock
}
public enum DefaultCharacterTableType
{
Ascii,
EbcdicWithSpecialChar,
EbcdicNoSpecialChar
//MACINTOSH
//DOS/IBM-ASCII
}
}

View File

@ -1,406 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2003-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor.Core.CharacterTable
{
/// <summary>
/// Used to manage Thingy TBL file (entry=value)
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1711:Identifiers should not have incorrect suffix", Justification = "<En attente>")]
public sealed class TblStream : IDisposable
{
#region Global class variables
/// <summary>
/// TBL file path
/// </summary>
private string _fileName = string.Empty;
/// <summary>
/// Represente the whole TBL file
/// </summary>
private Dictionary<string, Dte> _dteList = new Dictionary<string, Dte>();
#endregion
#region Constructors
/// <summary>
/// Constructeur permétant de charg?le fichier DTE
/// </summary>
public TblStream(string fileName) => FileName = fileName;
/// <summary>
/// Constructeur permétant de chargéle fichier DTE
/// </summary>
public TblStream() { }
#endregion
#region Indexer
/// <summary>
/// Indexer to work on the DTE contained in TBL in the manner of a table.
/// </summary>
public Dte this[string index]
{
get => _dteList[index];
set => _dteList[index] = value;
}
#endregion
#region Methods
/// <summary>
/// Find entry in TBL file
/// </summary>
/// <param name="hex">Hex value to find match</param>
/// <param name="showSpecialValue">Fin the Endblock and EndLine</param>
public string FindMatch(string hex, bool showSpecialValue)
{
if (showSpecialValue)
{
if (_dteList.ContainsKey($"/{hex}")) return FModel.Properties.Resources.EndTagString; //"<end>";
if (_dteList.ContainsKey($"*{hex}")) return FModel.Properties.Resources.LineTagString; //"<ln>";
}
return _dteList.ContainsKey(hex)
? _dteList[hex].Value
: "#";
}
/// <summary>
/// Convert data to TBL string.
/// </summary>
/// <returns>
/// Return string converted to TBL string representation.
/// Return null on error
/// </returns>
public string ToTblString(byte[] data)
{
if (data == null) return null;
var sb = new StringBuilder();
for (var i = 0; i < data.Length; i++)
{
if (i < data.Length - 1)
{
var mte = FindMatch(ByteConverters.ByteToHex(data[i]) + ByteConverters.ByteToHex(data[i + 1]), true);
if (mte != "#")
{
sb.Append(mte);
continue;
}
}
sb.Append(FindMatch(ByteConverters.ByteToHex(data[i]), true));
}
return sb.ToString();
}
/// <summary>
/// Close the TBL and clear object
/// </summary>
public void Close()
{
_fileName = string.Empty;
_dteList.Clear();
}
/// <summary>
/// Load the TBL file
/// </summary>
private void Load(string tblString)
{
//Variables
char[] sepEndLine = {'\n'}; //end line char
char[] sepEqual = {'='}; //equal separator char
//build strings line
var textFromString = new StringBuilder(tblString);
textFromString.Insert(textFromString.Length, new[] { '\r', '\n' });
var lines = textFromString.ToString().Split(sepEndLine);
//Clear before loading
_dteList.Clear();
#region Fill dtelist dictionary
foreach (var line in lines)
{
var info = line.Split(sepEqual);
Dte dte;
try
{
switch (info[0].Length)
{
case 2:
dte = info[1].Length == 2
? new Dte(info[0], info[1].Substring(0, info[1].Length - 1), DteType.Ascii)
: new Dte(info[0], info[1].Substring(0, info[1].Length - 1),
DteType.DualTitleEncoding);
break;
case 4: // >2
dte = new Dte(info[0], info[1].Substring(0, info[1].Length - 1),
DteType.MultipleTitleEncoding);
break;
default:
continue;
}
}
catch (IndexOutOfRangeException)
{
switch (info[0].Substring(0, 1))
{
case @"/":
dte = new Dte(info[0].Substring(0, info[0].Length - 1), string.Empty, DteType.EndBlock);
break;
case @"*":
dte = new Dte(info[0].Substring(0, info[0].Length - 1), string.Empty, DteType.EndLine);
break;
default:
continue;
}
}
catch (ArgumentOutOfRangeException)
{
//Occurs when two == are in the same line
dte = new Dte(info[0], "=", DteType.DualTitleEncoding);
}
_dteList.Add(dte.Entry, dte);
}
#endregion
#region Load bookmark
BookMarks.Clear();
foreach (var line in lines)
{
try
{
if (line.Substring(0, 1) == "(")
{
var fav = new BookMark();
var lineSplited = line.Split(')');
fav.Description = lineSplited[1].Substring(0, lineSplited[1].Length - 1);
lineSplited = line.Split('h');
fav.BytePositionInStream =
ByteConverters.HexLiteralToLong(lineSplited[0].Substring(1, lineSplited[0].Length - 1)).position;
fav.Marker = ScrollMarker.TblBookmark;
BookMarks.Add(fav);
}
}
catch
{
//Nothing to add if error
}
}
#endregion
}
/// <summary>
/// Load TBL file
/// </summary>
private void Load()
{
//ouverture du fichier
if (!File.Exists(_fileName))
{
var fs = File.Create(_fileName);
fs.Close();
}
StreamReader tblFile;
try
{
tblFile = new StreamReader(_fileName, Encoding.ASCII);
}
catch
{
return;
}
if (tblFile.BaseStream.CanRead)
Load(tblFile.ReadToEnd());
tblFile.Close();
}
/// <summary>
/// Save tbl file
/// </summary>
public void Save()
{
var myFile = new FileStream(_fileName, FileMode.Create, FileAccess.Write);
var tblFile = new StreamWriter(myFile, Encoding.Unicode); //ASCII
if (tblFile.BaseStream.CanWrite)
{
//Save tbl set
foreach (var dte in _dteList)
if (dte.Value.Type != DteType.EndBlock &&
dte.Value.Type != DteType.EndLine)
tblFile.WriteLine(dte.Value.Entry + "=" + dte.Value);
else
tblFile.WriteLine(dte.Value.Entry);
//Save bookmark
tblFile.WriteLine();
foreach (var mark in BookMarks)
tblFile.WriteLine(mark.ToString());
//Add to line at end of file. Needed for some apps that using tbl file
tblFile.WriteLine();
tblFile.WriteLine();
}
//close file
tblFile.Close();
}
/// <summary>
/// Add a DTE/MTE in TBL
/// </summary>
public void Add(Dte dte) => _dteList.Add(dte.Entry, dte);
/// <summary>
/// Remove TBL entry
/// </summary>
/// <param name="dte"></param>
public void Remove(Dte dte) => _dteList.Remove(dte.Entry);
#endregion
#region Property
/// <summary>
/// Get or set the File path to TBL
/// </summary>
public string FileName
{
get => _fileName;
internal set
{
if (File.Exists(value))
{
_fileName = value;
Load();
}
else
throw new FileNotFoundException();
}
}
/// <summary>
/// Get the count of DTE/MTE in the TBL
/// </summary>
public int Length => _dteList.Count;
/// <summary>
/// Get of set bookmarks
/// </summary>
public List<BookMark> BookMarks { get; set; } = new List<BookMark>();
public int TotalDte => _dteList.Count(l => l.Value.Type == DteType.DualTitleEncoding);
public int TotalMte => _dteList.Count(l => l.Value.Type == DteType.MultipleTitleEncoding);
public int TotalAscii => _dteList.Count(l => l.Value.Type == DteType.Ascii);
public int TotalInvalid => _dteList.Count(l => l.Value.Type == DteType.Invalid);
public int TotalJaponais => _dteList.Count(l => l.Value.Type == DteType.Japonais);
public int TotalEndLine => _dteList.Count(l => l.Value.Type == DteType.EndLine);
public int TotalEndBlock => _dteList.Count(l => l.Value.Type == DteType.EndBlock);
/// <summary>
/// Get the end block char
/// </summary>
public string EndBlock
{
get
{
foreach (var dte in _dteList)
if (dte.Value.Type == DteType.EndBlock)
return dte.Value.Entry;
return string.Empty;
}
}
/// <summary>
/// Get the end line char
/// </summary>
public string EndLine
{
get
{
foreach (var dte in _dteList)
if (dte.Value.Type == DteType.EndLine)
return dte.Value.Entry;
return string.Empty;
}
}
/// <summary>
/// Enable/Disable Readonly on control.
/// </summary>
public bool AllowEdit { get; set; }
#endregion
#region Build default TBL
public static TblStream CreateDefaultTbl(DefaultCharacterTableType type = DefaultCharacterTableType.Ascii)
{
var tbl = new TblStream();
switch (type)
{
case DefaultCharacterTableType.Ascii:
for (byte i = 0; i < 255; i++)
tbl.Add(new Dte(ByteConverters.ByteToHex(i).ToUpper(), $"{ByteConverters.ByteToChar(i)}"));
break;
case DefaultCharacterTableType.EbcdicWithSpecialChar:
tbl.Load(FModel.Properties.Resources.EBCDIC);
break;
case DefaultCharacterTableType.EbcdicNoSpecialChar:
tbl.Load(FModel.Properties.Resources.EBCDIC_NoSpecialChar);
break;
}
tbl.AllowEdit = true;
return tbl;
}
#endregion
#region IDisposable Support
private bool _disposedValue; // To detect redundant calls
void Dispose(bool disposing)
{
if (!_disposedValue)
{
if (disposing)
{
_dteList = null;
}
_disposedValue = true;
}
}
public void Dispose() => Dispose(true);
#endregion
}
}

View File

@ -1,23 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
namespace WpfHexaEditor.Core
{
public static class ConstantReadOnly
{
public static readonly string HexLineInfoStringFormat = "x8";
public static readonly string HexStringFormat = "x";
public static readonly string DefaultHex8String = "0x00000000";
public const long Largefilelength = 52_428_800L; //50 MB
public const int Copyblocksize = 131_072; //128 KB
public const int Findblocksize = 1_048_576; //1 MB
/// <summary>
/// "D" may have the "widest" size
/// </summary>
public const char WidestChar = 'D';
}
}

View File

@ -1,36 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Windows.Data;
namespace WpfHexaEditor.Core.Converters
{
/// <summary>
/// Permet d'inverser des bool
/// </summary>
public sealed class BoolInverterConverter : GenericStaticInstance<BoolInverterConverter>,IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool? val = null;
try
{
val = value != null && (bool) value;
}
catch
{
// ignored
}
return !val;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
}

View File

@ -1,36 +0,0 @@
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace WpfHexaEditor.Core.Converters
{
/// <summary>
/// CODE FROM NUGET PACKAGE EXPLORER : https://github.com/NuGetPackageExplorer/NuGetPackageExplorer
///
/// This BooleanToVisibility converter allows us to override the converted value when
/// the bound value is false.
///
/// The built-in converter in WPF restricts us to always use Collapsed when the bound
/// value is false.
/// </summary>
public sealed class BooleanToVisibilityConverter : GenericStaticInstance<BooleanToVisibilityConverter>,IValueConverter
{
public bool Inverted { get; set; }
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = (bool) value;
if (Inverted)
boolValue = !boolValue;
return (string) parameter == "hidden"
? (boolValue ? Visibility.Visible : Visibility.Hidden)
: (boolValue ? Visibility.Visible : Visibility.Collapsed);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) =>
throw new NotImplementedException();
}
}

View File

@ -1,29 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Windows.Data;
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor.Core.Converters
{
/// <summary>
/// Used to convert hexadecimal to Long value.
/// </summary>
public sealed class HexToLongStringConverter : GenericStaticInstance<HexToLongStringConverter> ,IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var (success, val) = ByteConverters.IsHexValue(value.ToString());
return success
? (object) val
: string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
}
}

View File

@ -1,30 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Windows.Data;
namespace WpfHexaEditor.Core.Converters
{
/// <summary>
/// Used to convert long value to hexadecimal string like this 0xFFFFFFFF.
/// </summary>
public sealed class LongToHexStringConverter : GenericStaticInstance<LongToHexStringConverter>,IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
value != null
? (long.TryParse(value.ToString(), out var longValue)
? (longValue > -1
? "0x" + longValue
.ToString(ConstantReadOnly.HexLineInfoStringFormat, CultureInfo.InvariantCulture)
.ToUpper()
: ConstantReadOnly.DefaultHex8String)
: ConstantReadOnly.DefaultHex8String)
: ConstantReadOnly.DefaultHex8String;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
}
}

View File

@ -1,25 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Windows.Data;
using System.IO;
namespace WpfHexaEditor.Core.Converters
{
/// <summary>
/// Used to get the filename with extention.
/// </summary>
public sealed class PathToFilenameConverter : GenericStaticInstance<PathToFilenameConverter> ,IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) =>
(value is string filename)
? Path.GetFileName(filename)
: string.Empty;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) => value;
}
}

View File

@ -1,209 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
namespace WpfHexaEditor.Core
{
/// <summary>
/// ByteAction used for ByteModified class
/// </summary>
public enum ByteAction
{
Nothing,
Added,
Deleted,
Modified,
/// <summary>
/// Used in ByteProvider for get list
/// </summary>
All
}
/// <summary>
/// Used for coloring mode of selection
/// </summary>
public enum FirstColor
{
HexByteData,
StringByteData
}
/// <summary>
/// Mode of Copy/Paste
/// </summary>
public enum CopyPasteMode
{
Byte,
HexaString,
AsciiString,
TblString,
CSharpCode,
VbNetCode,
JavaCode,
CCode,
FSharpCode,
PascalCode
}
/// <summary>
/// Used with Copy to code fonction for language are similar to C.
/// </summary>
internal enum CodeLanguage
{
C,
CSharp,
Java,
FSharp,
Vbnet,
Pascal
}
/// <summary>
/// Used for check label are selected et next label to select...
/// </summary>
public enum KeyDownLabel
{
FirstChar,
SecondChar,
//ThirdChar,
NextPosition
}
public enum ByteToString
{
/// <summary>
/// Build-in convertion mode. (recommended)
/// </summary>
ByteToCharProcess,
/// <summary>
/// System.Text.Encoding.ASCII string encoder
/// </summary>
AsciiEncoding
}
/// <summary>
/// Scrollbar marker
/// </summary>
public enum ScrollMarker
{
Nothing,
SearchHighLight,
Bookmark,
SelectionStart,
ByteModified,
ByteDeleted,
TblBookmark
}
/// <summary>
/// Type are opened in byteprovider
/// </summary>
///[Obsolete("The ByteProviderStreamType is low extensible for variety of stream source,and will be removed in next release.")]
public enum ByteProviderStreamType
{
File,
MemoryStream,
Nothing
}
/// <summary>
/// Type of character are used
/// </summary>
public enum CharacterTableType
{
Ascii,
TblFile
}
/// <summary>
/// Used for control the speed of mouse wheel
/// </summary>
public enum MouseWheelSpeed
{
VerySlow = 1,
Slow = 3,
Normal = 5,
Fast = 7,
VeryFast = 9,
System
}
/// <summary>
/// IByteControl spacer width
/// </summary>
public enum ByteSpacerWidth
{
VerySmall = 1,
Small = 3,
Normal = 6,
Large = 9,
VeryLarge = 12
}
public enum ByteSpacerGroup
{
TwoByte = 2,
FourByte = 4,
SixByte = 6,
EightByte = 8
}
public enum ByteSpacerPosition
{
HexBytePanel,
StringBytePanel,
Both,
Nothing
}
public enum ByteSpacerVisual
{
Empty,
Line,
Dash
}
/// <summary>
/// Used with the view mode of HexByte, header or position.
/// </summary>
public enum DataVisualType
{
Hexadecimal, //Editable
Decimal //Not editable
//Binary //Editable
}
/// <summary>
/// Used to select the visual of the offset panel
/// </summary>
public enum OffSetPanelType
{
OffsetOnly,
LineOnly,
Both
}
/// <summary>
/// Used to fix the wigth of the offset panel
/// </summary>
public enum OffSetPanelFixedWidth
{
Dynamic,
Fixed
}
/// <summary>
/// Use mode of the caret
/// </summary>
public enum CaretMode
{
Insert,
Overwrite
}
}

View File

@ -1,17 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2018
// Author : Janus Tida
//////////////////////////////////////////////
namespace WpfHexaEditor.Core
{
/// <summary>
/// This class is designed to simplify getting the instance.
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class GenericStaticInstance<T> where T : class, new()
{
private static T _staticInstance;
public static T StaticInstance => _staticInstance ?? (_staticInstance = new T());
}
}

View File

@ -1,52 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2017-2019
// Author : Janus Tida
// Contributor : Derek Tremblay
//////////////////////////////////////////////
using System;
namespace WpfHexaEditor.Core.Interfaces
{
/// <summary>
/// All byte control inherit from this interface.
/// This interface is used to reduce the code when manipulate byte control
/// </summary>
internal interface IByteControl
{
//Properties
long BytePositionInStream { get; set; }
ByteAction Action { get; set; }
byte? Byte { get; set; }
bool IsHighLight { get; set; }
bool IsSelected { get; set; }
bool InternalChange { get; set; }
bool IsMouseOverMe { get; }
//Methods
void UpdateVisual();
void Clear();
//Events
event EventHandler ByteModified;
event EventHandler MouseSelection;
event EventHandler Click;
event EventHandler DoubleClick;
event EventHandler RightClick;
event EventHandler MoveNext;
event EventHandler MovePrevious;
event EventHandler MoveRight;
event EventHandler MoveLeft;
event EventHandler MoveUp;
event EventHandler MoveDown;
event EventHandler MovePageDown;
event EventHandler MovePageUp;
event EventHandler ByteDeleted;
event EventHandler EscapeKey;
event EventHandler CtrlzKey;
event EventHandler CtrlvKey;
event EventHandler CtrlcKey;
event EventHandler CtrlaKey;
event EventHandler CtrlyKey;
}
}

View File

@ -1,26 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2017
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor.Core.Interfaces
{
public interface IByteModified
{
//Properties
ByteAction Action { get; set; }
byte? Byte { get; set; }
long BytePositionInStream { get; set; }
bool IsValid { get; }
long Length { get; set; }
//Methods
void Clear();
ByteModified GetCopy();
string ToString();
}
}

View File

@ -1,179 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Text;
using System.Windows.Input;
using WpfHexaEditor.Core.Native;
namespace WpfHexaEditor.Core
{
/// <summary>
/// Static class for valid keyboard key.
/// </summary>
public static class KeyValidator
{
/// <summary>
/// Check if is a numeric key as pressed
/// </summary>
public static bool IsNumericKey(Key key)
{
return key == Key.D0 || key == Key.D1 || key == Key.D2 || key == Key.D3 || key == Key.D4 || key == Key.D5 ||
key == Key.D6 || key == Key.D7 || key == Key.D8 || key == Key.D9 ||
key == Key.NumPad0 || key == Key.NumPad1 || key == Key.NumPad2 || key == Key.NumPad3 ||
key == Key.NumPad4 || key == Key.NumPad5 || key == Key.NumPad6 || key == Key.NumPad7 ||
key == Key.NumPad8 || key == Key.NumPad9;
}
/// <summary>
/// Get if key is a Hexakey (alpha)
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static bool IsHexKey(Key key)
{
return key == Key.A || key == Key.B || key == Key.C || key == Key.D || key == Key.E || key == Key.F ||
IsNumericKey(key);
}
/// <summary>
/// Get the digit from key
/// </summary>
public static int GetDigitFromKey(Key key)
{
switch (key)
{
case Key.D0:
case Key.NumPad0: return 0;
case Key.D1:
case Key.NumPad1: return 1;
case Key.D2:
case Key.NumPad2: return 2;
case Key.D3:
case Key.NumPad3: return 3;
case Key.D4:
case Key.NumPad4: return 4;
case Key.D5:
case Key.NumPad5: return 5;
case Key.D6:
case Key.NumPad6: return 6;
case Key.D7:
case Key.NumPad7: return 7;
case Key.D8:
case Key.NumPad8: return 8;
case Key.D9:
case Key.NumPad9: return 9;
default: throw new ArgumentOutOfRangeException("Invalid key: " + key);
}
}
public static bool IsIgnoredKey(Key key)
{
//ADD SOMES OTHER KEY FOR VALIDATED IN IBYTECONTROL
//DELETE KEY FOR ADD OTHER FUNCTIONALITY...
return key == Key.Tab ||
key == Key.Enter ||
key == Key.Return ||
key == Key.LWin ||
key == Key.RWin ||
key == Key.CapsLock ||
key == Key.LeftAlt ||
key == Key.RightAlt ||
key == Key.System ||
key == Key.LeftCtrl ||
key == Key.F1 || key == Key.F2 || key == Key.F3 || key == Key.F4 || key == Key.F5 || key == Key.F6 ||
key == Key.F7 || key == Key.F8 || key == Key.F9 || key == Key.F10 || key == Key.F11 ||
key == Key.F12 ||
key == Key.Home ||
key == Key.Insert ||
key == Key.End;
}
public static bool IsArrowKey(Key key) =>
key == Key.Up || key == Key.Down || key == Key.Left || key == Key.Right;
public static bool IsBackspaceKey(Key key) => key == Key.Back;
public static bool IsSubstractKey(Key key) => key == Key.Subtract || key == Key.OemMinus;
public static bool IsDeleteKey(Key key) => key == Key.Delete;
public static bool IsCapsLock(Key key) => key == Key.CapsLock;
public static bool IsEscapeKey(Key key) => key == Key.Escape;
public static bool IsUpKey(Key key) => key == Key.Up;
public static bool IsWindowsKey(Key key) => key == Key.LWin || key == Key.RWin;
public static bool IsDownKey(Key key) => key == Key.Down;
public static bool IsRightKey(Key key) => key == Key.Right;
public static bool IsLeftKey(Key key) => key == Key.Left;
public static bool IsPageDownKey(Key key) => key == Key.PageDown;
public static bool IsPageUpKey(Key key) => key == Key.PageUp;
public static bool IsEnterKey(Key key) => key == Key.Enter;
public static bool IsTabKey(Key key) => key == Key.Tab;
public static bool IsCtrlCKey(Key key) => key == Key.C && Keyboard.Modifiers == ModifierKeys.Control;
public static bool IsCtrlZKey(Key key) => key == Key.Z && Keyboard.Modifiers == ModifierKeys.Control;
public static bool IsCtrlYKey(Key key) => key == Key.Y && Keyboard.Modifiers == ModifierKeys.Control;
public static bool IsCtrlVKey(Key key) => key == Key.V && Keyboard.Modifiers == ModifierKeys.Control;
public static bool IsCtrlAKey(Key key) => key == Key.A && Keyboard.Modifiers == ModifierKeys.Control;
#region DllImport/methods for key detection (Thank to : Inbar Barkai for help)
/// <summary>
/// Capture character on different locale keyboards in WPF. Convert key to appropiate char?
/// </summary>
/// <remarks>
/// Code from
/// http://stackoverflow.com/questions/5825820/how-to-capture-the-character-on-different-locale-keyboards-in-wpf-c
/// </remarks>
/// <returns>return a char represent the key passed in parameter</returns>
public static char GetCharFromKey(Key key)
{
var ch = ' ';
var virtualKey = KeyInterop.VirtualKeyFromKey(key);
var keyboardState = new byte[256];
NativeMethods.GetKeyboardState(keyboardState);
var scanCode = NativeMethods.MapVirtualKey((uint) virtualKey, NativeMethods.MapType.MapvkVkToVsc);
var stringBuilder = new StringBuilder(2);
var result = NativeMethods.ToUnicode((uint) virtualKey, scanCode, keyboardState, stringBuilder,
stringBuilder.Capacity, 0);
switch (result)
{
case -1:
case 0:
break;
case 1:
ch = stringBuilder[0];
break;
default:
ch = stringBuilder[0];
break;
}
return ch;
}
#endregion DllImport for key detection (Thank to : Inbar Barkai for help)
}
}

View File

@ -1,44 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System.Windows;
using System.Windows.Threading;
namespace WpfHexaEditor.Core.MethodExtention
{
/// <summary>
/// DoEvents when control is in long task. Control do not freeze the dispatcher.
/// </summary>
public static class ApplicationExtention
{
private static readonly DispatcherOperationCallback ExitFrameCallback = ExitFrame;
public static void DoEvents(this Application app, DispatcherPriority priority = DispatcherPriority.Background)
{
var nestedFrame = new DispatcherFrame();
var exitOperation = Dispatcher.CurrentDispatcher.BeginInvoke(priority, ExitFrameCallback, nestedFrame);
try
{
//execute all next message
Dispatcher.PushFrame(nestedFrame);
//If not completed, will stop it
if (exitOperation.Status != DispatcherOperationStatus.Completed)
exitOperation.Abort();
}
catch
{
exitOperation.Abort();
}
}
private static object ExitFrame(object f)
{
(f as DispatcherFrame).Continue = false;
return null;
}
}
}

View File

@ -1,47 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System.Collections.Generic;
using System.Linq;
namespace WpfHexaEditor.Core.MethodExtention
{
/// <summary>
/// Extention methodes for find match in byte[]
/// </summary>
public static class ByteArrayExtention
{
/// <summary>
/// Finds all index of byte find
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1062:Validate arguments of public methods", Justification = "<En attente>")]
public static IEnumerable<long> FindIndexOf(this byte[] self, byte[] candidate)
{
if (!IsEmptyLocate(self, candidate))
for (var i = 0; i < self.Length; i++)
{
if (!IsMatch(self, i, candidate))
continue;
yield return i;
}
}
/// <summary>
/// Check if match is finded
/// </summary>
private static bool IsMatch(byte[] array, long position, byte[] candidate) =>
candidate.Length <= array.Length - position && !candidate.Where((t, i) => array[position + i] != t).Any();
/// <summary>
/// Check if can find
/// </summary>
private static bool IsEmptyLocate(byte[] array, byte[] candidate) => array == null
|| candidate == null
|| array.Length == 0
|| candidate.Length == 0
|| candidate.Length > array.Length;
}
}

View File

@ -1,14 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
namespace WpfHexaEditor.Core.MethodExtention
{
public static class DoubleExtension
{
public static double Round(this double s, int digit = 2) => Math.Round(s, digit);
}
}

View File

@ -1,34 +0,0 @@
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfHexaEditor.Core.MethodExtention
{
public static class StringExtension
{
/// <summary>
/// The screen size of a string
/// </summary>
/// <remarks>
/// Code from :
/// https://stackoverflow.com/questions/11447019/is-there-any-way-to-find-the-width-of-a-character-in-a-fixed-width-font-given-t
///
/// Modified/adapted by Derek Tremblay
/// </remarks>
public static Size GetScreenSize(this string text, FontFamily fontFamily, double fontSize, FontStyle fontStyle,
FontWeight fontWeight, FontStretch fontStretch, Brush foreGround)
{
fontFamily = new TextBlock().FontFamily;
fontSize = fontSize > 0 ? fontSize : new TextBlock().FontSize;
var typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
var ft = new FormattedText(text ?? string.Empty, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
typeface, fontSize, foreGround, VisualTreeHelper.GetDpi(Application.Current.MainWindow).PixelsPerDip);
return new Size(ft.Width, ft.Height);
}
}
}

View File

@ -1,60 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace WpfHexaEditor.Core.MethodExtention
{
public static class TrackExtention
{
/// <summary>
/// Get actual top position of track
/// </summary>
public static double Top(this Track track)
{
if (track.Parent is Grid parent)
{
var topRepeatButton = parent.Children[1] as RepeatButton;
return topRepeatButton.ActualHeight + parent.Margin.Top + 1;
}
return 0;
}
/// <summary>
/// Get actual bottom position of track
/// </summary>
public static double Bottom(this Track track)
{
if (track.Parent is Grid parent)
{
var trackControl = parent.Children[2] as Track;
return trackControl.Top() +
trackControl.ActualHeight +
parent.Margin.Top + 1;
}
return 0;
}
/// <summary>
/// Get actual bottom position of track
/// </summary>
public static double ButtonHeight(this Track track) => track.Top() - 1;
/// <summary>
/// Get actual Tick Height
/// </summary>
public static double TickHeight(this Track track) => track.ActualHeight / track.Maximum;
/// <summary>
/// Get actual Tick Height with another maximum value
/// </summary>
public static double TickHeight(this Track track, long maximum) => track.ActualHeight / maximum;
}
}

View File

@ -1,33 +0,0 @@
using System.Runtime.InteropServices;
using System.Text;
namespace WpfHexaEditor.Core.Native
{
/// <summary>
/// Used for key detection
/// </summary>
internal static class NativeMethods
{
internal enum MapType : uint
{
MapvkVkToVsc = 0x0,
MapvkVscToVk = 0x1,
MapvkVkToChar = 0x2,
MapvkVscToVkEx = 0x3,
}
[DllImport("user32.dll")]
internal static extern int ToUnicode(uint wVirtKey,
uint wScanCode,
byte[] lpKeyState,
[Out, MarshalAs(UnmanagedType.LPWStr, SizeParamIndex = 4)] StringBuilder pwszBuff,
int cchBuff,
uint wFlags);
[DllImport("user32.dll")]
internal static extern bool GetKeyboardState(byte[] lpKeyState);
[DllImport("user32.dll")]
internal static extern uint MapVirtualKey(uint uCode, MapType uMapType);
}
}

View File

@ -1,83 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Windows.Media;
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor.Core.Xcbb
{
/// <summary>
/// IMPLEMENTATION NOT COMPLETED
/// Used to create block of custom colors background
/// </summary>
/// TODO : Add programated positon..
public class CustomBackgroundBlock
{
private long _length;
public CustomBackgroundBlock() { }
public CustomBackgroundBlock(long start, long length, SolidColorBrush color, string description)
{
StartOffset = start;
Length = length;
Color = color;
Description = description;
}
public CustomBackgroundBlock(long start, long length, SolidColorBrush color)
{
StartOffset = start;
Length = length;
Color = color;
}
public CustomBackgroundBlock(string start, long length, SolidColorBrush color)
{
var srt = ByteConverters.HexLiteralToLong(start);
StartOffset = srt.success ? srt.position : throw new Exception("Can't convert this string to long");
Length = length;
Color = color;
}
public CustomBackgroundBlock(string start, long length, SolidColorBrush color, string description)
{
var srt = ByteConverters.HexLiteralToLong(start);
StartOffset = srt.success ? srt.position : throw new Exception("Can't convert this string to long");
Length = length;
Color = color;
Description = description;
}
/// <summary>
/// Get or set the start offset
/// </summary>
public long StartOffset { get; set; }
/// <summary>
/// Get the stop offset
/// </summary>
public long StopOffset => StartOffset + Length - 1;
/// <summary>
/// Get or set the lenght of background block
/// </summary>
public long Length
{
get => _length;
set => _length = value > 0 ? value : 1;
}
/// <summary>
/// Description of background block
/// </summary>
public string Description { get; set; }
public SolidColorBrush Color { get; set; } = Brushes.Transparent;
}
}

View File

@ -1,61 +0,0 @@
using System.Collections.Generic;
using System.Windows.Media;
using WpfHexaEditor.Core.Bytes;
using static FModel.Properties.Resources;
namespace WpfHexaEditor.Core.Xcbb
{
/// <summary>
/// IMPLEMENTATON NOT COMPLETED - FOR TESTING CONCEPT ONLY
/// Window executable file custom background block.
/// Will be implemented in XML file (XCBB)...
/// Will de deleted soon in futher commit
/// </summary>
/// TODO : Localize string
public class ExeFile
{
public List<CustomBackgroundBlock> GetCustomBackgroundBlock() =>
new List<CustomBackgroundBlock>
{
new CustomBackgroundBlock(0, 2, Brushes.BlueViolet, CBB_EXEFile_MagicNumberString),
new CustomBackgroundBlock(2, 2, Brushes.Brown, CBB_EXEFile_BytesInLastBlockString),
new CustomBackgroundBlock(4, 2, Brushes.SeaGreen, CBB_EXEFile_NumberOfBlockInFileBlockString),
new CustomBackgroundBlock(6, 2, Brushes.CadetBlue, CBB_EXEFile_NumberOfRelocationEntriesString),
new CustomBackgroundBlock(8, 2, Brushes.DarkGoldenrod, CBB_EXEFile_NumberOfRelocationEntriesString),
new CustomBackgroundBlock("0x0A", 2, Brushes.Coral, CBB_EXEFile_NumberOfHeaderParagraphAdditionalMemoryString),
new CustomBackgroundBlock("0x0C", 2, Brushes.HotPink, CBB_EXEFile_MaxNumberOfHeaderParagraphAdditionalMemoryString),
new CustomBackgroundBlock("0x0E", 2, Brushes.Cyan, CBB_EXEFile_RelativeValueOfStackSegmentString),
new CustomBackgroundBlock("0x10", 2, Brushes.IndianRed, CBB_EXEFile_InitialValueOfSPRegisterString),
new CustomBackgroundBlock("0x12", 2, Brushes.LimeGreen, CBB_EXEFile_WordChecksumString),
new CustomBackgroundBlock("0x14", 2, Brushes.PaleTurquoise, CBB_EXEFile_InitialValueOfIPRegisterString),
new CustomBackgroundBlock("0x16", 2, Brushes.DarkOrange, CBB_EXEFile_InitialValueOfCSRegisterString),
new CustomBackgroundBlock("0x18", 2, Brushes.Chartreuse, CBB_EXEFile_OffsetOfTheFirstRelocationItemString),
new CustomBackgroundBlock("0x1A", 2, Brushes.DarkSeaGreen, CBB_EXEFile_OverlayNumberString),
};
/// <summary>
/// Detect if is a PE file and create the backgroung based on file data
/// </summary>
/// TODO : complete with other various custombackground based on file
public List<CustomBackgroundBlock> GetCustomBackgroundBlock(ByteProvider provider)
{
if (ByteProvider.CheckIsOpen(provider))
{
//Added only if is a PE file...
if (ByteConverters.ByteToHex(provider.GetCopyData(0, 1, true)) == "4D 5A")
{
//Load default
var list = GetCustomBackgroundBlock();
//Add CBB : This program cannot be run in DOS mode
list.Add(new CustomBackgroundBlock("0x4E", 38, Brushes.PaleVioletRed, CBB_EXEFile_NotDOSProgramString));
return list;
}
}
return new List<CustomBackgroundBlock>();
}
}
}

View File

@ -1,95 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<!--DEV TEST - wpf hexeditor control - Custom Backgroung Block definition file-->
<XcbbFileDefinition FileType="exe" ValidIf="[0x00-0x01]=$'4D 5A'">
<CustomBackgroundBlock PositionStart="0x00" Lenght="2" BackColor="BlueViolet">
<LocalizedDescription Language="en-US" IsDefault="True" Description="This is the 'magic number' of an EXE file."/>
<LocalizedDescription Language="fr-CA" Description="C'est le 'nombre magique' d'un fichier EXE."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x02" Lenght="2" BackColor="Brown">
<LocalizedDescription Language="en-US" IsDefault="True" Description="The number of bytes in the last block of the program that are actually used.
If this value is zero, that means the entire last block is used"/>
<LocalizedDescription Language="fr-CA" Description="Nombre d'octets réellement utilisés dans le dernier bloc du programme.
Si cette valeur est zéro, cela signifie que le dernier bloc entier est utilisé"/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x04" Lenght="2" BackColor="SeaGreen">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of blocks in the file that are part of the EXE file.
If [02-03] is non-zero, only that much of the last block is used."/>
<LocalizedDescription Language="fr-CA" Description="Nombre de blocs dans le fichier qui font partie du fichier EXE.
Si [02-03] est non nul, seule la plus grande partie du dernier bloc est utilisée."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x06" Lenght="2" BackColor="BlueViolet">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of relocation entries stored after the header. May be zero."/>
<LocalizedDescription Language="fr-CA" Description="Nombre d'entrées de relocalisation stockées après l'en-tête. Peut être zéro"/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x08" Lenght="2" BackColor="DarkGoldenrod">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of paragraphs in the header. The program's data begins just after the header, and this field can be used to calculate the appropriate file offset.
The header includes the relocation entries. Note that some OSs and/or programs may fail if the header is not a multiple of 512 bytes."/>
<LocalizedDescription Language="fr-CA" Description="Nombre de paragraphes dans l'en-tête. Les données du programme commencent juste après l'en-tête et ce champ peut être utilisé pour calculer le décalage de fichier approprié.
L'en-tête comprend les entrées de relocalisation. Notez que certains systèmes d'exploitation et / ou programmes peuvent échouer si l'en-tête n'est pas un multiple de 512 octets."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x0A" Lenght="2" BackColor="Coral">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Number of paragraphs of additional memory that the program will need.
This is the equivalent of the BSS size in a Unix program.
The program can't be loaded if there isn't at least this much memory available to it."/>
<LocalizedDescription Language="fr-CA" Description="Nombre de paragraphes de mémoire supplémentaire dont le programme aura besoin.
C'est l'équivalent de la taille BSS dans un programme Unix.
Le programme ne peut pas être chargé s'il n'y a pas au moins autant de mémoire disponible."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x0C" Lenght="2" BackColor="HotPink">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Maximum number of paragraphs of additional memory.
Normally, the OS reserves all the remaining conventional memory for your program, but you can limit it with this field."/>
<LocalizedDescription Language="fr-CA" Description="Nombre maximum de paragraphes de mémoire supplémentaire.
Normalement, le système d'exploitation réserve toute la mémoire conventionnelle restante pour votre programme, mais vous pouvez le limiter avec ce champ."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x0E" Lenght="2" BackColor="Cyan">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Relative value of the stack segment.
This value is added to the segment the program was loaded at, and the result is used to initialize the SS register."/>
<LocalizedDescription Language="fr-CA" Description="Valeur relative du segment de pile.
Cette valeur est ajoutée au segment dans lequel le programme a été chargé et le résultat est utilisé pour initialiser le registre SS."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x10" Lenght="2" BackColor="IndianRed">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Initial value of the SP register."/>
<LocalizedDescription Language="fr-CA" Description="Valeur initiale du registre SP."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x12" Lenght="2" BackColor="LimeGreen">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Word checksum.
If set properly, the 16-bit sum of all words in the file should be zero.
Usually, this isn't filled in."/>
<LocalizedDescription Language="fr-CA" Description="Word checksum.
Si défini correctement, la somme de 16 bits de tous les mots du fichier doit être zéro.
Habituellement, ce n'est pas renseigné."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x14" Lenght="2" BackColor="PaleTurquoise">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Initial value of the IP register."/>
<LocalizedDescription Language="fr-CA" Description="Valeur initiale du registre IP."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x16" Lenght="2" BackColor="DarkOrange">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Initial value of the CS register, relative to the segment the program was loaded at."/>
<LocalizedDescription Language="fr-CA" Description="Valeur initiale du registre CS, relative au segment dans lequel le programme a été chargé."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x18" Lenght="2" BackColor="Chartreuse">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Offset of the first relocation item in the file."/>
<LocalizedDescription Language="fr-CA" Description="Décalage du premier élément de déplacement dans le fichier."/>
</CustomBackgroundBlock>
<CustomBackgroundBlock PositionStart="0x1A" Lenght="2" BackColor="DarkSeaGreen">
<LocalizedDescription Language="en-US" IsDefault="True" Description="Overlay number. Normally zero, meaning that it's the main program."/>
<LocalizedDescription Language="fr-CA" Description="Numéro de superposition. Normalement zéro, ce qui signifie que c'est le programme principal."/>
</CustomBackgroundBlock>
</XcbbFileDefinition>

View File

@ -1,46 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor.Core.Xcbb
{
/// <summary>
/// Used to parse expression used in Xccb file for validate byte data.
/// </summary>
/// <remarks>
/// Expression parser need to be linked to a ByteProvided for validating data.
/// </remarks>
public class XcbbExpressionParser
{
/// <summary>
/// This ByteProvider is used for get data from file/stream and validate them in expression
/// </summary>
private readonly ByteProvider _provider;
/// <summary>
/// Unique constructor
/// </summary>
XcbbExpressionParser(ByteProvider provider) => _provider = provider;
/// <summary>
/// Use for valid expresion "valid if data are equal to..."
/// </summary>
/// <param name="expression">expression like: [0x00-0x01]=$'4D 5A'</param>
/// <returns>
/// True = expression is valid
/// False = expression not valid
/// Null = unable to valid expression</returns>
public bool? ValidIf(string expression)
{
if (ByteProvider.CheckIsOpen(_provider))
{
return false;
}
return null;
}
}
}

View File

@ -1,24 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace WpfHexaEditor.Core.Xcbb
{
/// <summary>
/// Class for read and parse xcbb file (xml custom backgroung block definition)
/// </summary>
public class XcbbFileParser
{
protected XcbbFileParser(string path)
{
LoadFile(path);
}
private void LoadFile(string path)
{
}
}
}

View File

@ -1,127 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2018
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Documents;
using System.Windows.Media;
namespace WpfHexaEditor
{
/// <summary>
/// Light Label like control
/// </summary>
internal class FastTextLine: FrameworkElement
{
private readonly HexEditor _parent;
#region Constructor
public FastTextLine(HexEditor parent)
{
//Parent hexeditor
_parent = parent ?? throw new ArgumentNullException(nameof(parent));
//Default properties
DataContext = this;
}
#endregion Contructor
#region Base properties
/// <summary>
/// Definie the foreground
/// </summary>
public static readonly DependencyProperty ForegroundProperty =
TextElement.ForegroundProperty.AddOwner(
typeof(FastTextLine));
public Brush Foreground
{
get => (Brush)GetValue(ForegroundProperty);
set => SetValue(ForegroundProperty, value);
}
public static readonly DependencyProperty BackgroundProperty =
TextElement.BackgroundProperty.AddOwner(typeof(FastTextLine),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender));
/// <summary>
/// Defines the background
/// </summary>
public Brush Background
{
get => (Brush)GetValue(BackgroundProperty);
set => SetValue(BackgroundProperty, value);
}
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(string), typeof(FastTextLine),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.AffectsMeasure));
/// <summary>
/// Text to be displayed representation of Byte
/// </summary>
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty FontWeightProperty = TextElement.FontWeightProperty.AddOwner(typeof(FastTextLine));
/// <summary>
/// The FontWeight property specifies the weight of the font.
/// </summary>
public FontWeight FontWeight
{
get => (FontWeight)GetValue(FontWeightProperty);
set => SetValue(FontWeightProperty, value);
}
#endregion Base properties
#region Properties
public bool AutoWidth { get; set; } = true;
public Point RenderPoint
{
get => (Point)GetValue(RenderPointProperty);
set => SetValue(RenderPointProperty, value);
}
// Using a DependencyProperty as the backing store for RenderPoint. This enables animation, styling, binding, etc...
public static readonly DependencyProperty RenderPointProperty =
DependencyProperty.Register(nameof(RenderPoint), typeof(Point), typeof(FastTextLine),
new FrameworkPropertyMetadata(new Point(0, 0), FrameworkPropertyMetadataOptions.AffectsMeasure));
#endregion
/// <summary>
/// Render the control
/// </summary>
protected override void OnRender(DrawingContext dc)
{
//Draw background
if (Background != null)
dc.DrawRectangle(Background, null, new Rect(0, 0, RenderSize.Width, RenderSize.Height));
//Draw text
var formatedText = new FormattedText(Text, CultureInfo.InvariantCulture, FlowDirection.LeftToRight,
new Typeface(_parent.FontFamily, _parent.FontStyle, FontWeight, _parent.FontStretch),
_parent.FontSize, Foreground, VisualTreeHelper.GetDpi(this).PixelsPerDip);
dc.DrawText(formatedText, new Point(RenderPoint.X, RenderPoint.Y));
if (AutoWidth)
Width = formatedText.Width + RenderPoint.X;
}
}
}

View File

@ -1,229 +0,0 @@
<!--
Apache 2.0 - 2019
Author : Derek Tremblay (derektremblay666@gmail.com)
-->
<Window
x:Class="WpfHexaEditor.Dialog.FindReplaceWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:FModel.Properties"
xmlns:wpfHexaEditor="clr-namespace:WpfHexaEditor"
Title="Find and Replace"
Width="193"
Height="340"
MinWidth="550"
MinHeight="360"
MaxWidth="700"
MaxHeight="500"
Icon="/FModel;component/Resources/Logo-Icon.ico"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
Style="{StaticResource {x:Type Window}}"
mc:Ignorable="d">
<Grid>
<Popup
x:Name="SettingPopup"
OpacityMask="WhiteSmoke"
PlacementTarget="{Binding ElementName=SettingButton}"
StaysOpen="False">
<StackPanel Margin="1,0.5,0.5,0.8" Background="{x:Static SystemColors.MenuBarBrush}">
<MenuItem
x:Name="HighlightMenuItem"
Click="SettingMenuItem_Click"
Header="Trim the data on the find length when replace"
IsCheckable="True"
IsChecked="True" />
<MenuItem
x:Name="TrimMenuItem"
Click="SettingMenuItem_Click"
Header="Highlight all data find"
IsCheckable="True"
IsChecked="True" />
</StackPanel>
</Popup>
<Button
x:Name="FindNextButton"
Width="100"
Height="27"
Margin="0,73,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindNextButton_Click"
Content="Find Next"
TabIndex="3" />
<Button
Width="100"
Height="27"
Margin="0,0,14,10"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Click="CloseButton_Click"
Content="Close"
IsCancel="True"
TabIndex="10" />
<wpfHexaEditor:HexEditor
x:Name="FindHexEdit"
Height="110"
Margin="10,41,129,0"
VerticalAlignment="Top"
AllowAutoHighLightSelectionByte="False"
AllowContextMenu="False"
AllowDeleteByte="True"
AllowDrop="True"
AllowExtend="True"
AllowFileDrop="False"
AllowZoom="False"
AppendNeedConfirmation="False"
ByteModifiedColor="White"
BytePerLine="8"
ByteSpacerPositioning="Nothing"
BytesDeleted="FindHexEdit_BytesDeleted"
HideByteDeleted="False"
StatusBarVisibility="Collapsed" />
<Label
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Find what:" />
<Button
x:Name="ReplaceButton"
Width="100"
Height="28"
Margin="0,169,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="ReplaceButton_Click"
Content="Replace"
TabIndex="6" />
<Button
x:Name="ReplaceAllButton"
Width="100"
Height="27"
Margin="0,234,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="ReplaceAllButton_Click"
Content="Replace All"
TabIndex="9" />
<wpfHexaEditor:HexEditor
x:Name="ReplaceHexEdit"
Margin="10,187,129,10"
AllowAutoHighLightSelectionByte="False"
AllowContextMenu="False"
AllowDeleteByte="True"
AllowDrop="True"
AllowExtend="True"
AllowFileDrop="False"
AllowZoom="False"
AppendNeedConfirmation="False"
ByteModifiedColor="White"
BytePerLine="8"
ByteSpacerPositioning="Nothing"
BytesDeleted="ReplaceHexEdit_BytesDeleted"
HideByteDeleted="False"
StatusBarVisibility="Collapsed" />
<Label
Height="26"
Margin="10,156,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Replace with:" />
<Button
x:Name="FindAllButton"
Width="100"
Height="27"
Margin="0,137,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindAllButton_Click"
Content="Find All"
TabIndex="5" />
<Button
x:Name="FindFirstButton"
Width="100"
Height="27"
Margin="0,41,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindFirstButton_Click"
Content="Find First"
TabIndex="2" />
<Button
x:Name="FindLastButton"
Width="100"
Height="27"
Margin="0,105,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindLastButton_Click"
Content="Find Last"
TabIndex="4" />
<Button
Width="61"
Height="26"
Margin="0,10,129,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="ClearButton_Click"
Content="Clear"
TabIndex="1" />
<Button
Width="61"
Height="26"
Margin="0,156,129,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="ClearReplaceButton_Click"
Content="Clear"
TabIndex="11" />
<Button
x:Name="ReplaceNextButton"
Width="100"
Height="27"
Margin="0,202,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="ReplaceNextButton_Click"
Content="Replace Next"
TabIndex="7" />
<Button
x:Name="SettingButton"
Width="100"
Height="26"
Margin="0,10,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="SettingButton_Click">
<Image
Width="31"
Height="23"
Source="/WPFHexaEditor;component/Resources/Icon/Settings-Icon.ico" />
</Button>
</Grid>
</Window>

View File

@ -1,84 +0,0 @@
using System.IO;
using System.Windows;
namespace WpfHexaEditor.Dialog
{
/// <summary>
/// Logique d'interaction pour FindReplaceWindow.xaml
/// </summary>
public partial class FindReplaceWindow
{
private readonly HexEditor _parent;
public FindReplaceWindow(HexEditor parent, byte[] findData = null)
{
InitializeComponent();
//Parent hexeditor for "binding" search
_parent = parent;
InitializeMStream(FindHexEdit, findData);
InitializeMStream(ReplaceHexEdit);
}
#region Events
private void ClearButton_Click(object sender, RoutedEventArgs e) => InitializeMStream(FindHexEdit);
private void ClearReplaceButton_Click(object sender, RoutedEventArgs e) => InitializeMStream(ReplaceHexEdit);
private void CloseButton_Click(object sender, RoutedEventArgs e) => Close();
private void FindAllButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindAll(FindHexEdit.GetAllBytes(), HighlightMenuItem.IsChecked);
private void FindFirstButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindFirst(FindHexEdit.GetAllBytes(), 0, HighlightMenuItem.IsChecked);
private void FindNextButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindNext(FindHexEdit.GetAllBytes(), HighlightMenuItem.IsChecked);
private void FindLastButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindLast(FindHexEdit.GetAllBytes(), HighlightMenuItem.IsChecked);
private void ReplaceButton_Click(object sender, RoutedEventArgs e) =>
_parent?.ReplaceFirst(FindHexEdit.GetAllBytes(), ReplaceHexEdit.GetAllBytes(),
TrimMenuItem.IsChecked, HighlightMenuItem.IsChecked);
private void ReplaceNextButton_Click(object sender, RoutedEventArgs e) =>
_parent?.ReplaceNext(FindHexEdit.GetAllBytes(), ReplaceHexEdit.GetAllBytes(),
TrimMenuItem.IsChecked, HighlightMenuItem.IsChecked);
private void ReplaceAllButton_Click(object sender, RoutedEventArgs e) =>
_parent?.ReplaceAll(FindHexEdit.GetAllBytes(), ReplaceHexEdit.GetAllBytes(),
TrimMenuItem.IsChecked, HighlightMenuItem.IsChecked);
private void ReplaceHexEdit_BytesDeleted(object sender, System.EventArgs e) =>
InitializeMStream(ReplaceHexEdit, ReplaceHexEdit.GetAllBytes());
private void FindHexEdit_BytesDeleted(object sender, System.EventArgs e) =>
InitializeMStream(FindHexEdit, FindHexEdit.GetAllBytes());
private void SettingButton_Click(object sender, RoutedEventArgs e) => SettingPopup.IsOpen = true;
private void SettingMenuItem_Click(object sender, RoutedEventArgs e) => SettingPopup.IsOpen = false;
#endregion
#region Methods
/// <summary>
/// Initialize stream and hexeditor
/// </summary>
private void InitializeMStream(HexEditor hexeditor, byte[] findData = null)
{
hexeditor.CloseProvider();
var ms = new MemoryStream(1);
if (findData != null && findData.Length > 0)
foreach (byte b in findData)
ms.WriteByte(b);
else
ms.WriteByte(0);
hexeditor.Stream = ms;
}
#endregion
}
}

View File

@ -1,119 +0,0 @@
<!--
Apache 2.0 2018 - 2019
Author : Derek Tremblay (derektremblay666@gmail.com)
-->
<Window
x:Class="WpfHexaEditor.Dialog.FindWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:FModel.Properties"
xmlns:wpfHexaEditor="clr-namespace:WpfHexaEditor"
Title="Find"
Width="193"
Height="190"
MinWidth="550"
MinHeight="275"
MaxWidth="700"
MaxHeight="500"
Icon="/FModel;component/Resources/Logo-Icon.ico"
ResizeMode="CanResizeWithGrip"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
Style="{StaticResource {x:Type Window}}"
mc:Ignorable="d">
<Grid>
<Button
x:Name="FindNextButton"
Width="100"
Height="27"
Margin="0,73,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindNextButton_Click"
Content="Find Next"
TabIndex="3" />
<Button
Width="100"
Height="27"
Margin="0,0,14,16"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Click="CloseButton_Click"
Content="Close"
IsCancel="True"
TabIndex="6" />
<wpfHexaEditor:HexEditor
x:Name="FindHexEdit"
Margin="10,41,129,21"
AllowAutoHighLightSelectionByte="False"
AllowContextMenu="False"
AllowDeleteByte="True"
AllowDrop="True"
AllowExtend="True"
AllowFileDrop="False"
AllowZoom="False"
AppendNeedConfirmation="False"
ByteModifiedColor="White"
BytePerLine="8"
ByteSpacerPositioning="Nothing"
BytesDeleted="FindHexEdit_BytesDeleted"
HideByteDeleted="False"
StatusBarVisibility="Collapsed" />
<Label
Margin="10,10,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Find what:" />
<Button
x:Name="FindAllButton"
Width="100"
Height="27"
Margin="0,137,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindAllButton_Click"
Content="Find All"
TabIndex="5" />
<Button
x:Name="FindFirstButton"
Width="100"
Height="27"
Margin="0,41,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindFirstButton_Click"
Content="Find First"
TabIndex="2" />
<Button
x:Name="FindLastButton"
Width="100"
Height="27"
Margin="0,105,14,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="FindLastButton_Click"
Content="Find Last"
TabIndex="4" />
<Button
Width="61"
Height="26"
Margin="0,10,129,0"
HorizontalAlignment="Right"
VerticalAlignment="Top"
Click="ClearButton_Click"
Content="Clear"
TabIndex="1" />
</Grid>
</Window>

View File

@ -1,60 +0,0 @@
using System.IO;
using System.Windows;
namespace WpfHexaEditor.Dialog
{
/// <summary>
/// Logique d'interaction pour FindWindow.xaml
/// </summary>
public partial class FindWindow
{
private MemoryStream _findMs = new MemoryStream(1);
private readonly HexEditor _parent;
public FindWindow(HexEditor parent, byte[] findData = null)
{
InitializeComponent();
//Parent hexeditor for "binding" search
_parent = parent;
InitializeMStream(findData);
}
private void CloseButton_Click(object sender, RoutedEventArgs e) => Close();
private void ClearButton_Click(object sender, RoutedEventArgs e) => InitializeMStream();
private void FindHexEdit_BytesDeleted(object sender, System.EventArgs e) =>
InitializeMStream(FindHexEdit.GetAllBytes());
private void FindAllButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindAll(FindHexEdit.GetAllBytes(), true);
private void FindFirstButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindFirst(FindHexEdit.GetAllBytes());
private void FindNextButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindNext(FindHexEdit.GetAllBytes());
private void FindLastButton_Click(object sender, RoutedEventArgs e) =>
_parent?.FindLast(FindHexEdit.GetAllBytes());
/// <summary>
/// Initialize stream and hexeditor
/// </summary>
private void InitializeMStream(byte[] findData = null)
{
FindHexEdit.CloseProvider();
_findMs = new MemoryStream(1);
if (findData != null && findData.Length > 0)
foreach (byte b in findData)
_findMs.WriteByte(b);
else
_findMs.WriteByte(0);
FindHexEdit.Stream = _findMs;
}
}
}

View File

@ -1,56 +0,0 @@
<Window
x:Class="WpfHexaEditor.Dialog.GiveByteWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:control="clr-namespace:WpfHexaEditor"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:FModel.Properties"
Title="Enter hexadecimal value ..."
Width="359"
Height="121"
x:ClassModifier="internal"
Icon="/FModel;component/Resources/Logo-Icon.ico"
ResizeMode="NoResize"
ShowInTaskbar="False"
WindowStartupLocation="CenterOwner"
WindowStyle="SingleBorderWindow"
Style="{StaticResource {x:Type Window}}"
mc:Ignorable="d">
<Grid>
<Button
x:Name="OkButton"
Width="75"
Margin="0,0,92,10"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Click="OKButton_Click"
Content="Ok"
IsDefault="True"
TabIndex="2" />
<Button
Width="75"
Height="20"
Margin="0,0,10,10"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Content="Cancel"
IsCancel="True"
TabIndex="3" />
<Label
Margin="10,18,0,0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Content="Byte to search" />
<control:HexBox
x:Name="HexTextBox"
Width="Auto"
Height="23"
Margin="143,20,10,0"
VerticalAlignment="Top"
MaximumValue="255" />
</Grid>
</Window>

View File

@ -1,14 +0,0 @@
using System.Windows;
namespace WpfHexaEditor.Dialog
{
/// <summary>
/// This Window is used to give a hex value for fill the selection with.
/// </summary>
internal partial class GiveByteWindow
{
public GiveByteWindow() => InitializeComponent();
private void OKButton_Click(object sender, RoutedEventArgs e) => DialogResult = true;
}
}

View File

@ -1,87 +0,0 @@
<!--
Apache 2.0 - 2016-2018
Author : Derek Tremblay (derektremblay666@gmail.com)
-->
<UserControl
x:Class="WpfHexaEditor.HexBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:FModel.Properties"
Width="100"
Height="24"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="13" />
<ColumnDefinition Width="65*" />
<ColumnDefinition Width="22" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<RepeatButton
Grid.Column="2"
Padding="0"
BorderBrush="#FFCDCBCB"
Click="UpButton_Click">
<Grid>
<TextBlock
Margin="0,-1,0,0"
FontSize="8"
Text="&#x25b2;" />
</Grid>
</RepeatButton>
<RepeatButton
Grid.Row="1"
Grid.Column="2"
Padding="0"
BorderBrush="#FFCDCBCB"
Click="DownButton_Click">
<Grid>
<TextBlock
Margin="0,-1,0,0"
FontSize="8"
Text="&#x25bc;" />
</Grid>
</RepeatButton>
<TextBox
x:Name="HexTextBox"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="1"
VerticalContentAlignment="Center"
BorderBrush="{x:Null}"
Focusable="True"
IsUndoEnabled="False"
KeyDown="HexTextBox_KeyDown"
MaxLength="15"
MaxLines="1"
PreviewKeyDown="HexTextBox_PreviewKeyDown"
TabIndex="1"
Text="0"
TextChanged="HexTextBox_TextChanged" Padding="0" Foreground="White">
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Click="CopyHexaMenuItem_Click" Header="Copy as hexadecimal" />
<MenuItem Click="CopyLongMenuItem_Click" Header="Copy as decimal" />
</ContextMenu>
</TextBox.ContextMenu>
</TextBox>
<Label
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Padding="0"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Content="0x" />
</Grid>
</UserControl>

View File

@ -1,174 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2017-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
//////////////////////////////////////////////
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using WpfHexaEditor.Core;
using WpfHexaEditor.Core.Bytes;
namespace WpfHexaEditor
{
/// <summary>
/// Control for enter hex value and deal with.
/// </summary>
public partial class HexBox
{
public HexBox() => InitializeComponent();
#region Events
/// <summary>
/// Occurs when value are changed.
/// </summary>
public event EventHandler ValueChanged;
#endregion
#region Properties
/// <summary>
/// Get hexadecimal value of LongValue
/// </summary>
public string HexValue => ByteConverters.LongToHex(LongValue);
/// <summary>
/// Set maximum value
/// </summary>
public long MaximumValue
{
get => (long)GetValue(MaximumValueProperty);
set => SetValue(MaximumValueProperty, value);
}
// Using a DependencyProperty as the backing store for MaximumValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty MaximumValueProperty =
DependencyProperty.Register(nameof(MaximumValue), typeof(long), typeof(HexBox),
new FrameworkPropertyMetadata(long.MaxValue, MaximumValue_Changed));
private static void MaximumValue_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is HexBox ctrl)
if (e.NewValue != e.OldValue)
if (ctrl.LongValue > (long)e.NewValue)
ctrl.UpdateValueFrom((long)e.NewValue);
}
/// <summary>
/// Get or set the hex value show in control
/// </summary>
public long LongValue
{
get => (long)GetValue(LongValueProperty);
set => SetValue(LongValueProperty, value);
}
// Using a DependencyProperty as the backing store for LongValue. This enables animation, styling, binding, etc...
public static readonly DependencyProperty LongValueProperty =
DependencyProperty.Register(nameof(LongValue), typeof(long), typeof(HexBox),
new FrameworkPropertyMetadata(0L,
LongValue_Changed,
LongValue_CoerceValue));
private static object LongValue_CoerceValue(DependencyObject d, object baseValue)
{
var ctrl = d as HexBox;
var newValue = (long)baseValue;
if (newValue > ctrl.MaximumValue) newValue = ctrl.MaximumValue;
if (newValue < 0) newValue = 0;
return newValue;
}
private static void LongValue_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is HexBox ctrl)
if (e.NewValue != e.OldValue)
{
var val = ByteConverters.LongToHex((long)e.NewValue);
if (val == "00000000")
val = "0";
else if (val.Length >= 3)
val = val.TrimStart('0');
ctrl.HexTextBox.Text = val.ToUpper();
ctrl.HexTextBox.CaretIndex = ctrl.HexTextBox.Text.Length;
ctrl.ToolTip = e.NewValue;
ctrl.ValueChanged?.Invoke(ctrl, new EventArgs());
}
}
#endregion Properties
#region Methods
/// <summary>
/// Substract one to the LongValue
/// </summary>
private void SubstractOne() => LongValue--;
/// <summary>
/// Add one to the LongValue
/// </summary>
private void AddOne() => LongValue++;
/// <summary>
/// Update value from decimal long
/// </summary>
private void UpdateValueFrom(long value) => LongValue = value;
/// <summary>
/// Update value from hex string
/// </summary>
private void UpdateValueFrom(string value)
{
var (success, val) = ByteConverters.HexLiteralToLong(value);
LongValue = success ? val : 0;
}
#endregion Methods
#region Controls events
private void HexTextBox_PreviewKeyDown(object sender, KeyEventArgs e) =>
e.Handled = !KeyValidator.IsHexKey(e.Key) &&
!KeyValidator.IsBackspaceKey(e.Key) &&
!KeyValidator.IsDeleteKey(e.Key) &&
!KeyValidator.IsArrowKey(e.Key) &&
!KeyValidator.IsTabKey(e.Key) &&
!KeyValidator.IsEnterKey(e.Key);
private void HexTextBox_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Up)
AddOne();
if (e.Key == Key.Down)
SubstractOne();
HexTextBox.Focus();
}
private void UpButton_Click(object sender, RoutedEventArgs e) => AddOne();
private void DownButton_Click(object sender, RoutedEventArgs e) => SubstractOne();
private void HexTextBox_TextChanged(object sender, TextChangedEventArgs e) =>
UpdateValueFrom(HexTextBox.Text);
private void CopyHexaMenuItem_Click(object sender, RoutedEventArgs e) =>
Clipboard.SetText($"0x{HexTextBox.Text}");
private void CopyLongMenuItem_Click(object sender, RoutedEventArgs e) =>
Clipboard.SetText(LongValue.ToString());
#endregion Controls events
}
}

View File

@ -1,218 +0,0 @@
//////////////////////////////////////////////
// Apache 2.0 - 2016-2019
// Author : Derek Tremblay (derektremblay666@gmail.com)
// Contributor: Janus Tida
//////////////////////////////////////////////
using System;
using System.Windows;
using System.Windows.Input;
using WpfHexaEditor.Core;
using WpfHexaEditor.Core.Bytes;
using WpfHexaEditor.Core.MethodExtention;
namespace WpfHexaEditor
{
internal class HexByte : BaseByte
{
#region Global class variables
private KeyDownLabel _keyDownLabel = KeyDownLabel.FirstChar;
#endregion global class variables
#region Constructor
public HexByte(HexEditor parent) : base(parent)
{
//Update width
UpdateDataVisualWidth();
}
#endregion Contructor
#region Methods
/// <summary>
/// Update the render of text derived bytecontrol from byte property
/// </summary>
public override void UpdateTextRenderFromByte()
{
if (Byte != null)
{
switch (_parent.DataStringVisual)
{
case DataVisualType.Hexadecimal:
var chArr = ByteConverters.ByteToHexCharArray(Byte.Value);
Text = new string(chArr);
break;
case DataVisualType.Decimal:
Text = Byte.Value.ToString("d3");
break;
}
}
else
Text = string.Empty;
}
public override void Clear()
{
base.Clear();
_keyDownLabel = KeyDownLabel.FirstChar;
}
public void UpdateDataVisualWidth()
{
switch (_parent.DataStringVisual)
{
case DataVisualType.Decimal:
Width = 25;
break;
case DataVisualType.Hexadecimal:
Width = 20;
break;
}
}
#endregion Methods
#region Events delegate
protected override void OnMouseDown(MouseButtonEventArgs e)
{
if (e.LeftButton == MouseButtonState.Pressed)
{
if (IsFocused)
{
//Is focused set editing to second char.
_keyDownLabel = KeyDownLabel.SecondChar;
UpdateCaret();
}
}
base.OnMouseDown(e);
}
protected override void OnKeyDown(KeyEventArgs e)
{
if (Byte == null) return;
if (KeyValidation(e)) return;
//MODIFY BYTE
if (!ReadOnlyMode && KeyValidator.IsHexKey(e.Key))
switch (_parent.DataStringVisual)
{
case DataVisualType.Hexadecimal:
#region Edit hexadecimal value
string key;
key = KeyValidator.IsNumericKey(e.Key)
? KeyValidator.GetDigitFromKey(e.Key).ToString()
: e.Key.ToString().ToLower();
//Update byte
var byteValueCharArray = ByteConverters.ByteToHexCharArray(Byte.Value);
switch (_keyDownLabel)
{
case KeyDownLabel.FirstChar:
byteValueCharArray[0] = key.ToCharArray()[0];
_keyDownLabel = KeyDownLabel.SecondChar;
Action = ByteAction.Modified;
Byte = ByteConverters.HexToByte(
byteValueCharArray[0] + byteValueCharArray[1].ToString())[0];
break;
case KeyDownLabel.SecondChar:
byteValueCharArray[1] = key.ToCharArray()[0];
_keyDownLabel = KeyDownLabel.NextPosition;
Action = ByteAction.Modified;
Byte = ByteConverters.HexToByte(
byteValueCharArray[0] + byteValueCharArray[1].ToString())[0];
//Insert byte at end of file
if (_parent.Length != BytePositionInStream + 1)
{
_keyDownLabel = KeyDownLabel.NextPosition;
OnMoveNext(new EventArgs());
}
break;
case KeyDownLabel.NextPosition:
//byte[] byteToAppend = { (byte)key.ToCharArray()[0] };
_parent.AppendByte(new byte[] { 0 });
OnMoveNext(new EventArgs());
break;
}
#endregion
break;
case DataVisualType.Decimal:
//Not editable at this moment, maybe in future
break;
}
UpdateCaret();
base.OnKeyDown(e);
}
#endregion Events delegate
#region Caret events/methods
protected override void OnGotFocus(RoutedEventArgs e)
{
_keyDownLabel = KeyDownLabel.FirstChar;
UpdateCaret();
base.OnGotFocus(e);
}
private void UpdateCaret()
{
if (ReadOnlyMode || Byte == null)
_parent.HideCaret();
else
{
//TODO: clear size and use BaseByte.TextFormatted property...
var size = Text[1].ToString()
.GetScreenSize(_parent.FontFamily, _parent.FontSize, _parent.FontStyle, FontWeight,
_parent.FontStretch, _parent.Foreground);
_parent.SetCaretSize(Width / 2, size.Height);
_parent.SetCaretMode(CaretMode.Overwrite);
switch (_keyDownLabel)
{
case KeyDownLabel.FirstChar:
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(0, 0)));
break;
case KeyDownLabel.SecondChar:
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(size.Width + 1, 0)));
break;
case KeyDownLabel.NextPosition:
if (_parent.Length == BytePositionInStream + 1)
if (_parent.AllowExtend)
{
_parent.SetCaretMode(CaretMode.Insert);
_parent.MoveCaret(TransformToAncestor(_parent).Transform(new Point(size.Width * 2, 0)));
}
else
_parent.HideCaret();
break;
}
}
}
#endregion
}
}

View File

@ -1,425 +0,0 @@
<!--
Apache 2.0 - 2016-2019
Author : Derek Tremblay (derektremblay666@gmail.com)
-->
<UserControl
x:Class="WpfHexaEditor.HexEditor"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfHexaEditor"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:p="clr-namespace:FModel.Properties"
d:DesignHeight="350"
d:DesignWidth="804"
BorderBrush="#FF443E3E"
BorderThickness="1"
Drop="Control_Drop"
Focusable="True"
FontSize="11"
KeyDown="Control_KeyDown"
Loaded="Control_Loaded"
MouseWheel="Control_MouseWheel"
Unloaded="Control_Unloaded"
mc:Ignorable="d">
<!--#region Ressources-->
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="BrushesDictionary.xaml" />
<ResourceDictionary Source="ToolTipDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!--#endregion-->
<!--#region Build-in Context Menu-->
<UserControl.ContextMenu>
<ContextMenu x:Name="CMenu" Visibility="Collapsed">
<MenuItem
x:Name="UndoCMenu"
Click="UndoCMenu_Click"
Header="Undo">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Undo-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<Separator />
<MenuItem Header="Bookmarks">
<MenuItem
x:Name="BookMarkCMenu"
Width="Auto"
Click="BookMarkCMenu_Click"
Header="Set bookmark">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Add-Bookmark-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<Separator />
<MenuItem
x:Name="ClearBookMarkCMenu"
Width="Auto"
Click="ClearBookMarkCMenu_Click"
Header="Clear bookmark">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Clear-Bookmark-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
</MenuItem>
<Separator />
<MenuItem
x:Name="CopyHexaCMenu"
Click="CopyToClipBoardCMenu_Click"
Header="Copy as hexadecimal">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Copy-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<MenuItem
x:Name="CopyAsciicMenu"
Click="CopyToClipBoardCMenu_Click"
Header="Copy as ASCII">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Copy-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<MenuItem x:Name="CopyAsCMenu" Header="Copy selection as ...">
<MenuItem
x:Name="CopyCcMenu"
Click="CopyToClipBoardCMenu_Click"
Header="C" />
<MenuItem
x:Name="CopyCSharpCMenu"
Click="CopyToClipBoardCMenu_Click"
Header="C#" />
<MenuItem
x:Name="CopyFSharpCMenu"
Click="CopyToClipBoardCMenu_Click"
Header="F#" />
<MenuItem
x:Name="CopyJavaCMenu"
Click="CopyToClipBoardCMenu_Click"
Header="Java" />
<MenuItem
x:Name="CopyVbNetCMenu"
Click="CopyToClipBoardCMenu_Click"
Header="Visual Basic.Net" />
<MenuItem
x:Name="CopyPascalCMenu"
Click="CopyToClipBoardCMenu_Click"
Header="Pascal" />
<MenuItem
x:Name="CopyTblcMenu"
Click="CopyToClipBoardCMenu_Click"
Header="TBL string (character file loaded)" />
</MenuItem>
<Separator />
<MenuItem
x:Name="PasteMenu"
Click="PasteMenu_Click"
Header="Paste without inserting">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Paste-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<Separator />
<MenuItem
x:Name="FillByteCMenu"
Click="FillByteCMenu_Click"
Header="Fill selection with byte...">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/0x-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<MenuItem
x:Name="ReplaceByteCMenu"
Click="ReplaceByteCMenu_Click"
Header="Replace byte in selection...">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/0x-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<Separator />
<MenuItem
x:Name="DeleteCMenu"
Click="DeleteCMenu_Click"
Header="Delete">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Delete-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<Separator />
<MenuItem
x:Name="FindAllCMenu"
Click="FindAllCMenu_Click"
Header="Find all occurence of selection">
<!-- <MenuItem.Icon>
<Image Source="/WPFHexaEditor;component/Resources/Icon/Find-Icon.ico" />
</MenuItem.Icon> -->
</MenuItem>
<Separator />
<MenuItem
x:Name="SelectAllCMenu"
Click="SelectAllCMenu_Click"
Header="Select all" />
</ContextMenu>
</UserControl.ContextMenu>
<!--#endregion-->
<Grid
x:Name="BaseGrid"
SizeChanged="Grid_SizeChanged" Background="White">
<!--#region Grid/Column Definitions-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="207*" />
<ColumnDefinition Width="10*" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30" />
<RowDefinition Height="287*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--#endregion-->
<!--#region Data/Infos StackPanel-->
<StackPanel
x:Name="LinesInfoStackPanel"
Grid.Row="1"
Margin="2,0,0,0"
HorizontalAlignment="Left" />
<StackPanel
x:Name="HexDataStackPanel"
Grid.Row="1"
Grid.Column="1"
Margin="5,0" />
<StackPanel
x:Name="HexHeaderStackPanel"
Grid.Row="0"
Grid.Column="1"
Margin="5,0"
Orientation="Horizontal" />
<StackPanel
x:Name="StringDataStackPanel"
Grid.Row="1"
Grid.Column="2"
Margin="5,0,0,0"/>
<!--#endregion-->
<!--#region Statusbar definition-->
<Grid
x:Name="StatusBarGrid"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="5"
VerticalAlignment="Top"
Background="#FF252D36"
Visibility="Visible">
<Separator
Height="1"
Margin="0,0,0,27"
Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:HexEditor}}, Path=BorderBrush}" />
<StatusBar Height="27" BorderBrush="#7F748198" Margin="0">
<StatusBarItem Padding="0">
<StackPanel Orientation="Horizontal">
<!--<Label
Padding="5,5,0,5"
Content="{x:Static p:Resources.ZoomString}"
FontWeight="Bold" />-->
<Label
Width="40"
Content="{Binding Path=ZoomScale, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged}"
ContentStringFormat="P0"
ToolTip="Zoom" />
<Button
BorderThickness="0"
Click="ZoomResetButton_Click"
Content="X"
FontWeight="Bold"
ToolTip="Reset zoom to 100%" />
</StackPanel>
</StatusBarItem>
<Separator Background="#7F748198" />
<StatusBarItem Width="110" Padding="0">
<StackPanel Orientation="Horizontal">
<Label
Padding="5,5,0,5"
Content="Ln"
FontWeight="Bold" />
<Label Content="{Binding Path=SelectionLine, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}">
<Label.ToolTip>
<StackPanel Orientation="Horizontal">
<Label Content="Line :" FontWeight="Bold" />
<Label Content="{Binding Path=SelectionLine, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="{Binding Path=SelectionLine, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}" />
</StackPanel>
</Label.ToolTip>
</Label>
</StackPanel>
</StatusBarItem>
<Separator Background="#7F748198" />
<StatusBarItem Width="125" Padding="0">
<StackPanel Orientation="Horizontal">
<Label
Padding="5,5,0,5"
Content="Position"
FontWeight="Bold" />
<Label Content="{Binding Path=SelectionStart, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}">
<Label.ToolTip>
<StackPanel Orientation="Horizontal">
<Label Content="Position" FontWeight="Bold" />
<Label Content="{Binding Path=SelectionStart, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged}" />
<Label Content="{Binding Path=SelectionStart, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource LongHexConverter}}" />
</StackPanel>
</Label.ToolTip>
</Label>
</StackPanel>
</StatusBarItem>
<Separator Background="#7F748198" />
<StatusBarItem Width="125" Padding="0">
<StackPanel Orientation="Horizontal">
<Label
Padding="5,5,0,5"
Content="Length"
FontWeight="Bold" />
<Label x:Name="FileLengthKbLabel" ContentStringFormat="N0" />
</StackPanel>
</StatusBarItem>
<Separator Background="#7F748198" />
<StatusBarItem
x:Name="ByteCountPanel"
Padding="0"
Visibility="Collapsed">
<StackPanel Orientation="Horizontal">
<Label
Padding="5,5,0,5"
Content="Count of"
FontWeight="Bold" />
<Label x:Name="CountOfByteLabel" ToolTip="Byte at position start" />
<Label Padding="0,5" Content=":" />
<Label
x:Name="CountOfByteSumLabel"
ContentStringFormat="N0"
ToolTip="Count of Byte at position start" />
</StackPanel>
</StatusBarItem>
</StatusBar>
</Grid>
<Label
Grid.Row="2"
Grid.Column="2"
Width="64"
Margin="0,0,5,0"
HorizontalAlignment="Right"
Content="ReadOnly"
FontWeight="Bold"
Visibility="{Binding Path=ReadOnlyMode, RelativeSource={RelativeSource AncestorType={x:Type local:HexEditor}}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay, Converter={StaticResource BoolToVisibilityConverter}}" Padding="0,0,0,1" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" />
<!--#endregion-->
<!--#region Scrollbar, marker, and move rectangle-->
<ScrollBar
x:Name="VerticalScrollBar"
Style="{StaticResource VerticalScrollBarStyle}"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="4"
Width="20"
HorizontalAlignment="Right"
LargeChange="100"
SmallChange="1"
ValueChanged="VerticalScrollBar_ValueChanged" />
<Grid
x:Name="MarkerGrid"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="4"
Margin="0,17" />
<Rectangle
x:Name="BottomRectangle"
Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="4"
Height="10"
VerticalAlignment="Bottom"
Fill="#FF252D36"
MouseDown="BottomRectangle_MouseDown"
MouseEnter="BottomRectangle_MouseEnter"
MouseLeave="BottomRectangle_MouseLeave"
Opacity="0" />
<Rectangle
x:Name="TopRectangle"
Grid.Row="0"
Grid.Column="0"
Grid.ColumnSpan="4"
Height="10"
VerticalAlignment="Top"
Fill="#FF252D36"
MouseDown="TopRectangle_MouseDown"
MouseEnter="TopRectangle_MouseEnter"
MouseLeave="TopRectangle_MouseLeave"
Opacity="0" />
<!--#endregion-->
<!--#region Long process-->
<ProgressBar
x:Name="LongProgressProgressBar"
Grid.Row="3"
Grid.Column="0"
Grid.ColumnSpan="5"
Height="3"
BorderThickness="0"
Maximum="1"
Minimum="0" Background="#FF252D36" BorderBrush="#7F748198" />
<!-- TODO: ADD TEXTBLOCK FOR DETAIL -->
<Border
x:Name="CancelLongProcessButton"
Grid.Row="0"
Grid.RowSpan="2"
Grid.Column="0"
Grid.ColumnSpan="4"
Width="120"
Height="50"
BorderBrush="Gray"
BorderThickness="2"
CornerRadius="4">
<Button
VerticalContentAlignment="Center"
BorderThickness="0"
Click="CancelLongProcessButton_Click"
Content="Cancel long process"
FontWeight="Bold"
Opacity="0.9"
ToolTip="Click to cancel long process." />
</Border>
<Label
x:Name="TblLabel"
Grid.Row="2"
Grid.RowSpan="2"
Grid.Column="2"
Grid.ColumnSpan="2"
Margin="0,1,05,1"
HorizontalAlignment="Right"
Content="TBL string (character file loaded)"
FontWeight="Bold"
Visibility="Collapsed" />
<!--#endregion-->
</Grid>
</UserControl>

File diff suppressed because it is too large Load Diff

View File

@ -1,286 +0,0 @@
<Window x:Class="FModel.Forms.HexViewer.HexViewer"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FModel.Forms.HexViewer"
xmlns:control="clr-namespace:WpfHexaEditor"
xmlns:properties="clr-namespace:FModel.Properties"
mc:Ignorable="d"
Title="Hex Viewer" Height="700" Width="1000" Closing="Window_Closing" Style="{StaticResource {x:Type Window}}" WindowStartupLocation="CenterScreen" Icon="/FModel;component/Resources/Logo-Icon.ico" >
<Grid>
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem
Height="26"
Header="File"
RenderTransformOrigin="0.656,0.769">
<MenuItem
x:Name="OpenMenu"
Click="OpenMenu_Click"
Header="Open...">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/open_16x.png" Height="15" Width="15"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem
x:Name="SaveMenu"
Click="SaveMenu_Click"
Header="Save">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/save_16x.png" Height="15" Width="15"/>
</MenuItem.Icon>
</MenuItem>
<MenuItem
Click="SaveAsMenu_Click"
Header="Save as..."
IsEnabled="True" />
<Separator />
<MenuItem
x:Name="CloseFileMenu"
Click="CloseFileMenu_Click"
Header="Close file">
<MenuItem.Icon>
<Image Source="/FModel;component/Resources/close_file_16x.png" Height="15" Width="15"/>
</MenuItem.Icon>
</MenuItem>
<Separator />
<MenuItem
x:Name="ExitMenu"
Click="ExitMenu_Click"
Header="Exit" />
</MenuItem>
<MenuItem Header="Edit">
<MenuItem
x:Name="UndoMenu"
Click="UndoMenu_Click"
Header="Undo" />
<MenuItem
x:Name="RedoMenu"
Click="RedoMenu_Click"
Header="Redo" />
<Separator />
<MenuItem
x:Name="FindMenu"
Click="FindMenu_Click"
Header="Find..." />
<MenuItem
x:Name="ReplaceMenu"
Click="ReplaceMenu_Click"
Header="Find and replace..." />
<MenuItem
x:Name="FindAllSelection"
Click="FindAllSelection_Click"
Header="Find all occurence of selection" />
<Separator />
<MenuItem
x:Name="SetReadOnlyMenu"
Click="SetReadOnlyMenu_Click"
Header="Read only"
IsCheckable="True"
IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=ReadOnly, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<Separator />
<MenuItem
x:Name="CopyHexaMenu"
Click="CopyHexaMenu_Click"
Header="Copy hexadecimal string" />
<MenuItem
x:Name="CopyStringMenu"
Click="CopyStringMenu_Click"
Header="Copy ASCII string" />
<MenuItem
x:Name="DeleteSelectionMenu"
Click="DeleteSelectionMenu_Click"
Header="Delete selection" />
<Separator />
<MenuItem
x:Name="SelectAllButton"
Click="SelectAllButton_Click"
Header="Select all" />
<Separator />
<MenuItem Header="Bookmarks">
<MenuItem
x:Name="SetBookMarkButton"
Click="SetBookMarkButton_Click"
Header="Set position as bookmark" />
<MenuItem
x:Name="DeleteBookmark"
Click="DeleteBookmark_Click"
Header="Remove all bookmarks" />
</MenuItem>
<Separator />
<MenuItem Header="Character table">
<MenuItem
x:Name="CTableAsciiButton"
Click="CTableASCIIButton_Click"
Header="ASCII"
IsCheckable="True" />
<MenuItem
x:Name="CTableTblButton"
Click="CTableTBLButton_Click"
Header="Load TBL file" />
<MenuItem
x:Name="CTableTblDefaultEbcdicButton"
Click="CTableTblDefaultEBCDICButton_Click"
Header="Load Build-in TBL : EBCDIC with special character" />
<MenuItem
x:Name="CTableTblDefaultEbcdicnoSpButton"
Click="CTableTblDefaultEBCDICNoSPButton_Click"
Header="Load Build-in TBL : EBCDIC no special character" />
<MenuItem
x:Name="CTableTblDefaultAsciiButton"
Click="CTableTBLDefaultASCIIButton_Click"
Header="Load Build-in TBL : ASCII" />
</MenuItem>
</MenuItem>
<MenuItem x:Name="PositionMenu" Header="Position">
<StackPanel Orientation="Horizontal">
<Label Width="100" Content="Byte per line" Padding="0" />
<TextBox
Width="96"
VerticalContentAlignment="Center"
Text="{Binding BytePerLine, ElementName=HexEdit, UpdateSourceTrigger=LostFocus}"
TextWrapping="Wrap" Foreground="White" Padding="0,0,0,0" />
<Label Content="(Lost Focus)" Padding="10,0,0,0" />
</StackPanel>
<Separator />
<StackPanel Orientation="Horizontal">
<Label Width="100" Content="Byte shit left" Padding="0" />
<control:HexBox
x:Name="HbBsl"
Width="96"
ToolTip="ByteShiftLeft test" Height="15" />
<Separator />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Width="100" Content="Set position" Padding="0" />
<TextBox
x:Name="PositionText"
Width="75"
VerticalContentAlignment="Center"
TextChanged="PositionText_TextChanged" Padding="0" Foreground="White" />
<Button
x:Name="GoPositionButton"
Click="GOPosition_Click"
Content="GO"
IsEnabled="False" Padding="0,-2,0,0" Width="28" Foreground="White" Background="#FF333C46" Margin="5,0,0,0" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Width="100" Content="Set position" Padding="0" />
<control:HexBox
x:Name="HbSetPosition"
Width="96"
Height="15" />
</StackPanel>
</MenuItem>
<MenuItem x:Name="ViewMenu" Header="View">
<MenuItem
x:Name="ShowHeaderMenu"
Click="ShowHeaderMenu_Click"
Header="Header visibility"
IsCheckable="True"
IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=HeaderVisibility, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
<MenuItem
Click="StatusBarVisibility_Click"
Header="Statusbar visibility"
IsCheckable="True"
IsChecked="{Binding Source={x:Static properties:Settings.Default}, Path=StatusBarVisibility, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</MenuItem>
<MenuItem x:Name="OptionMenu" Header="Options">
<MenuItem
Header="Allow context menu"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowContextMenu, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Show byte ToolTip"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=ShowByteToolTip, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Auto highlight bytes same as the selected byte"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowAutoHighLightSelectionByte, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Auto select all same byte of SelectionStart in rage at double click"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowAutoSelectSameByteAtDoubleClick, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Count the number of the selected byte"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowByteCount, UpdateSourceTrigger=PropertyChanged}" />
<Separator />
<MenuItem
Header="Hide byte are deleted"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=HideByteDeleted, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Allow the possibility to delete byte"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowDeleteByte, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Allow expend at end of file"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowExtend, UpdateSourceTrigger=PropertyChanged}" />
<Separator />
<MenuItem
Header="Allow drop over control"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowDrop, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Allow file drop"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowFileDrop, UpdateSourceTrigger=PropertyChanged}" />
<MenuItem
Header="Allow text drop"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowTextDrop, UpdateSourceTrigger=PropertyChanged}" />
<Separator />
<MenuItem
Header="Allow zoom"
IsCheckable="True"
IsChecked="{Binding ElementName=HexEdit, Path=AllowZoom, UpdateSourceTrigger=PropertyChanged}" />
<Slider
x:Name="ZoomSlider"
Style="{StaticResource Horizontal_Slider}"
Width="225"
LargeChange="0.1"
Maximum="2"
Minimum="0.5"
ToolTip="Zoom editor (50% to 200%)"
Value="{Binding ElementName=HexEdit, Path=ZoomScale}" MinHeight="19" />
</MenuItem>
</Menu>
<TabControl>
<TabItem x:Name="TabHexEditor"
Height="20"
Margin="0"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Header="{Binding ElementName=HexEdit, Path=FileName, Converter={StaticResource FilenameConverter}}">
<control:HexEditor
x:Name="HexEdit"
Width="Auto"
Height="Auto"
AllowByteCount="False"
AllowDrop="True"
AllowExtend="False"
AppendNeedConfirmation="True"
ApplicationName="Hex Viewer"
BorderThickness="1"
ByteGrouping="FourByte"
ByteShiftLeft="{Binding LongValue, ElementName=HbBsl, UpdateSourceTrigger=PropertyChanged}"
ByteSpacerPositioning="HexBytePanel"
ByteSpacerVisualStyle="Dash"
ByteSpacerWidthTickness="Normal"
DataStringVisual="Hexadecimal"
DefaultCopyToClipboardMode="HexaString"
ForegroundSecondColor="Blue"
OffSetStringVisual="Hexadecimal"
UseCustomBackGroudBlock="True" BorderBrush="#7F748198" />
</TabItem>
</TabControl>
</DockPanel>
</Grid>
</Window>

View File

@ -1,217 +0,0 @@
using Microsoft.Win32;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using WpfHexaEditor.Core;
using WpfHexaEditor.Core.CharacterTable;
using WpfHexaEditor.Dialog;
using FModel.Properties;
using FProp = FModel.Properties.Settings;
namespace FModel.Forms.HexViewer
{
/// <summary>
/// Logique d'interaction pour HexViewer.xaml
/// </summary>
public partial class HexViewer : Window
{
private enum SettingEnum
{
HeaderVisibility,
ReadOnly,
ScrollVisibility,
StatusBarVisibility
}
public HexViewer()
{
InitializeComponent();
UpdateAllSettings();
}
private void OpenMenu_Click(object sender, RoutedEventArgs e)
{
var fileDialog = new OpenFileDialog();
//fileDialog.InitialDirectory = FProp.Default.FOutput_Path + "\\Exports\\";
if (fileDialog.ShowDialog() != null && File.Exists(fileDialog.FileName))
{
Application.Current.MainWindow.Cursor = Cursors.Wait;
HexEdit.FileName = fileDialog.FileName;
TabHexEditor.Header = Path.GetFileName(fileDialog.FileName);
Application.Current.MainWindow.Cursor = null;
}
}
private void SaveMenu_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Cursor = Cursors.Wait;
//HexEdit.SaveTBLFile();
HexEdit.SubmitChanges();
Application.Current.MainWindow.Cursor = null;
}
private void CloseFileMenu_Click(object sender, RoutedEventArgs e) => HexEdit.CloseProvider();
private void SetReadOnlyMenu_Click(object sender, RoutedEventArgs e) => UpdateSetting(SettingEnum.ReadOnly);
private void ShowHeaderMenu_Click(object sender, RoutedEventArgs e) => UpdateSetting(SettingEnum.HeaderVisibility);
private void StatusBarVisibility_Click(object sender, RoutedEventArgs e) => UpdateSetting(SettingEnum.StatusBarVisibility);
private void UpdateSetting(SettingEnum setting)
{
switch (setting)
{
case SettingEnum.HeaderVisibility:
HexEdit.HeaderVisibility = !Settings.Default.HeaderVisibility
? Visibility.Collapsed
: Visibility.Visible;
Settings.Default.HeaderVisibility = HexEdit.HeaderVisibility == Visibility.Visible;
break;
case SettingEnum.ReadOnly:
HexEdit.ReadOnlyMode = Settings.Default.ReadOnly;
HexEdit.ClearAllChange();
HexEdit.RefreshView();
break;
case SettingEnum.StatusBarVisibility:
HexEdit.StatusBarVisibility = !Settings.Default.StatusBarVisibility
? Visibility.Collapsed
: Visibility.Visible;
Settings.Default.StatusBarVisibility = HexEdit.StatusBarVisibility == Visibility.Visible;
break;
}
}
private void UpdateAllSettings()
{
UpdateSetting(SettingEnum.HeaderVisibility);
UpdateSetting(SettingEnum.ReadOnly);
UpdateSetting(SettingEnum.ScrollVisibility);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
HexEdit.CloseProvider();
Settings.Default.Save();
}
private void ExitMenu_Click(object sender, RoutedEventArgs e) => Close();
private void CopyHexaMenu_Click(object sender, RoutedEventArgs e) => HexEdit.CopyToClipboard(CopyPasteMode.HexaString);
private void CopyStringMenu_Click(object sender, RoutedEventArgs e) => HexEdit.CopyToClipboard();
private void DeleteSelectionMenu_Click(object sender, RoutedEventArgs e) => HexEdit.DeleteSelection();
private void GOPosition_Click(object sender, RoutedEventArgs e)
{
if (long.TryParse(PositionText.Text, out var position))
HexEdit.SetPosition(position, 1);
else
MessageBox.Show("Enter long value.");
ViewMenu.IsSubmenuOpen = false;
}
private void PositionText_TextChanged(object sender, TextChangedEventArgs e) =>
GoPositionButton.IsEnabled = long.TryParse(PositionText.Text, out var _);
private void UndoMenu_Click(object sender, RoutedEventArgs e) => HexEdit.Undo();
private void RedoMenu_Click(object sender, RoutedEventArgs e) => HexEdit.Redo();
private void SetBookMarkButton_Click(object sender, RoutedEventArgs e) => HexEdit.SetBookMark();
private void DeleteBookmark_Click(object sender, RoutedEventArgs e) => HexEdit.ClearScrollMarker(ScrollMarker.Bookmark);
private void FindAllSelection_Click(object sender, RoutedEventArgs e) => HexEdit.FindAllSelection(true);
private void SelectAllButton_Click(object sender, RoutedEventArgs e) => HexEdit.SelectAll();
private void CTableASCIIButton_Click(object sender, RoutedEventArgs e)
{
HexEdit.TypeOfCharacterTable = CharacterTableType.Ascii;
CTableAsciiButton.IsChecked = true;
CTableTblButton.IsChecked = false;
CTableTblDefaultAsciiButton.IsChecked = false;
}
private void CTableTBLButton_Click(object sender, RoutedEventArgs e)
{
var fileDialog = new OpenFileDialog();
if (fileDialog.ShowDialog() != null)
{
if (File.Exists(fileDialog.FileName))
{
Application.Current.MainWindow.Cursor = Cursors.Wait;
HexEdit.LoadTblFile(fileDialog.FileName);
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
CTableAsciiButton.IsChecked = false;
CTableTblButton.IsChecked = true;
CTableTblDefaultAsciiButton.IsChecked = false;
Application.Current.MainWindow.Cursor = null;
}
}
}
private void CTableTBLDefaultASCIIButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Cursor = Cursors.Wait;
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
HexEdit.LoadDefaultTbl();
Application.Current.MainWindow.Cursor = null;
}
private void SaveAsMenu_Click(object sender, RoutedEventArgs e)
{
var fileDialog = new SaveFileDialog();
if (fileDialog.ShowDialog() != null)
HexEdit.SubmitChanges(fileDialog.FileName, true);
}
private void CTableTblDefaultEBCDICButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Cursor = Cursors.Wait;
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
HexEdit.LoadDefaultTbl(DefaultCharacterTableType.EbcdicWithSpecialChar);
Application.Current.MainWindow.Cursor = null;
}
private void CTableTblDefaultEBCDICNoSPButton_Click(object sender, RoutedEventArgs e)
{
Application.Current.MainWindow.Cursor = Cursors.Wait;
HexEdit.TypeOfCharacterTable = CharacterTableType.TblFile;
HexEdit.LoadDefaultTbl(DefaultCharacterTableType.EbcdicNoSpecialChar);
Application.Current.MainWindow.Cursor = null;
}
private void FindMenu_Click(object sender, RoutedEventArgs e) =>
new FindWindow(HexEdit, HexEdit.SelectionByteArray)
{
Owner = this
}.Show();
private void ReplaceMenu_Click(object sender, RoutedEventArgs e) =>
new FindReplaceWindow(HexEdit, HexEdit.SelectionByteArray)
{
Owner = this
}.Show();
}
}

View File

@ -1,18 +0,0 @@
<!--
Apache 2.0 - 2016-2018
Author : Derek Tremblay (derektremblay666@gmail.com)
-->
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:WpfHexaEditor.Core.Converters">
<!-- THIS DICTIONNARY IS USED TO PUT VARIOUS RESSOURCES TYPE -->
<!-- VALUE CONVERTER -->
<conv:LongToHexStringConverter x:Key="LongHexConverter" />
<conv:BooleanToVisibilityConverter x:Key="BoolToVisibilityConverter" />
<conv:HexToLongStringConverter x:Key="HexToLongConverter" />
<conv:PathToFilenameConverter x:Key="FilenameConverter"/>
</ResourceDictionary>

Some files were not shown because too many files have changed in this diff Show More