implemented usmap

This commit is contained in:
iAmAsval 2021-01-04 14:12:08 +01:00
parent d05bed14a4
commit 841e76d2d7
23 changed files with 298 additions and 229 deletions

View File

@ -1,18 +1,22 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29806.167
VisualStudioVersion = 16.0.30804.86
MinimumVisualStudioVersion = 10.0.40219.1
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
{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
@ -20,6 +24,6 @@ Global
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FE6EA91D-BBB8-4FBC-875C-25AD92EDB519}
SolutionGuid = {688BAB53-42F7-45F2-AFDF-79A07771213F}
EndGlobalSection
EndGlobal

View File

@ -131,6 +131,7 @@
<PackageReference Include="System.Data.HashFunction.CityHash" Version="2.0.0" />
<PackageReference Include="ToastNotifications" Version="2.5.1" />
<PackageReference Include="ToastNotifications.Messages" Version="2.5.1" />
<PackageReference Include="Usmap.NET" Version="1.0.0" />
<PackageReference Include="WriteableBitmapEx" Version="1.6.7" />
</ItemGroup>

View File

@ -8,6 +8,7 @@ using FModel.Properties;
using ToastNotifications;
using ToastNotifications.Lifetime;
using ToastNotifications.Position;
using UsmapNET.Classes;
namespace FModel
{
@ -19,9 +20,9 @@ namespace FModel
/// </summary>
public static readonly Dictionary<string, PakFileReader> CachedPakFiles = new Dictionary<string, PakFileReader>();
public static readonly Dictionary<string, FFileIoStoreReader> CachedIoStores = new Dictionary<string, FFileIoStoreReader>();
public static readonly Dictionary<string, FUnversionedType> CachedSchemas = new Dictionary<string, FUnversionedType>();
public static Usmap Usmap = null;
public static FIoGlobalData GlobalData = null;
public static Dictionary<string, Dictionary<int, PropertyInfo>> TypeMappings;
public static Dictionary<string, Dictionary<int, string>> EnumMappings;
public static readonly Notifier gNotifier = new Notifier(cfg =>
{
cfg.LifetimeSupervisor = new TimeAndCountBasedLifetimeSupervisor(TimeSpan.FromSeconds(7), MaximumNotificationCount.FromCount(15));

View File

@ -0,0 +1,50 @@
using FModel.Logger;
using FModel.Utils;
using FModel.Windows.CustomNotifier;
using Newtonsoft.Json;
using System.Net.NetworkInformation;
using System.Threading.Tasks;
namespace FModel.Grabber.Mappings
{
static class MappingsData
{
public static async Task<Mapping[]> GetData()
{
if (NetworkInterface.GetIsNetworkAvailable())
{
Mapping[] data = await Endpoints.GetJsonEndpoint<Mapping[]>(Endpoints.BENBOT_MAPPINGS, string.Empty).ConfigureAwait(false);
return data;
}
else
{
Globals.gNotifier.ShowCustomMessage("Mappings", Properties.Resources.NoInternet, "/FModel;component/Resources/wifi-strength-off.ico");
DebugHelper.WriteLine("{0} {1} {2}", "[FModel]", "[Mappings]", "No internet");
return null;
}
}
}
public class Mapping
{
[JsonProperty("url")]
public string Url { get; set; }
[JsonProperty("fileName")]
public string FileName { get; set; }
[JsonProperty("hash")]
public string Hash { get; set; }
[JsonProperty("length")]
public string Length { get; set; }
[JsonProperty("uploaded")]
public string Uploaded { get; set; }
[JsonProperty("meta")]
public Metadata Meta { get; set; }
}
public class Metadata
{
[JsonProperty("version")]
public string Version { get; set; }
[JsonProperty("compressionMethod")]
public string CompressionMethod { get; set; }
}
}

View File

@ -0,0 +1,45 @@
using FModel.Utils;
using System;
using System.IO;
using System.Threading.Tasks;
using UsmapNET.Classes;
namespace FModel.Grabber.Mappings
{
static class MappingsGrabber
{
public static async Task<bool> Load(bool forceReload = false)
{
if (Globals.Game.ActualGame == EGame.Fortnite)
{
Mapping[] benMappings = await MappingsData.GetData().ConfigureAwait(false);
if (benMappings != null)
{
foreach (Mapping mapping in benMappings)
{
if (mapping.Meta.CompressionMethod == "Brotli")
{
DirectoryInfo chunksDir = Directory.CreateDirectory(Path.Combine(Properties.Settings.Default.OutputPath, "PakChunks"));
string mappingPath = Path.Combine(chunksDir.FullName, mapping.FileName);
byte[] mappingsData;
if (!forceReload && File.Exists(mappingPath))
{
mappingsData = await File.ReadAllBytesAsync(mappingPath);
}
else
{
mappingsData = await Endpoints.GetRawDataAsync(new Uri(mapping.Url)).ConfigureAwait(false);
await File.WriteAllBytesAsync(mappingPath, mappingsData).ConfigureAwait(false);
}
Globals.Usmap = new Usmap(mappingsData);
return true;
}
}
}
}
return false;
}
}
}

View File

@ -23,19 +23,15 @@ using FModel.Windows.Search;
using FModel.Windows.Settings;
using FModel.Windows.SoundPlayer;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using System.Net.NetworkInformation;
using FModel.Grabber.Mappings;
namespace FModel
{
@ -83,7 +79,6 @@ namespace FModel
Keys.NoKeyGoodBye();
MenuItems.FeedCustomGoTos();
AeConfiguration();
LoadMappings();
if (t.Exception != null) Tasks.TaskCompleted(t.Exception);
else StatusBarVm.statusBarViewModel.Set($"{Properties.Resources.Hello} {Environment.UserName}!", Properties.Resources.State);
@ -98,54 +93,22 @@ namespace FModel
{
await PaksGrabber.PopulateMenu().ConfigureAwait(false);
await AesGrabber.Load(Properties.Settings.Default.ReloadAesKeys).ConfigureAwait(false);
await MappingsGrabber.Load().ConfigureAwait(false);
await CdnDataGrabber.DoCDNStuff().ConfigureAwait(false);
await Folders.DownloadAndExtractVgm().ConfigureAwait(false);
if (Properties.Settings.Default.UseDiscordRpc) DiscordIntegration.StartClient();
}
private async void LoadMappings()
public async void ReloadMappings(object sender, RoutedEventArgs e)
{
string rawMappings = "{}";
string rawEnumMappings = "{}";
#if DEBUG
if (File.Exists("TypeMappings.json"))
if (await MappingsGrabber.Load(true).ConfigureAwait(false))
{
rawMappings = await File.ReadAllTextAsync("TypeMappings.json");
Globals.gNotifier.ShowCustomMessage("Mappings", "Reloaded successfully");
}
else if (NetworkInterface.GetIsNetworkAvailable())
else
{
rawMappings = await Endpoints.GetStringEndpoint(Endpoints.FORTNITE_TYPE_MAPPINGS);
Globals.gNotifier.ShowCustomMessage("Mappings", "Fail to reload");
}
if (File.Exists("EnumMappings.json"))
{
rawEnumMappings = await File.ReadAllTextAsync("EnumMappings.json");
}
else if (NetworkInterface.GetIsNetworkAvailable())
{
rawEnumMappings = await Endpoints.GetStringEndpoint(Endpoints.FORTNITE_ENUM_MAPPINGS);
}
#else
rawMappings = await Endpoints.GetStringEndpoint(Endpoints.FORTNITE_TYPE_MAPPINGS);
rawEnumMappings = await Endpoints.GetStringEndpoint(Endpoints.FORTNITE_ENUM_MAPPINGS);
#endif
var serializerSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new CamelCaseNamingStrategy(false, false)
}
};
Globals.TypeMappings = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<int, PakReader.IO.PropertyInfo>>>(rawMappings, serializerSettings);
Globals.EnumMappings = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<int, string>>>(rawEnumMappings, serializerSettings);
}
public void ReloadMappings(object sender, RoutedEventArgs e)
{
LoadMappings();
Globals.gNotifier.ShowCustomMessage("Mappings", "Reloaded successfully");
}
private void AeConfiguration()

View File

@ -27,7 +27,11 @@ namespace FModel.PakReader.IO
public static bool operator ==(FIoDirectoryIndexHandle a, FIoDirectoryIndexHandle b) => a._handle == b._handle;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static bool operator !=(FIoDirectoryIndexHandle a, FIoDirectoryIndexHandle b) => a._handle != b._handle;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public bool Equals(FIoDirectoryIndexHandle b) => _handle == b._handle;
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public override bool Equals(object obj) => obj is FIoDirectoryIndexHandle handle && Equals(handle);
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static FIoDirectoryIndexHandle FromIndex(uint index) => new FIoDirectoryIndexHandle(index);
}

View File

@ -17,8 +17,7 @@ namespace FModel.PakReader.IO
{
_zeroMask = header.ZeroMask;
_fragmentIt = header.Fragments.GetEnumerator();
if (header.HasValues)
Skip();
Skip();
}
public bool MoveNext()

View File

@ -0,0 +1,29 @@
using System.Collections.Generic;
using UsmapNET.Classes;
namespace FModel.PakReader.IO
{
public class FUnversionedType
{
public string Name { get; }
public Dictionary<int, FUnversionedProperty> Properties { get; set; }
public FUnversionedType(string name)
{
Name = name;
Properties = new Dictionary<int, FUnversionedProperty>();
}
}
public class FUnversionedProperty
{
public string Name { get; set; }
public UsmapPropertyData Data { get; set; }
public FUnversionedProperty(UsmapProperty prop)
{
Name = prop.Name;
Data = prop.Data;
}
}
}

View File

@ -1,34 +0,0 @@
using Newtonsoft.Json;
namespace FModel.PakReader.IO
{
public class PropertyInfo
{
public string Name;
public string Type;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string StructType;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public bool? Bool;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string EnumName;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string EnumType;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string InnerType;
[JsonProperty(NullValueHandling = NullValueHandling.Ignore)]
public string ValueType;
public PropertyInfo(string name, string type, string structType = null, bool? b = null, string enumName = null, string enumType = null, string innerType = null, string valueType = null)
{
Name = name;
Type = type;
StructType = structType;
Bool = b;
EnumName = enumName;
EnumType = enumType;
InnerType = innerType;
ValueType = valueType;
}
}
}

View File

@ -2,7 +2,6 @@
using System.Collections.Generic;
using System.IO;
using System.Runtime.CompilerServices;
using FModel.PakReader.IO;
using FModel.PakReader.Parsers.Objects;
namespace FModel.PakReader.Parsers.Class
@ -34,17 +33,18 @@ namespace FModel.PakReader.Parsers.Class
}
}
internal UCurveTable(IoPackageReader reader)
internal UCurveTable(IoPackageReader reader, string _)
{
reader.ReadUInt16(); // don't ask me
reader.ReadUInt32(); // what this is
int NumRows = reader.ReadInt32();
CurveTableMode = (ECurveTableMode)reader.ReadByte();
Dictionary<int, PropertyInfo> properties = CurveTableMode switch
string export = CurveTableMode switch
{
ECurveTableMode.RichCurves => Globals.TypeMappings["RichCurve"],
ECurveTableMode.SimpleCurves => Globals.TypeMappings["SimpleCurve"],
ECurveTableMode.RichCurves => "RichCurve",
ECurveTableMode.SimpleCurves => "SimpleCurve",
_ => throw new FileLoadException($"This table has an unknown mode ({CurveTableMode})")
};
@ -59,7 +59,7 @@ namespace FModel.PakReader.Parsers.Class
RowName = $"{baseName}_NK{num++:00}";
}
RowMap[RowName] = new UObject(reader, properties, true);
RowMap[RowName] = new UObject(reader, export, true);
}
}

