mirror of
https://github.com/4sval/FModel.git
synced 2026-06-21 23:40:12 -05:00
Merge branch '4sval:dev' into dev
This commit is contained in:
commit
21f3d47ccc
4
.github/workflows/main.yml
vendored
4
.github/workflows/main.yml
vendored
|
|
@ -21,10 +21,10 @@ jobs:
|
|||
- name: Fetch Submodules Recursively
|
||||
run: git submodule update --init --recursive
|
||||
|
||||
- name: .NET 8 Setup
|
||||
- name: .NET 10 Setup
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: .NET Restore
|
||||
run: dotnet restore FModel
|
||||
|
|
|
|||
6
.github/workflows/qa.yml
vendored
6
.github/workflows/qa.yml
vendored
|
|
@ -14,16 +14,16 @@ jobs:
|
|||
with:
|
||||
submodules: 'recursive'
|
||||
|
||||
- name: .NET 8 Setup
|
||||
- name: .NET 10 Setup
|
||||
uses: actions/setup-dotnet@v5
|
||||
with:
|
||||
dotnet-version: '8.0.x'
|
||||
dotnet-version: '10.0.x'
|
||||
|
||||
- name: .NET Restore
|
||||
run: dotnet restore "./FModel/FModel.slnx" -r win-x64
|
||||
|
||||
- name: .NET Publish
|
||||
run: dotnet publish "./FModel/FModel.csproj" -c Release --no-restore --no-self-contained -r win-x64 -f net8.0-windows -o "./FModel/bin/Publish/" -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:DebugType=None -p:GenerateDocumentationFile=false -p:DebugSymbols=false
|
||||
run: dotnet publish "./FModel/FModel.csproj" -c Release --no-restore --no-self-contained -r win-x64 -f net10.0-windows -o "./FModel/bin/Publish/" -p:PublishReadyToRun=false -p:PublishSingleFile=true -p:DebugType=None -p:GenerateDocumentationFile=false -p:DebugSymbols=false
|
||||
|
||||
- name: ZIP File
|
||||
uses: thedoctor0/zip-release@0.7.6
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 81458ae77d3f3230d7582a77ffd938510430a4bf
|
||||
Subproject commit bf3c09087c2a4d7d812582e268ec0d275a0827fd
|
||||
|
|
@ -45,6 +45,7 @@ public class CreatorPackage : IDisposable
|
|||
case "AthenaMusicPackItemDefinition":
|
||||
case "AthenaBattleBusItemDefinition":
|
||||
case "AthenaCharacterItemDefinition":
|
||||
case "ExtractableItemDefinition":
|
||||
case "AthenaMapMarkerItemDefinition":
|
||||
case "AthenaBackpackItemDefinition":
|
||||
case "CosmeticShoesItemDefinition":
|
||||
|
|
|
|||
|
|
@ -163,6 +163,7 @@ public enum EAssetCategory : uint
|
|||
Aion2 = GameSpecific + 2,
|
||||
RocoKingdomWorld = GameSpecific + 3,
|
||||
DeltaForce = GameSpecific + 4,
|
||||
LegoBatman = GameSpecific + 5,
|
||||
}
|
||||
|
||||
public enum EUnluacMode
|
||||
|
|
|
|||
|
|
@ -49,6 +49,7 @@ public static class AvalonExtensions
|
|||
case "bat":
|
||||
case "txt":
|
||||
case "pem":
|
||||
case "js":
|
||||
case "po":
|
||||
return null;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<TargetFramework>net10.0-windows</TargetFramework>
|
||||
<UseWPF>true</UseWPF>
|
||||
<ApplicationIcon>FModel.ico</ApplicationIcon>
|
||||
<Version>4.4.4.0</Version>
|
||||
|
|
@ -152,27 +152,25 @@
|
|||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AdonisUI" Version="1.17.1" />
|
||||
<PackageReference Include="AdonisUI.ClassicTheme" Version="1.17.1" />
|
||||
<PackageReference Include="Autoupdater.NET.Official" Version="1.9.2" />
|
||||
<PackageReference Include="AvalonEdit" Version="6.3.1.120" />
|
||||
<PackageReference Include="CSCore" Version="1.2.1.2" />
|
||||
<PackageReference Include="DiscordRichPresence" Version="1.6.1.70" />
|
||||
<PackageReference Include="EpicManifestParser" Version="2.4.1" />
|
||||
<PackageReference Include="EpicManifestParser.ZlibngDotNetDecompressor" Version="1.0.1" />
|
||||
<PackageReference Include="EpicManifestParser" Version="3.0.0-preview.1" />
|
||||
<PackageReference Include="FModel.AdonisUI" Version="1.18.0" />
|
||||
<PackageReference Include="FModel.AdonisUI.ClassicTheme" Version="1.18.0" />
|
||||
<PackageReference Include="K4os.Compression.LZ4.Streams" Version="1.3.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="NVorbis" Version="0.10.5" />
|
||||
<PackageReference Include="Ookii.Dialogs.Wpf" Version="5.0.1" />
|
||||
<PackageReference Include="OpenTK" Version="4.9.4" />
|
||||
<PackageReference Include="RestSharp" Version="113.0.0" />
|
||||
<PackageReference Include="Serilog" Version="4.3.0" />
|
||||
<PackageReference Include="RestSharp" Version="114.0.0" />
|
||||
<PackageReference Include="Serilog" Version="4.3.1" />
|
||||
<PackageReference Include="Serilog.Sinks.File" Version="7.0.0" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="3.1.12" />
|
||||
<PackageReference Include="SkiaSharp.HarfBuzz" Version="2.88.9" />
|
||||
<PackageReference Include="Svg.Skia" Version="3.2.1" />
|
||||
<PackageReference Include="SkiaSharp.HarfBuzz" Version="[2.88.9]" />
|
||||
<PackageReference Include="Svg.Skia" Version="[4.8.0]" /> <!--because of skia 3.0 in newer versions-->
|
||||
<PackageReference Include="Twizzle.ImGui-Bundle.NET" Version="1.91.5.2" />
|
||||
<PackageReference Include="VirtualizingWrapPanel" Version="2.3.2" />
|
||||
<PackageReference Include="VirtualizingWrapPanel" Version="2.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
|
|
@ -1,37 +0,0 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.0.31912.275
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FModel", "FModel.csproj", "{B1F494EA-90A6-4C24-800E-2F724A1884CA}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUE4Parse", "..\CUE4Parse\CUE4Parse\CUE4Parse.csproj", "{C4620341-BBB7-4384-AC7D-5082D3E0386E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CUE4Parse-Conversion", "..\CUE4Parse\CUE4Parse-Conversion\CUE4Parse-Conversion.csproj", "{D0E1E8F7-F56D-469A-8E24-C2439B9FFD83}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{B1F494EA-90A6-4C24-800E-2F724A1884CA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{B1F494EA-90A6-4C24-800E-2F724A1884CA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{B1F494EA-90A6-4C24-800E-2F724A1884CA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{B1F494EA-90A6-4C24-800E-2F724A1884CA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C4620341-BBB7-4384-AC7D-5082D3E0386E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C4620341-BBB7-4384-AC7D-5082D3E0386E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C4620341-BBB7-4384-AC7D-5082D3E0386E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C4620341-BBB7-4384-AC7D-5082D3E0386E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D0E1E8F7-F56D-469A-8E24-C2439B9FFD83}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D0E1E8F7-F56D-469A-8E24-C2439B9FFD83}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D0E1E8F7-F56D-469A-8E24-C2439B9FFD83}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D0E1E8F7-F56D-469A-8E24-C2439B9FFD83}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {53DB7A15-4E15-4575-9402-0110BDF2794E}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
@ -1,58 +1,76 @@
|
|||
<SyntaxDefinition name="Lua" extensions=".lua;.luac" xmlns="http://icsharpcode.net/sharpdevelop/syntaxdefinition/2008">
|
||||
<Color name="Keyword1" foreground="#C586C0" fontWeight="bold" />
|
||||
<Color name="Keyword2" foreground="#569CD6" fontWeight="bold" />
|
||||
<Color name="Comment" foreground="#6A9955" />
|
||||
<Color name="String" foreground="#D69D85" />
|
||||
<Color name="Number" foreground="#B5CEA8" />
|
||||
<Color name="Function" foreground="#DCDCAA" />
|
||||
<Color name="Punctuation" foreground="#89DDFF" />
|
||||
<Color name="ObjectName" foreground="#3DC9B0" />
|
||||
<Color name="Constant" foreground="#9CDCFE" />
|
||||
<Color name="Keyword1" foreground="#d8a0df" fontWeight="bold" />
|
||||
<Color name="Keyword2" foreground="#569cd6" fontWeight="bold" />
|
||||
<Color name="Self" foreground="#569cd6" fontStyle="italic" />
|
||||
<Color name="Function" foreground="#dcdcaa" />
|
||||
<Color name="ObjectName" foreground="#4ec9b0" />
|
||||
<Color name="Property" foreground="#abd4a2" />
|
||||
<Color name="String" foreground="#f4ab6b" />
|
||||
<Color name="Number" foreground="#ff9e64" />
|
||||
<Color name="Comment" foreground="#565f89" fontStyle="italic" />
|
||||
<Color name="Punctuation" foreground="#89ddff" />
|
||||
<Color name="Constant" foreground="#e0af68" />
|
||||
<Color name="Metamethod" foreground="#bb9af7" fontStyle="italic" />
|
||||
<Color name="GotoLabel" foreground="#7dcfff" />
|
||||
<Color name="Discard" foreground="#3b4261" />
|
||||
|
||||
<RuleSet>
|
||||
<Rule color="Comment">--\[\[(.|\n)*?\]\]</Rule>
|
||||
<Rule color="Comment">--.*$</Rule>
|
||||
|
||||
<Rule color="String">\[\[(.|\n)*?\]\]</Rule>
|
||||
<Rule color="String">"([^"\\]|\\.)*"</Rule>
|
||||
<Rule color="String">'([^'\\]|\\.)*'</Rule>
|
||||
|
||||
<Rule color="Number">\b0[xX][0-9A-Fa-f]+\b</Rule>
|
||||
<Rule color="Number">\b\d+\.\d+([eE][+-]?\d+)?\b</Rule>
|
||||
<Rule color="Number">\b\d+[eE][+-]?\d+\b</Rule>
|
||||
<Rule color="Number">\b\d+\b</Rule>
|
||||
|
||||
<Keywords color="Keyword1">
|
||||
<Word>return</Word>
|
||||
<Word>function</Word>
|
||||
<Word>goto</Word>
|
||||
<Word>end</Word>
|
||||
<Word>if</Word>
|
||||
<Word>and</Word>
|
||||
<Word>break</Word>
|
||||
<Word>do</Word>
|
||||
<Word>else</Word>
|
||||
<Word>elseif</Word>
|
||||
<Word>then</Word>
|
||||
<Word>end</Word>
|
||||
<Word>for</Word>
|
||||
<Word>function</Word>
|
||||
<Word>goto</Word>
|
||||
<Word>if</Word>
|
||||
<Word>in</Word>
|
||||
<Word>or</Word>
|
||||
<Word>repeat</Word>
|
||||
<Word>return</Word>
|
||||
<Word>then</Word>
|
||||
<Word>until</Word>
|
||||
<Word>while</Word>
|
||||
<Word>break</Word>
|
||||
<Word>or</Word>
|
||||
<Word>and</Word>
|
||||
<Word>repeat</Word>
|
||||
<Word>do</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="Keyword2">
|
||||
<Word>false</Word>
|
||||
<Word>local</Word>
|
||||
<Word>nil</Word>
|
||||
<Word>not</Word>
|
||||
<Word>true</Word>
|
||||
<Word>false</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="Self">
|
||||
<Word>self</Word>
|
||||
<Word>_G</Word>
|
||||
<Word>_ENV</Word>
|
||||
</Keywords>
|
||||
|
||||
<Keywords color="Function">
|
||||
<!-- Core functions -->
|
||||
<Word>assert</Word>
|
||||
<Word>collectgarbage</Word>
|
||||
<Word>dofile</Word>
|
||||
<Word>error</Word>
|
||||
<Word>getmetatable</Word>
|
||||
<Word>ipairs</Word>
|
||||
<Word>load</Word>
|
||||
<Word>loadfile</Word>
|
||||
<Word>module</Word>
|
||||
<Word>next</Word>
|
||||
<Word>pairs</Word>
|
||||
<Word>pcall</Word>
|
||||
|
|
@ -61,128 +79,24 @@
|
|||
<Word>rawget</Word>
|
||||
<Word>rawlen</Word>
|
||||
<Word>rawset</Word>
|
||||
<Word>require</Word>
|
||||
<Word>select</Word>
|
||||
<Word>setmetatable</Word>
|
||||
<Word>tonumber</Word>
|
||||
<Word>tostring</Word>
|
||||
<Word>type</Word>
|
||||
<Word>unpack</Word>
|
||||
<Word>xpcall</Word>
|
||||
<Word>getmetatable</Word>
|
||||
<Word>require</Word>
|
||||
<Word>module</Word>
|
||||
|
||||
<!-- Modules / tables -->
|
||||
<Word>bit32</Word>
|
||||
<Word>coroutine</Word>
|
||||
<Word>debug</Word>
|
||||
<Word>io</Word>
|
||||
<Word>math</Word>
|
||||
<Word>os</Word>
|
||||
<Word>package</Word>
|
||||
<Word>string</Word>
|
||||
<Word>table</Word>
|
||||
<Word>coroutine</Word>
|
||||
<Word>os</Word>
|
||||
<Word>io</Word>
|
||||
<Word>utf8</Word>
|
||||
<Word>bit32</Word>
|
||||
<Word>package</Word>
|
||||
<Word>debug</Word>
|
||||
|
||||
<!-- Bit32 / bitwise functions -->
|
||||
<Word>arshift</Word>
|
||||
<Word>band</Word>
|
||||
<Word>bnot</Word>
|
||||
<Word>bor</Word>
|
||||
<Word>bxor</Word>
|
||||
<Word>btest</Word>
|
||||
<Word>extract</Word>
|
||||
<Word>lrotate</Word>
|
||||
<Word>lshift</Word>
|
||||
<Word>replace</Word>
|
||||
<Word>rrotate</Word>
|
||||
<Word>rshift</Word>
|
||||
|
||||
<!-- Coroutine functions -->
|
||||
<Word>create</Word>
|
||||
<Word>resume</Word>
|
||||
<Word>running</Word>
|
||||
<Word>status</Word>
|
||||
<Word>wrap</Word>
|
||||
<Word>yield</Word>
|
||||
<Word>isyieldable</Word>
|
||||
|
||||
<!-- Debug functions -->
|
||||
<Word>getuservalue</Word>
|
||||
<Word>gethook</Word>
|
||||
<Word>getinfo</Word>
|
||||
<Word>getlocal</Word>
|
||||
<Word>getregistry</Word>
|
||||
<Word>getupvalue</Word>
|
||||
<Word>upvaluejoin</Word>
|
||||
<Word>upvalueid</Word>
|
||||
<Word>setuservalue</Word>
|
||||
<Word>sethook</Word>
|
||||
<Word>setlocal</Word>
|
||||
<Word>setupvalue</Word>
|
||||
<Word>traceback</Word>
|
||||
|
||||
<!-- IO functions -->
|
||||
<Word>close</Word>
|
||||
<Word>flush</Word>
|
||||
<Word>input</Word>
|
||||
<Word>lines</Word>
|
||||
<Word>open</Word>
|
||||
<Word>output</Word>
|
||||
<Word>popen</Word>
|
||||
<Word>read</Word>
|
||||
<Word>tmpfile</Word>
|
||||
<Word>seek</Word>
|
||||
<Word>setvbuf</Word>
|
||||
<Word>write</Word>
|
||||
|
||||
<!-- String functions -->
|
||||
<Word>byte</Word>
|
||||
<Word>char</Word>
|
||||
<Word>dump</Word>
|
||||
<Word>find</Word>
|
||||
<Word>format</Word>
|
||||
<Word>gmatch</Word>
|
||||
<Word>gsub</Word>
|
||||
<Word>len</Word>
|
||||
<Word>lower</Word>
|
||||
<Word>match</Word>
|
||||
<Word>rep</Word>
|
||||
<Word>reverse</Word>
|
||||
<Word>sub</Word>
|
||||
<Word>upper</Word>
|
||||
<Word>pack</Word>
|
||||
<Word>packsize</Word>
|
||||
<Word>unpack</Word>
|
||||
<Word>concat</Word>
|
||||
<Word>maxn</Word>
|
||||
<Word>insert</Word>
|
||||
<Word>move</Word>
|
||||
<Word>offset</Word>
|
||||
<Word>codepoint</Word>
|
||||
<Word>codes</Word>
|
||||
<Word>charpattern</Word>
|
||||
|
||||
<!-- OS / Time functions -->
|
||||
<Word>clock</Word>
|
||||
<Word>date</Word>
|
||||
<Word>difftime</Word>
|
||||
<Word>execute</Word>
|
||||
<Word>exit</Word>
|
||||
<Word>getenv</Word>
|
||||
<Word>remove</Word>
|
||||
<Word>rename</Word>
|
||||
<Word>setlocale</Word>
|
||||
<Word>time</Word>
|
||||
<Word>loadlib</Word>
|
||||
<Word>searchpath</Word>
|
||||
<Word>seeall</Word>
|
||||
<Word>preload</Word>
|
||||
<Word>cpath</Word>
|
||||
<Word>path</Word>
|
||||
<Word>searchers</Word>
|
||||
<Word>loaded</Word>
|
||||
|
||||
<!-- Math functions / constants -->
|
||||
<Word>abs</Word>
|
||||
<Word>acos</Word>
|
||||
<Word>asin</Word>
|
||||
|
|
@ -195,36 +109,140 @@
|
|||
<Word>exp</Word>
|
||||
<Word>floor</Word>
|
||||
<Word>fmod</Word>
|
||||
<Word>ult</Word>
|
||||
<Word>frexp</Word>
|
||||
<Word>huge</Word>
|
||||
<Word>ldexp</Word>
|
||||
<Word>log</Word>
|
||||
<Word>log10</Word>
|
||||
<Word>max</Word>
|
||||
<Word>maxinteger</Word>
|
||||
<Word>min</Word>
|
||||
<Word>mininteger</Word>
|
||||
<Word>modf</Word>
|
||||
<Word>pi</Word>
|
||||
<Word>pow</Word>
|
||||
<Word>rad</Word>
|
||||
<Word>random</Word>
|
||||
<Word>randomseed</Word>
|
||||
<Word>sin</Word>
|
||||
<Word>sinh</Word>
|
||||
<Word>sqrt</Word>
|
||||
<Word>tan</Word>
|
||||
<Word>sinh</Word>
|
||||
<Word>tanh</Word>
|
||||
<Word>pow</Word>
|
||||
<Word>frexp</Word>
|
||||
<Word>ldexp</Word>
|
||||
<Word>huge</Word>
|
||||
<Word>maxinteger</Word>
|
||||
<Word>mininteger</Word>
|
||||
<Word>tointeger</Word>
|
||||
<Word>ult</Word>
|
||||
<Word>byte</Word>
|
||||
<Word>char</Word>
|
||||
<Word>dump</Word>
|
||||
<Word>find</Word>
|
||||
<Word>format</Word>
|
||||
<Word>gmatch</Word>
|
||||
<Word>gsub</Word>
|
||||
<Word>len</Word>
|
||||
<Word>lower</Word>
|
||||
<Word>match</Word>
|
||||
<Word>pack</Word>
|
||||
<Word>packsize</Word>
|
||||
<Word>rep</Word>
|
||||
<Word>reverse</Word>
|
||||
<Word>sub</Word>
|
||||
<Word>upper</Word>
|
||||
<Word>concat</Word>
|
||||
<Word>insert</Word>
|
||||
<Word>maxn</Word>
|
||||
<Word>move</Word>
|
||||
<Word>remove</Word>
|
||||
<Word>sort</Word>
|
||||
<Word>close</Word>
|
||||
<Word>flush</Word>
|
||||
<Word>input</Word>
|
||||
<Word>lines</Word>
|
||||
<Word>open</Word>
|
||||
<Word>output</Word>
|
||||
<Word>popen</Word>
|
||||
<Word>read</Word>
|
||||
<Word>seek</Word>
|
||||
<Word>setvbuf</Word>
|
||||
<Word>tmpfile</Word>
|
||||
<Word>write</Word>
|
||||
<Word>clock</Word>
|
||||
<Word>date</Word>
|
||||
<Word>difftime</Word>
|
||||
<Word>execute</Word>
|
||||
<Word>exit</Word>
|
||||
<Word>getenv</Word>
|
||||
<Word>rename</Word>
|
||||
<Word>setlocale</Word>
|
||||
<Word>time</Word>
|
||||
<Word>create</Word>
|
||||
<Word>isyieldable</Word>
|
||||
<Word>resume</Word>
|
||||
<Word>running</Word>
|
||||
<Word>status</Word>
|
||||
<Word>wrap</Word>
|
||||
<Word>yield</Word>
|
||||
<Word>arshift</Word>
|
||||
<Word>band</Word>
|
||||
<Word>bnot</Word>
|
||||
<Word>bor</Word>
|
||||
<Word>btest</Word>
|
||||
<Word>bxor</Word>
|
||||
<Word>extract</Word>
|
||||
<Word>lrotate</Word>
|
||||
<Word>lshift</Word>
|
||||
<Word>replace</Word>
|
||||
<Word>rrotate</Word>
|
||||
<Word>rshift</Word>
|
||||
<Word>charpattern</Word>
|
||||
<Word>codepoint</Word>
|
||||
<Word>codes</Word>
|
||||
<Word>offset</Word>
|
||||
<Word>gethook</Word>
|
||||
<Word>getinfo</Word>
|
||||
<Word>getlocal</Word>
|
||||
<Word>getregistry</Word>
|
||||
<Word>getupvalue</Word>
|
||||
<Word>getuservalue</Word>
|
||||
<Word>sethook</Word>
|
||||
<Word>setlocal</Word>
|
||||
<Word>setupvalue</Word>
|
||||
<Word>setuservalue</Word>
|
||||
<Word>traceback</Word>
|
||||
<Word>upvalueid</Word>
|
||||
<Word>upvaluejoin</Word>
|
||||
<Word>cpath</Word>
|
||||
<Word>loaded</Word>
|
||||
<Word>loadlib</Word>
|
||||
<Word>path</Word>
|
||||
<Word>preload</Word>
|
||||
<Word>searchers</Word>
|
||||
<Word>searchpath</Word>
|
||||
<Word>seeall</Word>
|
||||
</Keywords>
|
||||
|
||||
<Rule color="Punctuation">(\|)|(<<)|(>>)|(\/\/)|(==)|(~=)|(<=)|(>=)|(<)|(>)|(=)|(\()|(\))|(\{)|(\})|(\[)|(\])|(::)|(:)|(;)|(,)|(\.\.\.)|(\.\.)|(\.)|[+\-*%\^#&~]</Rule>
|
||||
|
||||
<Rule color="ObjectName">(?<=function\s)[A-Za-z0-9_]+(?=\.)</Rule>
|
||||
|
||||
<Rule color="Function">(?<=\.)[A-Za-z0-9_]+(?=\()</Rule>
|
||||
<Rule color="Function">(?<=function\s)[A-Za-z0-9_]+(?=\s*\()</Rule> <!-- Standalone function name -->
|
||||
<Rule color="Metamethod">__[A-Za-z_][A-Za-z0-9_]*__</Rule>
|
||||
|
||||
<Rule color="Constant">\b[A-Z_][A-Z0-9_]*\b</Rule>
|
||||
<Rule color="GotoLabel">(?<=::)[A-Za-z_][A-Za-z0-9_]*(?=::)</Rule>
|
||||
|
||||
<Rule color="Discard">(?<![A-Za-z0-9_])_(?![A-Za-z0-9_])</Rule>
|
||||
|
||||
<Rule color="ObjectName">(?<=function\s)[A-Za-z_][A-Za-z0-9_]*(?=\.)</Rule>
|
||||
<Rule color="ObjectName">(?<=function\s)[A-Za-z_][A-Za-z0-9_]*(?=:)</Rule>
|
||||
|
||||
<Rule color="Function">(?<=function\s)[A-Za-z_][A-Za-z0-9_]*(?=\s*\()</Rule>
|
||||
|
||||
<Rule color="ObjectName">[A-Za-z_][A-Za-z0-9_]*(?=\.)</Rule>
|
||||
<Rule color="ObjectName">[A-Za-z_][A-Za-z0-9_]*(?=:)</Rule>
|
||||
|
||||
<Rule color="Function">(?<=:)[A-Za-z_][A-Za-z0-9_]*(?=\s*\()</Rule>
|
||||
<Rule color="Function">(?<=\.)[A-Za-z_][A-Za-z0-9_]*(?=\s*\()</Rule>
|
||||
<Rule color="Function">\b[A-Za-z_][A-Za-z0-9_]*(?=\s*\()</Rule>
|
||||
|
||||
<Rule color="Property">(?<=\.)[A-Za-z_][A-Za-z0-9_]*</Rule>
|
||||
|
||||
<Rule color="Constant">\b[A-Z][A-Z0-9]*_[A-Z0-9_]*\b</Rule>
|
||||
<Rule color="Constant">\b[A-Z]{2}[A-Z0-9_]*\b</Rule>
|
||||
</RuleSet>
|
||||
</SyntaxDefinition>
|
||||
|
|
|
|||
|
|
@ -300,7 +300,7 @@ namespace FModel.Settings
|
|||
}
|
||||
}
|
||||
|
||||
private EUnluacFlags _unluacFlags;
|
||||
private EUnluacFlags _unluacFlags = EUnluacFlags.Decompile;
|
||||
public EUnluacFlags UnluacFlags
|
||||
{
|
||||
get => _unluacFlags;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ public class VManifest
|
|||
Header = new VHeader(Ar);
|
||||
var compressedBuffer = Ar.ReadBytes((int) Header.CompressedSize);
|
||||
var uncompressedBuffer = new byte[(int)Header.UncompressedSize];
|
||||
ZlibHelper.Decompress(compressedBuffer, 0, compressedBuffer.Length, uncompressedBuffer, 0, uncompressedBuffer.Length);
|
||||
Compression.Decompress(compressedBuffer, 0, compressedBuffer.Length, uncompressedBuffer, 0, uncompressedBuffer.Length, CompressionMethod.Zlib, Ar);
|
||||
|
||||
var manifestAr = new FByteArchive("UncompressedValorantManifest", uncompressedBuffer);
|
||||
Chunks = manifestAr.ReadArray<VChunk>((int) Header.ChunkCount);
|
||||
|
|
|
|||
|
|
@ -265,15 +265,8 @@ public class ApplicationViewModel : ViewModel
|
|||
{
|
||||
var zipDir = Path.GetDirectoryName(vgmZipFilePath)!;
|
||||
await using var zipFs = File.OpenRead(vgmZipFilePath);
|
||||
using var zip = new ZipArchive(zipFs, ZipArchiveMode.Read);
|
||||
|
||||
foreach (var entry in zip.Entries)
|
||||
{
|
||||
var entryPath = Path.Combine(zipDir, entry.FullName);
|
||||
await using var entryFs = File.Create(entryPath);
|
||||
await using var entryStream = entry.Open();
|
||||
await entryStream.CopyToAsync(entryFs);
|
||||
}
|
||||
await using var zip = await ZipArchive.CreateAsync(zipFs, ZipArchiveMode.Read, true, null);
|
||||
await zip.ExtractToDirectoryAsync(zipDir, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -305,9 +298,7 @@ public class ApplicationViewModel : ViewModel
|
|||
oodlePath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", OodleHelper.OODLE_NAME_CURRENT);
|
||||
}
|
||||
|
||||
OodleHelper.Initialize(oodlePath);
|
||||
if (OodleHelper.Instance is null)
|
||||
FLogger.Append(ELog.Error, () => FLogger.Text("Failed to download Oodle", Constants.WHITE, true));
|
||||
await OodleHelper.InitializeAsync(oodlePath);
|
||||
}
|
||||
|
||||
public static async Task InitZlib()
|
||||
|
|
@ -319,12 +310,12 @@ public class ApplicationViewModel : ViewModel
|
|||
{
|
||||
if (!await ZlibHelper.DownloadDllAsync(zlibPath))
|
||||
{
|
||||
FLogger.Append(ELog.Error, () => FLogger.Text("Failed to download Zlib-ng", Constants.WHITE, true));
|
||||
zlibFileInfo.Refresh();
|
||||
if (!zlibFileInfo.Exists) return;
|
||||
}
|
||||
}
|
||||
|
||||
ZlibHelper.Initialize(zlibPath);
|
||||
await ZlibHelper.InitializeAsync(zlibPath);
|
||||
}
|
||||
|
||||
public static async Task InitDetex()
|
||||
|
|
|
|||
|
|
@ -570,139 +570,126 @@ public class AudioPlayerViewModel : ViewModel, ISource, IDisposable
|
|||
{
|
||||
if (SelectedAudioFile?.Data == null)
|
||||
return false;
|
||||
if (SelectedAudioFile.Extension == "wav")
|
||||
return true;
|
||||
|
||||
switch (SelectedAudioFile.Extension)
|
||||
{
|
||||
case "binka":
|
||||
case "adpcm":
|
||||
case "xvag":
|
||||
case "opus":
|
||||
case "wem":
|
||||
case "at9":
|
||||
case "raw":
|
||||
{
|
||||
if (TryConvert(out var wavFilePath))
|
||||
{
|
||||
var newAudio = new AudioFile(SelectedAudioFile.Id, new FileInfo(wavFilePath));
|
||||
Replace(newAudio);
|
||||
return true;
|
||||
}
|
||||
if (!TryConvert(SelectedAudioFile.FilePath, SelectedAudioFile.Data, SelectedAudioFile.Extension, out var convertedFilePath, true))
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
case "adx":
|
||||
case "hca":
|
||||
return TryConvertCriware();
|
||||
case "rada":
|
||||
{
|
||||
if (TryDecode(SelectedAudioFile.Extension, out var rawFilePath))
|
||||
{
|
||||
var newAudio = new AudioFile(SelectedAudioFile.Id, new FileInfo(rawFilePath));
|
||||
Replace(newAudio);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
var newAudio = new AudioFile(SelectedAudioFile.Id, new FileInfo(convertedFilePath));
|
||||
Replace(newAudio);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool TryConvertCriware()
|
||||
public static bool TryConvert(string inputFilePath, byte[] inputFileData, string extension, out string wavFilePath, bool updateUi = false)
|
||||
{
|
||||
wavFilePath = string.Empty;
|
||||
|
||||
switch (extension.ToLowerInvariant())
|
||||
{
|
||||
case "hca":
|
||||
case "adx":
|
||||
return TryConvertCriware(inputFilePath, inputFileData, extension, out wavFilePath);
|
||||
case "rada":
|
||||
return TryConvertRada(inputFilePath, inputFileData, extension, out wavFilePath, updateUi);
|
||||
default:
|
||||
{
|
||||
var vgmStreamPath = TryGetVgmstreamPath();
|
||||
if (string.IsNullOrEmpty(vgmStreamPath))
|
||||
return false;
|
||||
|
||||
var success = TryConvertToWav(inputFilePath, inputFileData, vgmStreamPath, true, out wavFilePath);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Log.Error("Failed to convert {InputFilePath} to .wav format", Path.GetFileName(inputFilePath));
|
||||
|
||||
if (updateUi)
|
||||
{
|
||||
FLogger.Append(ELog.Error, () =>
|
||||
{
|
||||
FLogger.Text("Failed to convert audio to .wav format. See: ", Constants.WHITE);
|
||||
FLogger.Link("→ link ←", Constants.AUDIO_ISSUE_LINK, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static bool TryConvertCriware(string inputFilePath, byte[] inputFileData, string extension, out string wavFilePath)
|
||||
{
|
||||
wavFilePath = string.Empty;
|
||||
|
||||
try
|
||||
{
|
||||
byte[] wavData = SelectedAudioFile.Extension switch
|
||||
byte[] wavData = extension switch
|
||||
{
|
||||
"hca" => HcaWaveStream.ConvertHcaToWav(
|
||||
SelectedAudioFile.Data,
|
||||
UserSettings.Default.CurrentDir.CriwareDecryptionKey),
|
||||
"adx" => AdxDecoder.ConvertAdxToWav(
|
||||
SelectedAudioFile.Data,
|
||||
UserSettings.Default.CurrentDir.CriwareDecryptionKey),
|
||||
"hca" => HcaWaveStream.ConvertHcaToWav(inputFileData, UserSettings.Default.CurrentDir.CriwareDecryptionKey),
|
||||
"adx" => AdxDecoder.ConvertAdxToWav(inputFileData, UserSettings.Default.CurrentDir.CriwareDecryptionKey),
|
||||
_ => throw new NotSupportedException()
|
||||
};
|
||||
|
||||
if (wavData.Length is 0)
|
||||
// Fallback for ADX
|
||||
if (wavData.Length == 0)
|
||||
{
|
||||
if (TryConvert(out var wavFilePathFallback))
|
||||
{
|
||||
var newAudioFallback = new AudioFile(SelectedAudioFile.Id, new FileInfo(wavFilePathFallback));
|
||||
Replace(newAudioFallback);
|
||||
return true;
|
||||
}
|
||||
var vgmStreamPath = TryGetVgmstreamPath();
|
||||
if (string.IsNullOrEmpty(vgmStreamPath))
|
||||
return false;
|
||||
|
||||
return TryConvertToWav(inputFilePath, inputFileData, vgmStreamPath, true, out wavFilePath);
|
||||
}
|
||||
|
||||
string wavFilePath = Path.Combine(
|
||||
UserSettings.Default.AudioDirectory,
|
||||
SelectedAudioFile.FilePath.TrimStart('/'));
|
||||
wavFilePath = Path.ChangeExtension(wavFilePath, ".wav");
|
||||
wavFilePath = Path.ChangeExtension(inputFilePath, ".wav");
|
||||
|
||||
var directory = Path.GetDirectoryName(wavFilePath);
|
||||
if (!string.IsNullOrEmpty(directory))
|
||||
Directory.CreateDirectory(directory);
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(wavFilePath)!);
|
||||
File.WriteAllBytes(wavFilePath, wavData);
|
||||
|
||||
var newAudio = new AudioFile(SelectedAudioFile.Id, new FileInfo(wavFilePath));
|
||||
Replace(newAudio);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (CriwareDecryptionException ex)
|
||||
{
|
||||
FLogger.Append(ELog.Error, () => FLogger.Text($"Encrypted {SelectedAudioFile.Extension.ToUpper()}: {ex.Message}", Constants.WHITE, true));
|
||||
Log.Error($"Encrypted {SelectedAudioFile.Extension.ToUpper()}: {ex.Message}");
|
||||
FLogger.Append(ELog.Error, () => FLogger.Text($"Encrypted {extension.ToUpper()}: {ex.Message}", Constants.WHITE, true));
|
||||
Log.Error($"Encrypted {extension.ToUpper()}: {ex.Message}");
|
||||
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
FLogger.Append(ELog.Error, () => FLogger.Text($"Failed to convert {SelectedAudioFile.Extension.ToUpper()}: {ex.Message}", Constants.WHITE, true));
|
||||
Log.Error($"Failed to convert {SelectedAudioFile.Extension.ToUpper()}: {ex.Message}");
|
||||
FLogger.Append(ELog.Error, () => FLogger.Text($"Failed to convert {extension.ToUpper()}: {ex.Message}", Constants.WHITE, true));
|
||||
Log.Error($"Failed to convert {extension.ToUpper()}: {ex.Message}");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool TryConvert(out string wavFilePath) => TryConvert(SelectedAudioFile.FilePath, SelectedAudioFile.Data, out wavFilePath, true);
|
||||
public static bool TryConvert(string inputFilePath, byte[] inputFileData, out string wavFilePath, bool updateUi = false)
|
||||
{
|
||||
wavFilePath = string.Empty;
|
||||
var vgmStreamPath = TryGetVgmstreamPath();
|
||||
if (string.IsNullOrEmpty(vgmStreamPath))
|
||||
return false;
|
||||
|
||||
var success = TryConvertToWav(inputFilePath, inputFileData, vgmStreamPath, true, out wavFilePath);
|
||||
|
||||
if (!success)
|
||||
{
|
||||
Log.Error("Failed to convert {InputFilePath} to .wav format", Path.GetFileName(inputFilePath));
|
||||
if (updateUi)
|
||||
{
|
||||
FLogger.Append(ELog.Error, () =>
|
||||
{
|
||||
FLogger.Text("Failed to convert audio to .wav format. See: ", Constants.WHITE);
|
||||
FLogger.Link("→ link ←", Constants.AUDIO_ISSUE_LINK, true);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
private bool TryDecode(string extension, out string rawFilePath)
|
||||
private static bool TryConvertRada(string inputFilePath, byte[] inputFileData, string extension, out string rawFilePath, bool updateUi = false)
|
||||
{
|
||||
rawFilePath = string.Empty;
|
||||
var decoderPath = Path.Combine(UserSettings.Default.OutputDirectory, ".data", $"{extension}dec.exe");
|
||||
if (!File.Exists(decoderPath))
|
||||
{
|
||||
Log.Error("Failed to convert {FilePath}, rada decoder is missing", SelectedAudioFile.FilePath);
|
||||
FLogger.Append(ELog.Error, () =>
|
||||
Log.Error("Failed to convert {FilePath}, {Extension} decoder is missing", inputFilePath, extension);
|
||||
|
||||
if (updateUi)
|
||||
{
|
||||
FLogger.Text("Failed to convert audio because rada decoder is missing. See: ", Constants.WHITE);
|
||||
FLogger.Link("→ link ←", Constants.RADA_ISSUE_LINK, true);
|
||||
});
|
||||
FLogger.Append(ELog.Error, () =>
|
||||
{
|
||||
FLogger.Text($"Failed to convert audio because {extension} decoder is missing. See: ", Constants.WHITE);
|
||||
FLogger.Link("→ link ←", Constants.RADA_ISSUE_LINK, true);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return TryConvertToWav(SelectedAudioFile.FilePath, SelectedAudioFile.Data, decoderPath, false, out rawFilePath);
|
||||
return TryConvertToWav(inputFilePath, inputFileData, decoderPath, false, out rawFilePath);
|
||||
}
|
||||
|
||||
private static bool TryConvertToWav(string inputFilePath, byte[] inputFileData, string converterPath, bool usevgmstream, out string wavFilePath)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ using CUE4Parse.GameTypes.Borderlands4.Wwise;
|
|||
using CUE4Parse.GameTypes.DFHO.Assets.Objects;
|
||||
using CUE4Parse.GameTypes.HonorOfKings.FileProvider;
|
||||
using CUE4Parse.GameTypes.KRD.Assets.Exports;
|
||||
using CUE4Parse.GameTypes.LegoBatman.Assets;
|
||||
using CUE4Parse.GameTypes.RocoKingdomWorld.Assets.Objects;
|
||||
using CUE4Parse.GameTypes.SMG.UE4.Assets.Exports.Wwise;
|
||||
using CUE4Parse.GameTypes.SquareEnix.UE4.Assets.Exports;
|
||||
|
|
@ -65,7 +66,6 @@ using CUE4Parse_Conversion;
|
|||
using CUE4Parse_Conversion.Sounds;
|
||||
using EpicManifestParser;
|
||||
using EpicManifestParser.UE;
|
||||
using EpicManifestParser.ZlibngDotNetDecompressor;
|
||||
using FModel.Creator;
|
||||
using FModel.Extensions;
|
||||
using FModel.Framework;
|
||||
|
|
@ -94,6 +94,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
private readonly Regex _fnLiveRegex = new(@"^FortniteGame[/\\]Content[/\\]Paks[/\\]",
|
||||
RegexOptions.Compiled | RegexOptions.Singleline | RegexOptions.IgnoreCase | RegexOptions.CultureInvariant);
|
||||
|
||||
private static readonly HttpClient _chunkClient = ManifestParseOptions.CreateDefaultClient();
|
||||
|
||||
private bool _modelIsOverwritingMaterial;
|
||||
public bool ModelIsOverwritingMaterial
|
||||
{
|
||||
|
|
@ -224,9 +226,9 @@ public class CUE4ParseViewModel : ViewModel
|
|||
{
|
||||
Provider.OnDemandOptions = new IoStoreOnDemandOptions
|
||||
{
|
||||
ChunkHostUri = new Uri("https://download.epicgames.com/", UriKind.Absolute),
|
||||
ChunkHostUri = new Uri("https://egdownload.fastly-edge.com/", UriKind.Absolute),
|
||||
ChunkCacheDirectory = Directory.CreateDirectory(Path.Combine(UserSettings.Default.OutputDirectory, ".data")),
|
||||
Timeout = TimeSpan.FromSeconds(30)
|
||||
DownloaderClient = _chunkClient
|
||||
};
|
||||
|
||||
switch (Provider)
|
||||
|
|
@ -247,9 +249,9 @@ public class CUE4ParseViewModel : ViewModel
|
|||
{
|
||||
ChunkCacheDirectory = cacheDir,
|
||||
ManifestCacheDirectory = cacheDir,
|
||||
ChunkBaseUrl = "http://download.epicgames.com/Builds/Fortnite/CloudDir/",
|
||||
Decompressor = ManifestZlibngDotNetDecompressor.Decompress,
|
||||
DecompressorState = ZlibHelper.Instance,
|
||||
ChunkBaseUrl = "https://egdownload.fastly-edge.com/Builds/Fortnite/CloudDir/",
|
||||
Decompressor = Compression.Decompressor,
|
||||
Client = _chunkClient,
|
||||
CacheChunksAsIs = false
|
||||
};
|
||||
|
||||
|
|
@ -260,7 +262,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
{
|
||||
(manifest, _) = manifestInfo.DownloadAndParseAsync(manifestOptions,
|
||||
cancellationToken: cancellationToken,
|
||||
elementManifestPredicate: static x => x.Uri.Host == "download.epicgames.com"
|
||||
elementDownloadPredicate: static x => x.Uri.Host is "egdownload.fastly-edge.com" or "epicgames-download1.akamaized.net" or "download.epicgames.com"
|
||||
).GetAwaiter().GetResult();
|
||||
}
|
||||
catch (HttpRequestException ex)
|
||||
|
|
@ -400,6 +402,16 @@ public class CUE4ParseViewModel : ViewModel
|
|||
});
|
||||
}
|
||||
|
||||
private ITypeMappingsProvider SelectMappingsProvider(string path)
|
||||
{
|
||||
if (path.EndsWith(".jmap.gz", StringComparison.OrdinalIgnoreCase) || path.EndsWith(".jmap", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
return new JmapTypeMappingsProvider(path);
|
||||
}
|
||||
|
||||
return new FileUsmapTypeMappingsProvider(path);
|
||||
}
|
||||
|
||||
public Task InitMappings(bool force = false)
|
||||
{
|
||||
if (!UserSettings.IsEndpointValid(EEndpointType.Mapping, out var endpoint))
|
||||
|
|
@ -413,7 +425,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
var l = ELog.Information;
|
||||
if (endpoint.Overwrite && File.Exists(endpoint.FilePath))
|
||||
{
|
||||
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(endpoint.FilePath);
|
||||
Provider.MappingsContainer = SelectMappingsProvider(endpoint.FilePath);
|
||||
}
|
||||
else if (endpoint.IsValid)
|
||||
{
|
||||
|
|
@ -439,7 +451,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
_apiEndpointView.DownloadFile(mapping.Url, mappingPath);
|
||||
}
|
||||
|
||||
Provider.MappingsContainer = new FileUsmapTypeMappingsProvider(mappingPath);
|
||||
Provider.MappingsContainer = SelectMappingsProvider(mappingPath);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -722,6 +734,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case "archive":
|
||||
case "dnearchive": // Banishers: Ghosts of New Eden
|
||||
case "gitignore":
|
||||
case "gitattributes":
|
||||
case "LICENSE":
|
||||
case "playstats": // Dispatch
|
||||
case "template":
|
||||
|
|
@ -780,6 +793,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
case "bl":
|
||||
case "bm":
|
||||
case "br":
|
||||
case "sql":
|
||||
case "cs":
|
||||
{
|
||||
var data = Provider.SaveAsset(entry);
|
||||
using var stream = new MemoryStream(data) { Position = 0 };
|
||||
|
|
@ -789,6 +804,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
|
||||
break;
|
||||
}
|
||||
case "ebd" when Provider.Versions.Game is EGame.GAME_ArcRaiders:
|
||||
case "json":
|
||||
{
|
||||
var data = Provider.SaveAsset(entry);
|
||||
|
|
@ -1018,9 +1034,25 @@ public class CUE4ParseViewModel : ViewModel
|
|||
var nonPath = Provider.Files.Keys.FirstOrDefault(k => k.EndsWith(nonFileName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
// I will only get one localization file because they did not translate any languages, lol
|
||||
var locPathKey = entry.Path.Replace("/BinData/", "/BinLocalize/en_US/").Replace("/BinDataCompressed/", "/BinLocalize/en_US/");
|
||||
var locPathKey = entry.Path.Replace("/BinData/", "/BinLocalize/zh_Hans/").Replace("/BinDataCompressed/", "/BinLocalize/zh_Hans/");
|
||||
var locFileFound = Provider.Files.TryGetValue(locPathKey, out var locEntry);
|
||||
|
||||
if (entry.Path is "NRC/Content/ScriptC/Data/Audio/dataconfig_audio.bytes")
|
||||
{
|
||||
var descFound = Provider.Files.TryGetValue("NRC/Content/ScriptC/Data/Audio/dataconfig_audiodesc.bytes", out var descEntry);
|
||||
var typeDescFound = Provider.Files.TryGetValue("NRC/Content/ScriptC/Data/Audio/typeDesc.bytes", out var typeDescEntry);
|
||||
|
||||
if (!descFound || !typeDescFound)
|
||||
{
|
||||
Log.Warning("Could not find associated dataconfig_audiodesc.bytes or typeDesc.bytes, cannot parse audio config");
|
||||
return;
|
||||
}
|
||||
|
||||
var data = new FRocoAudioConfig(entry.CreateReader(), descEntry.CreateReader(), typeDescEntry.CreateReader());
|
||||
TabControl.SelectedTab.SetDocumentText(JsonConvert.SerializeObject(data, Formatting.Indented), saveProperties, updateUi);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!string.IsNullOrEmpty(nonPath) && Provider.Files.TryGetValue(nonPath, out var nonEntry))
|
||||
{
|
||||
string json = Encoding.UTF8.GetString(nonEntry.Read());
|
||||
|
|
@ -1309,8 +1341,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
_ => []
|
||||
};
|
||||
|
||||
var directory = Path.GetDirectoryName(atomObject.Owner?.Name) ?? "/Criware/";
|
||||
directory = Path.GetDirectoryName(atomObject.Owner.Provider.FixPath(directory));
|
||||
var directory = Path.GetDirectoryName(Provider.FixPath(atomObject.Owner?.Name ?? "/Criware/"));
|
||||
foreach (var sound in extractedSounds)
|
||||
{
|
||||
SaveAndPlaySound(cancellationToken, Path.Combine(directory, sound.Name).Replace("\\", "/"), sound.Extension, sound.Data, saveAudio, updateUi);
|
||||
|
|
@ -1321,8 +1352,8 @@ public class CUE4ParseViewModel : ViewModel
|
|||
{
|
||||
var data = squareEnixObject switch
|
||||
{
|
||||
USQEXSEADSoundBank sqexSoundBank => sqexSoundBank.SQEXSoundBankData?.Data ?? [],
|
||||
USQEXSEADSound sqexSound => sqexSound.SQEXSoundData?.Data ?? [],
|
||||
USQEXSEADSoundBank sqexSoundBank => sqexSoundBank.SQEXSoundBankData?.ReadDataOnce() ?? [],
|
||||
USQEXSEADSound sqexSound => sqexSound.SQEXSoundData?.ReadDataOnce() ?? [],
|
||||
_ => [],
|
||||
};
|
||||
var sabPath = Path.Combine(TabControl.SelectedTab.Entry.PathWithoutExtension.Replace('\\', '/').SubstringBeforeLast('/'), squareEnixObject.Name);
|
||||
|
|
@ -1427,6 +1458,27 @@ public class CUE4ParseViewModel : ViewModel
|
|||
|
||||
return false;
|
||||
}
|
||||
// LEGO® Batman™: Legacy of the Dark Knight
|
||||
case UWubAudioEvent when (isNone || saveAudio) && pointer.Object.Value is UWubAudioEvent wubAudioEvent:
|
||||
{
|
||||
var extractedSounds = WwiseProvider.ExtractWubAudioEventSounds(wubAudioEvent);
|
||||
foreach (var sound in extractedSounds)
|
||||
{
|
||||
SaveAndPlaySound(cancellationToken, sound.OutputPath, sound.Extension, sound.Data?.GetData() ?? [], saveAudio, updateUi);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case UWubDialogueEvent when (isNone || saveAudio) && pointer.Object.Value is UWubDialogueEvent wubDialogueEvent:
|
||||
{
|
||||
var files = wubDialogueEvent.Wems
|
||||
.SelectMany(wem => Provider.Files.Values.Where(file => file.Path.EndsWith(wem.Text + ".wem", StringComparison.OrdinalIgnoreCase)))
|
||||
.ToList();
|
||||
foreach (var entry in files)
|
||||
{
|
||||
SaveAndPlaySound(cancellationToken, entry.PathWithoutExtension, entry.Extension, entry.Read(), saveAudio, updateUi);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
case UWorld when isNone && UserSettings.Default.PreviewWorlds:
|
||||
case UBlueprintGeneratedClass when isNone && UserSettings.Default.PreviewWorlds && TabControl.SelectedTab.ParentExportType switch
|
||||
{
|
||||
|
|
@ -1583,7 +1635,7 @@ public class CUE4ParseViewModel : ViewModel
|
|||
bool conversionSuccess = true;
|
||||
if (UserSettings.Default.ConvertAudioOnBulkExport && extLower is not "wav")
|
||||
{
|
||||
if (AudioPlayerViewModel.TryConvert(savedAudioPath, data, out string wavFilePath))
|
||||
if (AudioPlayerViewModel.TryConvert(savedAudioPath, data, extLower, out string wavFilePath))
|
||||
savedAudioPath = wavFilePath;
|
||||
else
|
||||
{
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ using CUE4Parse.FileProvider.Objects;
|
|||
using CUE4Parse.GameTypes.Borderlands3.Assets.Exports;
|
||||
using CUE4Parse.GameTypes.Borderlands4.Assets.Exports;
|
||||
using CUE4Parse.GameTypes.FN.Assets.Exports.DataAssets;
|
||||
using CUE4Parse.GameTypes.LegoBatman.Assets;
|
||||
using CUE4Parse.GameTypes.SMG.UE4.Assets.Exports.Wwise;
|
||||
using CUE4Parse.GameTypes.SMG.UE4.Assets.Objects;
|
||||
using CUE4Parse.GameTypes.SquareEnix.UE4.Assets.Exports;
|
||||
|
|
@ -263,6 +264,7 @@ public class GameFileViewModel(GameFile asset) : ViewModel
|
|||
UBorderlandsDialogObject when GameVersion is EGame.GAME_Borderlands3 => (EAssetCategory.Borderlands, EBulkType.None), // Borderlands 3;
|
||||
UGbxGraphAsset or UDialogScriptData or UDialogPerformanceData when GameVersion is EGame.GAME_Borderlands4 or EGame.GAME_Borderlands3 => (EAssetCategory.Borderlands, EBulkType.Audio), // Borderlands 4; Borderlands 3;
|
||||
UFaceFXAnimSet when GameVersion is EGame.GAME_Borderlands4 => (EAssetCategory.Borderlands, EBulkType.Audio), // Borderlands 4;
|
||||
UWubAudioEvent or UWubDialogueEvent when GameVersion is EGame.GAME_LEGOBatmanLegacyoftheDarkKnight => (EAssetCategory.LegoBatman, EBulkType.Audio), // Lego Batman: Legacy of the Dark Knight;
|
||||
|
||||
_ => (EAssetCategory.All, EBulkType.None),
|
||||
};
|
||||
|
|
@ -350,11 +352,15 @@ public class GameFileViewModel(GameFile asset) : ViewModel
|
|||
case "pem":
|
||||
case "xml":
|
||||
case "gitignore":
|
||||
case "gitattributes":
|
||||
case "html":
|
||||
case "css":
|
||||
case "js":
|
||||
case "data":
|
||||
case "csv":
|
||||
case "sql":
|
||||
case "py":
|
||||
case "cs":
|
||||
AssetCategory = EAssetCategory.Data;
|
||||
break;
|
||||
case "stinfo":
|
||||
|
|
|
|||
|
|
@ -48,10 +48,14 @@
|
|||
<SolidColorBrush x:Key="GitBrush" Color="Coral" />
|
||||
<SolidColorBrush x:Key="CsvBrush" Color="ForestGreen" />
|
||||
<SolidColorBrush x:Key="AIBrush" Color="LightGray" />
|
||||
<SolidColorBrush x:Key="SQLBrush" Color="#00758f" />
|
||||
<SolidColorBrush x:Key="PythonBrush" Color="#3d77a8" />
|
||||
<SolidColorBrush x:Key="CSharpBrush" Color="#9e559a" />
|
||||
|
||||
<!-- For specific games -->
|
||||
<SolidColorBrush x:Key="BorderlandsBrush" Color="Yellow"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="AionBrush" Color="DeepSkyBlue"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="RocoKingdomWorldBrush" Color="#fecf4d"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="DeltaForceBrush" Color="LightGreen"></SolidColorBrush>
|
||||
<SolidColorBrush x:Key="BatmanBrush" Color="Gold"></SolidColorBrush>
|
||||
</ResourceDictionary>
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public partial class DropOverlay : UserControl
|
|||
}
|
||||
else if (_dragStatus is DragStatus.File)
|
||||
{
|
||||
TitleText.Text = "Drop .usmap to import";
|
||||
TitleText.Text = "Drop usmap/jmap to import";
|
||||
DescriptionText.Text = "Mapping file will be applied immediately";
|
||||
}
|
||||
}
|
||||
|
|
@ -125,7 +125,6 @@ public partial class DropOverlay : UserControl
|
|||
if (!_applicationView.Status.IsReady || !e.Data.GetDataPresent(DataFormats.FileDrop) || e.Data.GetData(DataFormats.FileDrop) is not string[] files)
|
||||
return;
|
||||
|
||||
|
||||
bool directorySelectorIsVisible = _applicationView.Status.Kind is EStatusKind.Configuring;
|
||||
if (!directorySelectorIsVisible && (Helper.IsWindowOpen<DictionaryEditor>() || Helper.IsWindowOpen<EndpointEditor>()))
|
||||
{
|
||||
|
|
@ -145,7 +144,9 @@ public partial class DropOverlay : UserControl
|
|||
_dragStatus = DragStatus.Folder;
|
||||
return;
|
||||
}
|
||||
else if (File.Exists(path) && Path.GetExtension(path).Equals(".usmap", StringComparison.OrdinalIgnoreCase))
|
||||
else if (File.Exists(path) && path.EndsWith(".usmap", StringComparison.OrdinalIgnoreCase) ||
|
||||
path.EndsWith(".jmap", StringComparison.OrdinalIgnoreCase) ||
|
||||
path.EndsWith(".jmap.gz", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
_path = path;
|
||||
_dragStatus = DragStatus.File;
|
||||
|
|
|
|||
|
|
@ -80,10 +80,14 @@ public class FileToGeometryConverter : IMultiValueConverter
|
|||
"bin" => ("DataTableIcon", "BinaryBrush"),
|
||||
"xml" => ("XmlIcon", "JsonXmlBrush"),
|
||||
"gitignore" => ("GitIcon", "GitBrush"),
|
||||
"gitattributes" => ("GitIcon", "GitBrush"),
|
||||
"html" => ("HtmlIcon", "HtmlBrush"),
|
||||
"js" => ("JavaScriptIcon", "JavaScriptBrush"),
|
||||
"css" => ("CssIcon", "CssBrush"),
|
||||
"csv" => ("CsvIcon", "CsvBrush"),
|
||||
"sql" => ("SQLIcon", "SQLBrush"),
|
||||
"py" => ("PythonIcon", "PythonBrush"),
|
||||
"cs" => ("CSharpIcon", "CSharpBrush"),
|
||||
_ => ("DataTableIcon", "NeutralBrush")
|
||||
},
|
||||
|
||||
|
|
@ -93,6 +97,7 @@ public class FileToGeometryConverter : IMultiValueConverter
|
|||
EAssetCategory.Aion2 => ("AionIcon", "AionBrush"),
|
||||
EAssetCategory.RocoKingdomWorld => ("RocoKingdomWorldIcon", "RocoKingdomWorldBrush"),
|
||||
EAssetCategory.DeltaForce => ("DeltaForceIcon", "DeltaForceBrush"),
|
||||
EAssetCategory.LegoBatman => ("BatmanIcon", "BatmanBrush"),
|
||||
|
||||
_ => ("AssetIcon", "NeutralBrush")
|
||||
};
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -61,13 +61,13 @@ public class Morph : IDisposable
|
|||
}
|
||||
}
|
||||
|
||||
public Morph(float[] vertices, Dictionary<uint, int> dict, UMorphTarget morphTarget)
|
||||
public Morph(float[] vertices, Dictionary<uint, int> dict, UMorphTarget morphTarget, int index = 0)
|
||||
{
|
||||
Name = morphTarget.Name;
|
||||
Vertices = new float[vertices.Length];
|
||||
Array.Copy(vertices, Vertices, vertices.Length);
|
||||
|
||||
foreach (var vert in morphTarget.MorphLODModels[0].Vertices)
|
||||
foreach (var vert in morphTarget.MorphLODModels[index].Vertices)
|
||||
{
|
||||
var count = 0;
|
||||
if (dict.TryGetValue(vert.SourceIdx, out var baseIndex))
|
||||
|
|
|
|||
|
|
@ -100,11 +100,11 @@ public class SkeletalModel : UModel
|
|||
|
||||
foreach (var morph in export.MorphTargets)
|
||||
{
|
||||
if (!morph.TryLoad(out UMorphTarget morphTarget) || morphTarget.MorphLODModels.Length < 1 ||
|
||||
morphTarget.MorphLODModels[0].Vertices.Length < 1)
|
||||
if (!morph.TryLoad(out UMorphTarget morphTarget) || morphTarget.MorphLODModels.Length <= skeletalMesh.LODs[LodLevel].LODIndex ||
|
||||
morphTarget.MorphLODModels[skeletalMesh.LODs[LodLevel].LODIndex].Vertices.Length < 1)
|
||||
continue;
|
||||
|
||||
Morphs.Add(new Morph(cachedVertices, vertexLookup, morphTarget));
|
||||
Morphs.Add(new Morph(cachedVertices, vertexLookup, morphTarget, skeletalMesh.LODs[LodLevel].LODIndex));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -247,7 +247,7 @@ public class Options
|
|||
{
|
||||
return _game switch
|
||||
{
|
||||
"LIESOFP" or "CODEVEIN2" or "HIGHONLIFE2" => true,
|
||||
"LIESOFP" or "CODEVEIN2" or "HIGHONLIFE2" or "MORTALSHELL2" => true,
|
||||
_ => false,
|
||||
};
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user