View File

@ -1,8 +1,8 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using FModel.PakReader.IO;
using FModel.PakReader.Parsers.PropertyTagData;
using FModel.Utils;
@ -34,24 +34,21 @@ namespace FModel.PakReader.Parsers.Class
}
}
internal UDataTable(IoPackageReader reader, IReadOnlyDictionary<int, PropertyInfo> properties, string type)
internal UDataTable(IoPackageReader reader, string type)
{
var baseObj = new UObject(reader, properties, type: type);
var baseObj = new UObject(reader, type);
if (!baseObj.TryGetValue("RowStruct", out var rowStructProp) || !(rowStructProp is ObjectProperty rowStruct) || !rowStruct.Value.IsImport)
{
return;
}
var rowStructimportIndex = rowStruct.Value.AsImport;
if (rowStructimportIndex >= reader.ImportMap.Length)
{
return;
}
var rowStructimport = reader.ImportMap[rowStructimportIndex];
if (rowStructimport.Type != EType.ScriptImport ||
!Globals.GlobalData.ScriptObjectByGlobalId.TryGetValue(rowStructimport, out var rowStrucDesc) ||
rowStrucDesc.Name.IsNone)
@ -59,11 +56,13 @@ namespace FModel.PakReader.Parsers.Class
return;
}
if (!Globals.TypeMappings.TryGetValue(rowStrucDesc.Name.String, out var rowProperties))
{
FConsole.AppendText($"{reader.Summary.Name.String} can't be parsed yet (RowType: {rowStrucDesc.Name.String})", FColors.Red, true);
return;
}
// this slows down icon generation
//bool hasStruct = Globals.Usmap.Schemas.Any(x => x.Name == rowStrucDesc.Name.String);
//if (!hasStruct)
//{
// FConsole.AppendText($"{reader.Summary.Name.String} can't be parsed yet (RowType: {rowStrucDesc.Name.String})", FColors.Red, true);
// return;
//}
var NumRows = reader.ReadInt32();
RowMap = new Dictionary<string, object>();
@ -79,7 +78,7 @@ namespace FModel.PakReader.Parsers.Class
RowName = $"{baseName}_NK{num++:00}";
}
RowMap[RowName] = new UObject(reader, rowProperties, true, rowStrucDesc.Name.String);
RowMap[RowName] = new UObject(reader, rowStrucDesc.Name.String, true);
}
}

View File

@ -12,63 +12,51 @@ namespace FModel.PakReader.Parsers.Class
{
private readonly Dictionary<string, object> Dict;
public UObject(IoPackageReader reader, IReadOnlyDictionary<int, PropertyInfo> properties, bool structFallback = false, string type = null)
public UObject(IoPackageReader reader, string type, bool structFallback = false)
{
Dict = new Dictionary<string, object>();
var header = new FUnversionedHeader(reader);
if (!header.HasValues)
if (header.HasValues)
{
if (!structFallback && reader.ReadInt32() != 0 /* && reader.Position + 16 <= maxSize*/)
reader.Position += FGuid.SIZE;
return;
}
using var it = new FIterator(header);
FUnversionedType unversionedType = reader.GetOrCreateSchema(type);
using var it = new FIterator(header);
if (header.HasNonZeroValues)
{
var num = 1;
do
{
var (val, isNonZero) = it.Current;
if (unversionedType.Properties.TryGetValue(val, out var props))
{
var propertyTag = new FPropertyTag(props);
if (isNonZero)
{
var key = Dict.ContainsKey(props.Name) ? $"{props.Name}_NK{num++:00}" : props.Name;
var obj = BaseProperty.ReadAsObject(reader, propertyTag, propertyTag.Type, ReadType.NORMAL);
Dict[key] = obj;
}
else
{
var key = Dict.ContainsKey(props.Name) ? $"{props.Name}_NK{num++:00}" : props.Name;
var obj = BaseProperty.ReadAsZeroObject(reader, propertyTag, propertyTag.Type);
Dict[key] = obj;
}
}
else Dict[val.ToString()] = null;
} while (it.MoveNext());
}
else
{
#if DEBUG
var headerWritten = false;
do
{
if (properties.ContainsKey(it.Current.Val))
continue;
if (!headerWritten)
{
headerWritten = true;
FConsole.AppendText(string.Concat("\n", type ?? "Unknown", ": ", reader.Summary.Name.String), "#CA6C6C", true);
}
FConsole.AppendText($"Val: {it.Current.Val} (IsNonZero: {it.Current.IsNonZero})", FColors.Yellow, true);
}
while (it.MoveNext());
it.Reset();
do
{
FConsole.AppendText($"Val: {it.Current.Val} (IsNonZero: {it.Current.IsNonZero})", FColors.Yellow, true);
}
while (it.MoveNext());
#endif
var num = 1;
do
{
var (val, isNonZero) = it.Current;
if (properties.TryGetValue(val, out var propertyInfo))
{
if (isNonZero)
{
var key = Dict.ContainsKey(propertyInfo.Name) ? $"{propertyInfo.Name}_NK{num++:00}" : propertyInfo.Name;
var obj = BaseProperty.ReadAsObject(reader, new FPropertyTag(propertyInfo), new FName(propertyInfo.Type), ReadType.NORMAL);
Dict[key] = obj;
}
else
{
var obj = BaseProperty.ReadAsZeroObject(reader, new FPropertyTag(propertyInfo), new FName(propertyInfo.Type));
var key = Dict.ContainsKey(propertyInfo.Name) ? $"{propertyInfo.Name}_NK{num++:00}" : propertyInfo.Name;
Dict[key] = obj;
}
}
else Dict[val.ToString()] = null;
} while (it.MoveNext());
}
if (!structFallback && reader.ReadInt32() != 0 /* && reader.Position + 16 <= maxSize*/)
reader.Position += FGuid.SIZE;

View File

@ -1,8 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using FModel.PakReader.IO;
using FModel.PakReader.Parsers.Objects;
using FModel.PakReader.Parsers.PropertyTagData;
@ -53,8 +51,7 @@ namespace FModel.PakReader.Parsers.Class
}
}
internal USoundWave(IoPackageReader reader, Dictionary<int, PropertyInfo> properties, Stream ubulk,
long ubulkOffset) : base(reader, properties)
internal USoundWave(IoPackageReader reader, string type, Stream ubulk, long ubulkOffset) : base(reader, type)
{
Serialize(reader, ubulk, ubulkOffset);
}

View File

@ -1,6 +1,5 @@
using System.Collections.Generic;
using System.IO;
using FModel.PakReader.IO;
using FModel.PakReader.Parsers.Objects;
using FModel.PakReader.Textures;
using SkiaSharp;
@ -50,8 +49,7 @@ namespace FModel.PakReader.Parsers.Class
}
}
internal UTexture2D(IoPackageReader reader, Dictionary<int, PropertyInfo> properties, Stream ubulk,
long bulkOffset) : base(reader, properties)
internal UTexture2D(IoPackageReader reader, string type, Stream ubulk, long bulkOffset) : base(reader, type)
{
Serialize(reader, ubulk, bulkOffset);
}

View File

@ -8,6 +8,7 @@ using FModel.PakReader.IO;
using FModel.PakReader.Parsers.Class;
using FModel.PakReader.Parsers.Objects;
using FModel.Utils;
using UsmapNET.Classes;
namespace FModel.PakReader.Parsers
{
@ -159,36 +160,16 @@ namespace FModel.PakReader.Parsers
_dataExportTypes[i] = exportType;
try
{
if (Globals.TypeMappings.TryGetValue(exportType.String, out var properties))
_dataExports[i] = exportType.String switch
{
_dataExports[i] = exportType.String switch
{
"Texture2D" => new UTexture2D(this, properties, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
"TextureCube" => new UTexture2D(this, properties, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
"VirtualTexture2D" => new UTexture2D(this, properties, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
"CurveTable" => new UCurveTable(this),
"DataTable" => new UDataTable(this, properties, exportType.String),
"SoundWave" => new USoundWave(this, properties, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
_ => new UObject(this, properties, structFallback, exportType.String),
};
}
else
{
_dataExports[i] = new UObject();
#if DEBUG
var header = new FUnversionedHeader(this);
if (!header.HasValues)
continue;
using var it = new FIterator(header);
FConsole.AppendText(string.Concat("\n", exportType.String, ": ", Summary.Name.String), "#CA6C6C", true);
do
{
FConsole.AppendText($"Val: {it.Current.Val} (IsNonZero: {it.Current.IsNonZero})", FColors.Yellow, true);
}
while (it.MoveNext());
#endif
}
"Texture2D" => new UTexture2D(this, exportType.String, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
"TextureCube" => new UTexture2D(this, exportType.String, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
"VirtualTexture2D" => new UTexture2D(this, exportType.String, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
"CurveTable" => new UCurveTable(this, exportType.String),
"DataTable" => new UDataTable(this, exportType.String),
"SoundWave" => new USoundWave(this, exportType.String, _ubulk, ExportMap.Sum(e => (long)e.CookedSerialSize) + beginExportOffset),
_ => new UObject(this, exportType.String, structFallback),
};
}
catch (Exception e)
{
@ -203,6 +184,45 @@ namespace FModel.PakReader.Parsers
public override string ToString() => Summary.Name.String;
public FUnversionedType GetOrCreateSchema(string export)
{
if (Globals.CachedSchemas.TryGetValue(export, out var v))
{
return v;
}
else
{
var type = export;
var bNested = false;
var bNop = false;
var ret = new FUnversionedType(type);
while (type != null)
{
var schema = Globals.Usmap.Schemas.FirstOrDefault(x => x.Name == type);
if (schema.Name != null)
{
var lastIndex = ret.Properties.LastOrDefault().Key;
if (!bNop && (bNested && schema.PropCount > 0)) lastIndex++;
foreach (var prop in schema.Properties)
{
for (int i = 0; i < prop.ArraySize; i++)
{
ret.Properties[lastIndex + i + prop.SchemaIdx] = new FUnversionedProperty(prop);
}
}
bNop = !bNested && schema.PropCount == 0;
bNested = true;
type = schema.SuperType;
}
}
Globals.CachedSchemas[export] = ret;
return ret;
}
}
private string Transform(string path)
{
string gname = Folders.GetGameName();

View File

@ -1,4 +1,5 @@
using Newtonsoft.Json;
using UsmapNET.Classes;
namespace FModel.PakReader.Parsers.Objects
{
@ -23,6 +24,13 @@ namespace FModel.PakReader.Parsers.Objects
Number = number;
}
public FName(UsmapPropertyData name, int index = 0, int number = 0)
{
String = name != null ? name.Type.ToString() : "None";
Index = index;
Number = number;
}
public FName(string name, int index = 0, int number = 0)
{
String = name;

View File

@ -21,16 +21,27 @@ namespace FModel.PakReader.Parsers.Objects
public readonly FName Type; // Variables
public readonly FName ValueType;
public FPropertyTag(PropertyInfo info)
public FPropertyTag(FUnversionedProperty info)
{
BoolVal = 0;
Name = new FName(info.Name);
Type = new FName(info.Type);
StructName = new FName(info.StructType);
BoolVal = (byte) ((info.Bool ?? false) ? 1 : 0);
EnumName = new FName(info.EnumName);
EnumType = new FName(info.EnumType);
InnerType = new FName(info.InnerType);
ValueType = new FName(info.ValueType);
Type = new FName(info.Data);
StructName = new FName(info.Data.StructType);
EnumName = new FName(info.Data.EnumName);
EnumType = new FName(info.Data.InnerType);
InnerType = new FName(info.Data.InnerType);
ValueType = new FName(info.Data.ValueType);
if (InnerType.String == "StructProperty")
{
StructName = new FName(info.Data.InnerType.StructType);
}
else if (ValueType.String == "StructProperty")
{
StructName = new FName(info.Data.ValueType.StructType);
}
ArrayIndex = 0;
Position = 0;
HasPropertyGuid = 0;

View File

@ -1,7 +1,4 @@
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using FModel.PakReader.IO;
using System.Runtime.CompilerServices;
using FModel.PakReader.Parsers.Class;
namespace FModel.PakReader.Parsers.Objects
@ -121,7 +118,7 @@ namespace FModel.PakReader.Parsers.Objects
{
if (reader is IoPackageReader ioReader)
{
return Globals.TypeMappings.TryGetValue(structName, out var structProperties) ? new UObject(ioReader, structProperties, true, structName) : new UObject(ioReader, new Dictionary<int, PropertyInfo>(), true, structName);
return new UObject(ioReader, structName, true);
}
return new UObject(reader, true);

View File

@ -1,4 +1,5 @@
using FModel.PakReader.Parsers.Objects;
using System.Linq;
namespace FModel.PakReader.Parsers.PropertyTagData
{
@ -11,7 +12,6 @@ namespace FModel.PakReader.Parsers.PropertyTagData
internal EnumProperty(PackageReader reader, FPropertyTag tag, ReadType readType)
{
Position = reader.Position;
if (!(reader is IoPackageReader) || readType != ReadType.NORMAL)
{
Value = reader.ReadFName();
@ -23,23 +23,16 @@ namespace FModel.PakReader.Parsers.PropertyTagData
}
}
private static string ByteToEnum(string enumName, int value)
private static string ByteToEnum(string enumName, int index)
{
if (enumName == null)
return value.ToString();
return index.ToString();
string result;
if (Globals.EnumMappings.TryGetValue(enumName, out var values))
{
result = values.TryGetValue(value, out var member) ? string.Concat(enumName, "::", member) : string.Concat(enumName, "::", value);
}
var enumProp = Globals.Usmap.Enums.FirstOrDefault(x => x.Name == enumName);
if (!enumProp.Equals(default))
return index >= enumProp.Names.Length ? string.Concat(enumName, "::", index) : string.Concat(enumName, "::", enumProp.Names[index]);
else
{
result = string.Concat(enumName, "::", value);
}
return result;
return string.Concat(enumName, "::", index);
}
public string GetValue() => Value.String;

View File

@ -1,4 +1,3 @@
using System;
using System.Collections.Generic;
using FModel.PakReader.Parsers.Objects;

View File

@ -13,7 +13,7 @@ namespace FModel.PakReader.Parsers.PropertyTagData
{
Position = reader.Position;
Value = new FSoftObjectPath(reader);
if (readType == ReadType.MAP)
if (!(reader is IoPackageReader) && readType == ReadType.MAP)
reader.Position += 16 - (reader.Position - Position); // skip ahead, putting the total bytes read to 16
}

View File

@ -14,9 +14,8 @@ namespace FModel.Utils
static class Endpoints
{
public static readonly FortniteApi FortniteAPI = new FortniteApi($"FModel/{Assembly.GetExecutingAssembly().GetName().Version}");
public const string FORTNITE_TYPE_MAPPINGS = "https://raw.githubusercontent.com/FabianFG/FortniteTypeMappings/master/TypeMappings.json";
public const string FORTNITE_ENUM_MAPPINGS = "https://raw.githubusercontent.com/FabianFG/FortniteTypeMappings/master/EnumMappings.json";
public const string BENBOT_AES = "https://benbotfn.tk/api/v1/aes";
public const string BENBOT_MAPPINGS = "https://benbotfn.tk/api/v1/mappings";
public const string BENBOT_HOTFIXES = "https://benbotfn.tk/api/v1/hotfixes";
public const string FMODEL_JSON = "https://dl.dropbox.com/s/sxyaqo6zu1drlea/FModel.json?dl=0";
public const string OAUTH_URL = "https://account-public-service-prod03.ol.epicgames.com/account/api/oauth/token";
@ -25,17 +24,15 @@ namespace FModel.Utils
public static byte[] GetRawData(Uri uri) => GetRawDataAsync(uri).GetAwaiter().GetResult();
public static async Task<byte[]> GetRawDataAsync(Uri uri)
{
using (HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(2) })
using HttpClient client = new HttpClient { Timeout = TimeSpan.FromSeconds(2) };
try
{
try
{
var data = await client.GetByteArrayAsync(uri).ConfigureAwait(false);
return data;
}
catch
{
return null;
}
var data = await client.GetByteArrayAsync(uri).ConfigureAwait(false);
return data;
}
catch
{
return null;
}
}