This commit is contained in:
Razmoth
2022-11-03 19:32:12 +04:00
parent c257f5669c
commit 3be27949f8
34 changed files with 390 additions and 421 deletions

View File

@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<TargetFramework>net6.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>

View File

@@ -12,8 +12,8 @@ namespace AssetStudio
{
public static class AIVersionManager
{
private const string BaseUrl = "https://raw.githubusercontent.com/radioegor146/gi-asset-indexes/master/";
private const string CommitsUrl = "https://api.github.com/repos/radioegor146/gi-asset-indexes/commits?path=";
private const string BaseUrl = "https://raw.githubusercontent.com/14eyes/gi-asset-indexes/master/";
private const string CommitsUrl = "https://api.github.com/repos/14eyes/gi-asset-indexes/commits?path=";
private const string VersionIndexName = "version-index.json";
private const string VersionIndexKey = "index";
@@ -220,7 +220,7 @@ namespace AssetStudio
return commit;
}
internal class VersionIndex
internal record VersionIndex
{
public string MappedPath = "";
public string RawPath = "";

View File

@@ -1,27 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<TargetFramework>net6.0</TargetFramework>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Razmoth 2022; Copyright © Perfare 2018-2022</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
<PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<PackageReference Include="System.Memory" Version="4.5.4" />
<PackageReference Include="System.IO.Compression" Version="4.0.0" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.1.11" />
<Reference Include="System.Net.Http" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="K4os.Compression.LZ4" Version="1.2.16" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2-beta2" />
</ItemGroup>
</Project>

View File

@@ -77,7 +77,7 @@ namespace AssetStudio
m_Header.unityVersion = "5.x.x";
m_Header.unityRevision = "2017.4.18f1";
}
else if (reader.Game.Name == "SR")
else if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
var readHeader = m_Header.signature != "ENCR";
@@ -120,7 +120,7 @@ namespace AssetStudio
case "UnityFS":
case "ENCR":
ReadHeader(reader);
if (reader.Game.Name == "ZZZ")
if (reader.Game.Name == "ZZZ_CB1")
{
reader.AlignStream(0x10);
}
@@ -282,7 +282,7 @@ namespace AssetStudio
private void ReadBlocksInfoAndDirectory(EndianBinaryReader reader)
{
byte[] blocksInfoBytes;
if (m_Header.version >= 7 && reader.Game.Name != "SR")
if (m_Header.version >= 7 && reader.Game.Name != "SR_CB2" && reader.Game.Name != "SR_CB3")
{
reader.AlignStream(16);
}
@@ -341,7 +341,7 @@ namespace AssetStudio
}
using (var blocksInfoReader = new EndianBinaryReader(blocksInfoUncompresseddStream))
{
if (reader.Game.Name != "SR" || m_Header.signature != "ENCR")
if ((reader.Game.Name != "SR_CB2" && reader.Game.Name != "SR_CB3") || m_Header.signature != "ENCR")
{
var uncompressedDataHash = blocksInfoReader.ReadBytes(16);
}

View File

@@ -12,7 +12,7 @@ namespace AssetStudio
public static void BuildMap(List<string> files, Game game)
{
Logger.Info(string.Format("Building {0}", game.MapName));
Logger.Info($"Building {game.Name}Map");
try
{
int collisions = 0;
@@ -50,7 +50,7 @@ namespace AssetStudio
}
CABMap = CABMap.OrderBy(pair => pair.Key).ToDictionary(pair => pair.Key, pair => pair.Value);
var outputFile = new FileInfo($"Maps/{game.MapName}.bin");
var outputFile = new FileInfo($"Maps/{game.Name}Map.bin");
if (!outputFile.Directory.Exists)
outputFile.Directory.Create();
@@ -71,20 +71,20 @@ namespace AssetStudio
}
}
}
Logger.Info($"{game.MapName} build successfully, {collisions} collisions found !!");
Logger.Info($"{game.Name}Map build successfully, {collisions} collisions found !!");
}
catch (Exception e)
{
Logger.Warning($"{game.MapName} was not build, {e.Message}");
Logger.Warning($"{game.Name}Map was not build, {e.Message}");
}
}
public static void LoadMap(Game game)
{
Logger.Info(string.Format("Loading {0}", game.MapName));
Logger.Info($"Loading {game.Name}Map");
try
{
CABMap.Clear();
using (var binaryFile = File.OpenRead($"Maps/{game.MapName}.bin"))
using (var binaryFile = File.OpenRead($"Maps/{game.Name}Map.bin"))
using (var reader = new BinaryReader(binaryFile))
{
var count = reader.ReadInt32();
@@ -103,11 +103,11 @@ namespace AssetStudio
CABMap.Add(cab, new Entry(path, offset, dependencies));
}
}
Logger.Info(string.Format("Loaded {0} !!", game.MapName));
Logger.Info($"Loaded {game.Name}Map !!");
}
catch (Exception e)
{
Logger.Warning($"{game.Name} was not loaded, {e.Message}");
Logger.Warning($"{game.Name}Map was not loaded, {e.Message}");
}
}

View File

@@ -189,7 +189,7 @@ namespace AssetStudio
public uint m_ConstCurveCount;
public ACLClip(ObjectReader reader)
{
if (reader.Game.Name == "SR")
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_ClipDataUint = reader.ReadUInt32Array();
}
@@ -201,7 +201,7 @@ namespace AssetStudio
m_CurveCount = reader.ReadUInt32();
if (reader.Game.Name == "SR")
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_ConstCurveCount = reader.ReadUInt32();
}
@@ -970,7 +970,7 @@ namespace AssetStudio
var version = reader.version;
m_StreamedClip = new StreamedClip(reader);
m_DenseClip = new DenseClip(reader);
if (reader.Game.Name == "SR")
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_ACLClip = new ACLClip(reader);
}
@@ -978,7 +978,7 @@ namespace AssetStudio
{
m_ConstantClip = new ConstantClip(reader);
}
if (reader.Game.Name != "SR" && reader.Game.Name != "TOT")
if (reader.Game.Name != "SR_CB2" && reader.Game.Name != "SR_CB3" && reader.Game.Name != "TOT")
{
m_ACLClip = new ACLClip(reader);
}
@@ -1440,7 +1440,7 @@ namespace AssetStudio
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
if (reader.Game.Name == "SR")
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_AclClipData = reader.ReadUInt8Array();
var aclBindingsCount = reader.ReadInt32();

View File

@@ -15,7 +15,7 @@ namespace AssetStudio
{
m_Avatar = new PPtr<Avatar>(reader);
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
if (reader.Game.Name == "GI" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
var m_FBIKAvatar = new PPtr<Object>(reader); //FBIKAvatar placeholder
}

View File

@@ -50,7 +50,7 @@ namespace AssetStudio
Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
}
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
MainAsset = new AssetInfo(reader);
RuntimeComaptability = reader.ReadUInt32();
@@ -63,13 +63,13 @@ namespace AssetStudio
{
Dependencies[k] = reader.ReadAlignedString();
}
if (reader.Game.Name == "CB1" || reader.Game.Name == "CB2")
if (reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2")
{
IsStreamedScenessetBundle = reader.ReadBoolean();
reader.AlignStream();
PathFlags = reader.ReadInt32();
}
else if (reader.Game.Name == "CB3")
else if (reader.Game.Name == "GI_CB3")
{
IsStreamedScenessetBundle = reader.ReadBoolean();
reader.AlignStream();

View File

@@ -569,7 +569,7 @@ namespace AssetStudio
var m_KeepIndices = reader.ReadBoolean();
}
reader.AlignStream();
if (reader.Game.Name == "GI" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
var m_PackSkinDataToUV2UV3 = reader.ReadBoolean();
reader.AlignStream();
@@ -694,7 +694,7 @@ namespace AssetStudio
}
}
if (reader.Game.Name == "ZZZ")
if (reader.Game.Name == "ZZZ_CB1")
{
var m_CloseMeshDynamicCompression = reader.ReadBoolean();
reader.AlignStream();
@@ -704,7 +704,7 @@ namespace AssetStudio
var m_CompressLevelTexCoordinates = reader.ReadInt32();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3"
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3"
|| version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_MeshMetrics = new float[2];
@@ -712,13 +712,13 @@ namespace AssetStudio
m_MeshMetrics[1] = reader.ReadSingle();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
var m_MetricsDirty = reader.ReadBoolean();
reader.AlignStream();
var m_CloseMeshDynamicCompression = reader.ReadBoolean();
reader.AlignStream();
if (reader.Game.Name != "CB1")
if (reader.Game.Name != "GI_CB1")
{
var m_IsStreamingMesh = reader.ReadBoolean();
reader.AlignStream();

View File

@@ -52,7 +52,7 @@ namespace AssetStudio
{
var m_AllowHalfResolution = reader.ReadByte();
}
else if (reader.Game.Name == "CB3")
else if (reader.Game.Name == "GI_CB3")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
@@ -88,7 +88,7 @@ namespace AssetStudio
{
var m_StaticShadowCaster = reader.ReadByte();
}
if (reader.Game.Name == "CB2")
if (reader.Game.Name == "GI_CB2")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
@@ -97,7 +97,7 @@ namespace AssetStudio
var m_IsRainOccluder = reader.ReadByte();
var m_IsDynamic = reader.ReadByte();
}
if (reader.Game.Name == "CB1")
if (reader.Game.Name == "GI_CB1")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
@@ -115,7 +115,7 @@ namespace AssetStudio
{
var m_RayTraceProcedural = reader.ReadByte();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB3")
{
var m_MeshShowQuality = reader.ReadByte();
}
@@ -142,7 +142,7 @@ namespace AssetStudio
var m_LightmapIndex = reader.ReadInt16();
var m_LightmapIndexDynamic = reader.ReadInt16();
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
if (m_LightmapIndex != -1 || m_LightmapIndexDynamic != -1)
throw new Exception("Not Supported !! skipping....");
@@ -159,7 +159,7 @@ namespace AssetStudio
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
var m_ViewDistanceRatio = reader.ReadSingle();
var m_ShaderLODDistanceRatio = reader.ReadSingle();
@@ -188,7 +188,7 @@ namespace AssetStudio
var m_StaticBatchRoot = new PPtr<Transform>(reader);
}
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
var m_MatLayers = reader.ReadInt32();
}
@@ -226,11 +226,16 @@ namespace AssetStudio
//SInt16 m_SortingLayer 5.6 and up
var m_SortingOrder = reader.ReadInt16();
reader.AlignStream();
if (reader.Game.Name == "GI" || reader.Game.Name == "CB1" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3" || reader.Game.Name == "BH3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3" || reader.Game.Name == "BH3")
{
var m_UseHighestMip = reader.ReadBoolean();
reader.AlignStream();
}
if (reader.Game.Name == "SR_CB3")
{
var _RenderFlag = reader.ReadUInt32();
reader.AlignStream();
}
}
}

View File

@@ -985,7 +985,7 @@ namespace AssetStudio
decompressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
}
compressedBlob = reader.ReadUInt8Array();
if (reader.Game.Name == "GI" || reader.Game.Name == "CB2" || reader.Game.Name == "CB3")
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
if (BitConverter.ToInt32(compressedBlob, 0) == -1)
compressedBlob = reader.ReadUInt8Array();

View File

@@ -27,17 +27,17 @@ namespace AssetStudio
var giFile = new GIFile(reader);
bundles = giFile.Bundles;
break;
case "CB1":
var cb1 = GameManager.GetGame("CB1");
if (ext != cb1.Extension)
case "GI_CB1":
var gi_cb1 = GameManager.GetGame("GI_CB1");
if (ext != gi_cb1.Extension)
goto default;
var cb1File = new CB1File(reader);
bundles = cb1File.Bundles;
var gi_cb1File = new CB1File(reader);
bundles = gi_cb1File.Bundles;
break;
case "CB2":
var cb2 = GameManager.GetGame("CB2");
if (ext != cb2.Extension)
case "GI_CB2":
var gi_cb2 = GameManager.GetGame("GI_CB2");
if (ext != gi_cb2.Extension)
goto default;
Blk.ExpansionKey = Crypto.CBXExpansionKey;
@@ -45,12 +45,12 @@ namespace AssetStudio
Blk.ConstKey = Crypto.CBXConstKey;
Blk.ConstVal = Crypto.CBXConstVal;
var cb2File = new CBXFile(reader);
bundles = cb2File.Bundles;
var gi_cb2File = new CBXFile(reader);
bundles = gi_cb2File.Bundles;
break;
case "CB3":
var cb3 = GameManager.GetGame("CB3");
if (ext != cb3.Extension)
case "GI_CB3":
var gi_cb3 = GameManager.GetGame("GI_CB3");
if (ext != gi_cb3.Extension)
goto default;
Blk.ExpansionKey = Crypto.CBXExpansionKey;
@@ -58,8 +58,8 @@ namespace AssetStudio
Blk.ConstKey = Crypto.CBXConstKey;
Blk.ConstVal = Crypto.CBXConstVal;
var cb3File = new CBXFile(reader);
bundles = cb3File.Bundles;
var gi_cb3File = new CBXFile(reader);
bundles = gi_cb3File.Bundles;
break;
case "BH3":
var bh3 = GameManager.GetGame("BH3");
@@ -75,8 +75,8 @@ namespace AssetStudio
var wmvFile = new WMVFile(reader);
bundles = wmvFile.Bundles;
break;
case "ZZZ":
var zzz = GameManager.GetGame("ZZZ");
case "ZZZ_CB1":
var zzz = GameManager.GetGame("ZZZ_CB1");
if (ext != zzz.Extension)
goto default;
@@ -89,9 +89,9 @@ namespace AssetStudio
var zzzFile = new BundleFile(reader);
bundles.Add(0, zzzFile.FileList);
break;
case "SR":
var sr = GameManager.GetGame("SR");
if (ext != sr.Extension)
case "SR_CB2":
var sr_cb2 = GameManager.GetGame("SR_CB2");
if (ext != sr_cb2.Extension)
goto default;
Mr0k.ExpansionKey = Crypto.Mr0kExpansionKey;
@@ -100,8 +100,22 @@ namespace AssetStudio
Mr0k.SBox = null;
Mr0k.BlockKey = null;
var srFile = new BundleFile(reader);
bundles.Add(0, srFile.FileList);
var sr_cb2File = new BundleFile(reader);
bundles.Add(0, sr_cb2File.FileList);
break;
case "SR_CB3":
var sr_cb3 = GameManager.GetGame("SR_CB3");
if (ext != sr_cb3.Extension)
goto default;
Mr0k.ExpansionKey = Crypto.Mr0kExpansionKey;
Mr0k.Key = Crypto.Mr0kKey;
Mr0k.ConstKey = Crypto.Mr0kConstKey;
Mr0k.SBox = null;
Mr0k.BlockKey = null;
var sr_cb3File = new BlocksFile(reader);
bundles = sr_cb3File.Bundles;
break;
case "TOT":
var tot = GameManager.GetGame("TOT");

View File

@@ -0,0 +1,30 @@
using System.Collections.Generic;
namespace AssetStudio
{
public class BlocksFile
{
public Dictionary<long, StreamFile[]> Bundles = new Dictionary<long, StreamFile[]>();
public BlocksFile(FileReader reader)
{
if (reader.BundlePos.Length != 0)
{
foreach (var pos in reader.BundlePos)
{
reader.Position = pos;
var bundle = new BundleFile(reader);
Bundles.Add(pos, bundle.FileList);
}
}
else
{
while (reader.Position != reader.Length)
{
var pos = reader.Position;
var bundle = new BundleFile(reader);
Bundles.Add(pos, bundle.FileList);
}
}
}
}
}

View File

@@ -2,7 +2,6 @@
using System.Linq;
using System.Reflection;
using System.Collections.Generic;
using System.Security.Cryptography;
namespace AssetStudio
{
@@ -11,14 +10,16 @@ namespace AssetStudio
private static Dictionary<int, Game> Games = new Dictionary<int, Game>();
static GameManager()
{
int count = 0;
foreach (Type type in
Assembly.GetAssembly(typeof(Game)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(Game))))
{
var format = (Game)Activator.CreateInstance(type);
Games.Add(count++, format);
}
int index = 0;
Games.Add(index++, new("GI", ".blk", "GI_Data|YS_Data"));
Games.Add(index++, new("GI_CB1", ".asb", "GS_Data"));
Games.Add(index++, new("GI_CB2", ".blk", "G_Data"));
Games.Add(index++, new("GI_CB3", ".blk", "YS_Data"));
Games.Add(index++, new("BH3", ".wmv", "BH3_Data"));
Games.Add(index++, new("ZZZ_CB1", ".bundle", "Win_Data/StreamingAssets/Bundles"));
Games.Add(index++, new("SR_CB2", ".unity3d", "SR_Data"));
Games.Add(index++, new("SR_CB3", ".block", "SR_Data"));
Games.Add(index++, new("TOT", ".blk", "AssetbundlesCache"));
}
public static Game GetGame(int index)
{
@@ -42,106 +43,20 @@ namespace AssetStudio
}
public static Game[] GetGames() => Games.Values.ToArray();
public static string[] GetGameNames() => Games.Values.Select(x => x.Name).ToArray();
public static string SupportedGames() => $"Supported Games:\n{string.Join("\n", Games.Values.Select(x => $"{x.Name} ({x.DisplayName})"))}";
public static string SupportedGames() => $"Supported Games:\n{string.Join("\n", Games.Values.Select(x => x.Name))}";
}
public abstract class Game
public record Game
{
public string Name;
public string DisplayName;
public string Extension;
public string MapName;
public string Path;
public override string ToString() => DisplayName;
}
public class GI : Game
{
public GI()
public Game(string name, string extension, string path)
{
Name = "GI";
DisplayName = "GI";
MapName = "BLKMap";
Extension = ".blk";
Path = "GI_Data|YS_Data";
}
}
public class CB1 : Game
{
public CB1()
{
Name = "CB1";
DisplayName = "GI_CB1";
MapName = "CB1Map";
Extension = ".asb";
Path = "GS_Data";
}
}
public class CB2 : Game
{
public CB2()
{
Name = "CB2";
DisplayName = "GI_CB2";
MapName = "CB2Map";
Extension = ".blk";
Path = "G_Data";
}
}
public class CB3 : Game
{
public CB3()
{
Name = "CB3";
DisplayName = "GI_CB3";
MapName = "CB3Map";
Extension = ".blk";
Path = "YS_Data";
}
}
public class BH3 : Game
{
public BH3()
{
Name = "BH3";
DisplayName = "HI3";
MapName = "WMVMap";
Extension = ".wmv";
Path = "BH3_Data";
}
}
public class ZZZ : Game
{
public ZZZ()
{
Name = "ZZZ";
DisplayName = "ZZZ";
MapName = "ZZZMap";
Extension = ".bundle";
Path = "Win_Data/StreamingAssets/Bundles";
}
}
public class SR : Game
{
public SR()
{
Name = "SR";
DisplayName = "SR";
MapName = "ENCRMap";
Extension = ".unity3d";
Path = "SR_Data";
}
}
public class TOT : Game
{
public TOT()
{
Name = "TOT";
DisplayName = "ToT";
MapName = "TOTMap";
Extension = ".blk";
Path = "AssetbundlesCache";
Name = name;
Extension = extension;
Path = path;
}
public override string ToString() => Name;
}
}

View File

@@ -2,17 +2,17 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>net472;net5.0-windows;net6.0-windows</TargetFrameworks>
<TargetFramework>net6.0-windows</TargetFramework>
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Razmoth 2022</Copyright>
<BaseOutputPath>..\AssetStudioGUI\bin</BaseOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.2-beta2" />
<PackageReference Include="System.CommandLine" Version="2.0.0-beta4.22272.1" />
</ItemGroup>

View File

@@ -6,6 +6,7 @@ using System.CommandLine.Binding;
using System.Text.RegularExpressions;
using static AssetStudioCLI.Studio;
using AssetStudio;
using System.CommandLine.Parsing;
namespace AssetStudioCLI
{
@@ -23,8 +24,9 @@ namespace AssetStudioCLI
var rootCommand = new RootCommand()
{
optionsBinder.Silent,
optionsBinder.Types,
optionsBinder.Filters,
optionsBinder.TypeFilter,
optionsBinder.NameFilter,
optionsBinder.ContainerFilter,
optionsBinder.GameName,
optionsBinder.MapOp,
optionsBinder.MapType,
@@ -74,7 +76,7 @@ namespace AssetStudioCLI
}
}
if (o.AIFile != null && game.Name == "GI" || game.Name == "CB2" || game.Name == "CB3")
if (o.AIFile != null && game.Name == "GI" || game.Name == "GI_CB2" || game.Name == "GI_CB3")
{
ResourceIndex.FromFile(o.AIFile.FullName);
}
@@ -89,7 +91,7 @@ namespace AssetStudioCLI
foreach (var file in files)
{
assetsManager.LoadFiles(file);
BuildAssetData(o.Types, o.Filters, ref i);
BuildAssetData(o.TypeFilter, o.NameFilter, o.ContainerFilter, ref i);
ExportAssets(o.Output.FullName, exportableAssets, o.GroupAssetsType);
exportableAssets.Clear();
assetsManager.Clear();
@@ -105,7 +107,7 @@ namespace AssetStudioCLI
{
throw new Exception("Unable to build AssetMap with input_path as a file !!");
}
var assets = BuildAssetMap(files.ToList(), o.Types, o.Filters);
var assets = BuildAssetMap(files.ToList(), o.TypeFilter, o.NameFilter, o.ContainerFilter);
if (!o.Output.Exists)
{
o.Output.Create();
@@ -131,8 +133,9 @@ namespace AssetStudioCLI
public class Options
{
public bool Silent { get; set; }
public ClassIDType[] Types { get; set; }
public Regex[] Filters { get; set; }
public ClassIDType[] TypeFilter { get; set; }
public Regex[] NameFilter { get; set; }
public Regex[] ContainerFilter { get; set; }
public string GameName { get; set; }
public MapOpType MapOp { get; set; }
public ExportListType MapType { get; set; }
@@ -149,8 +152,9 @@ namespace AssetStudioCLI
public class OptionsBinder : BinderBase<Options>
{
public readonly Option<bool> Silent;
public readonly Option<ClassIDType[]> Types;
public readonly Option<Regex[]> Filters;
public readonly Option<ClassIDType[]> TypeFilter;
public readonly Option<Regex[]> NameFilter;
public readonly Option<Regex[]> ContainerFilter;
public readonly Option<string> GameName;
public readonly Option<MapOpType> MapOp;
public readonly Option<ExportListType> MapType;
@@ -166,8 +170,9 @@ namespace AssetStudioCLI
public OptionsBinder()
{
Silent = new Option<bool>("--silent", "Hide log messages.");
Types = new Option<ClassIDType[]>("--type", "Specify unity class type(s)") { AllowMultipleArgumentsPerToken = true, ArgumentHelpName = "Texture2D|Sprite|etc.." };
Filters = new Option<Regex[]>("--filter", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify regex filter(s).") { AllowMultipleArgumentsPerToken = true };
TypeFilter = new Option<ClassIDType[]>("--types", "Specify unity class type(s)") { AllowMultipleArgumentsPerToken = true, ArgumentHelpName = "Texture2D|Sprite|etc.." };
NameFilter = new Option<Regex[]>("--names", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify name regex filter(s).") { AllowMultipleArgumentsPerToken = true };
ContainerFilter = new Option<Regex[]>("--containers", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify container regex filter(s).") { AllowMultipleArgumentsPerToken = true };
GameName = new Option<string>("--game", $"Specify Game.") { IsRequired = true };
MapOp = new Option<MapOpType>("--map_op", "Specify which map to build.");
MapType = new Option<ExportListType>("--map_type", "AssetMap output type.");
@@ -193,29 +198,9 @@ namespace AssetStudioCLI
}
}, false, "XOR key to decrypt MiHoYoBinData.");
Filters.AddValidator(result =>
{
var values = result.Tokens.Select(x => x.Value).ToArray();
foreach(var val in values)
{
if (string.IsNullOrWhiteSpace(val))
{
result.ErrorMessage = "Empty string.";
return;
}
try
{
Regex.Match("", val, RegexOptions.IgnoreCase);
}
catch (ArgumentException e)
{
result.ErrorMessage = "Invalid Regex.\n" + e.Message;
return;
}
}
});
TypeFilter.AddValidator(FilterValidator);
NameFilter.AddValidator(FilterValidator);
ContainerFilter.AddValidator(FilterValidator);
XorByte.AddValidator(result =>
{
var value = result.Tokens.Single().Value;
@@ -244,12 +229,38 @@ namespace AssetStudioCLI
MapType.SetDefaultValue(ExportListType.XML);
}
public void FilterValidator(OptionResult result)
{
{
var values = result.Tokens.Select(x => x.Value).ToArray();
foreach (var val in values)
{
if (string.IsNullOrWhiteSpace(val))
{
result.ErrorMessage = "Empty string.";
return;
}
try
{
Regex.Match("", val, RegexOptions.IgnoreCase);
}
catch (ArgumentException e)
{
result.ErrorMessage = "Invalid Regex.\n" + e.Message;
return;
}
}
}
}
protected override Options GetBoundValue(BindingContext bindingContext) =>
new Options
{
Silent = bindingContext.ParseResult.GetValueForOption(Silent),
Types = bindingContext.ParseResult.GetValueForOption(Types),
Filters = bindingContext.ParseResult.GetValueForOption(Filters),
TypeFilter = bindingContext.ParseResult.GetValueForOption(TypeFilter),
NameFilter = bindingContext.ParseResult.GetValueForOption(NameFilter),
ContainerFilter = bindingContext.ParseResult.GetValueForOption(ContainerFilter),
GameName = bindingContext.ParseResult.GetValueForOption(GameName),
MapOp = bindingContext.ParseResult.GetValueForOption(MapOp),
MapType = bindingContext.ParseResult.GetValueForOption(MapType),

View File

@@ -143,7 +143,7 @@ namespace AssetStudioCLI
return extractedCount;
}
public static List<AssetEntry> BuildAssetMap(List<string> files, ClassIDType[] formats, Regex[] filters)
public static List<AssetEntry> BuildAssetMap(List<string> files, ClassIDType[] typeFilters, Regex[] nameFilters, Regex[] containerFilters)
{
var assets = new List<AssetEntry>();
for (int i = 0; i < files.Count; i++)
@@ -195,7 +195,7 @@ namespace AssetStudioCLI
var preloadEnd = preloadIndex + preloadSize;
for (int k = preloadIndex; k < preloadEnd; k++)
{
if (Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3")
if (Game.Name == "GI" || Game.Name == "GI_CB2" || Game.Name == "GI_CB3")
{
if (long.TryParse(m_Container.Key, out var containerValue))
{
@@ -258,8 +258,8 @@ namespace AssetStudioCLI
objectAssetItemDic.Add(obj, asset);
assetsFile.AddObject(obj);
}
var isMatchRegex = filters.Length == 0 || filters.Any(x => x.IsMatch(asset.Name) || asset.Type == ClassIDType.Animator);
var isFilteredType = formats.Length == 0 || formats.Contains(asset.Type) || asset.Type == ClassIDType.Animator;
var isMatchRegex = nameFilters.Length == 0 || nameFilters.Any(x => x.IsMatch(asset.Name) || asset.Type == ClassIDType.Animator);
var isFilteredType = typeFilters.Length == 0 || typeFilters.Contains(asset.Type) || asset.Type == ClassIDType.Animator;
if (isMatchRegex && isFilteredType && exportable)
{
assets.Add(asset);
@@ -267,7 +267,7 @@ namespace AssetStudioCLI
}
foreach (var pair in animators)
{
if (pair.Item1.TryGet(out var gameObject) && gameObject is GameObject && (filters.Length == 0 || filters.Any(x => x.IsMatch(gameObject.m_Name))) && (formats.Length == 0 || formats.Contains(pair.Item2.Type)))
if (pair.Item1.TryGet(out var gameObject) && gameObject is GameObject && (nameFilters.Length == 0 || nameFilters.Any(x => x.IsMatch(gameObject.m_Name))) && (typeFilters.Length == 0 || typeFilters.Contains(pair.Item2.Type)))
{
pair.Item2.Name = gameObject.m_Name;
}
@@ -280,7 +280,15 @@ namespace AssetStudioCLI
{
if (pptr.TryGet(out var obj))
{
objectAssetItemDic[obj].Container = container;
var item = objectAssetItemDic[obj];
if (containerFilters.Length == 0 || containerFilters.Any(x => x.IsMatch(container)))
{
item.Container = container;
}
else
{
assets.Remove(item);
}
}
}
assetsManager.assetsFileList.Clear();
@@ -296,7 +304,7 @@ namespace AssetStudioCLI
return assets;
}
public static void BuildAssetData(ClassIDType[] formats, Regex[] filters, ref int i)
public static void BuildAssetData(ClassIDType[] typeFilters, Regex[] nameFilters, Regex[] containerFilters, ref int i)
{
string productName = null;
var objectCount = assetsManager.assetsFileList.Sum(x => x.Objects.Count);
@@ -373,7 +381,7 @@ namespace AssetStudioCLI
var preloadEnd = preloadIndex + preloadSize;
for (int k = preloadIndex; k < preloadEnd; k++)
{
if (Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3")
if (Game.Name == "GI" || Game.Name == "GI_CB2" || Game.Name == "GI_CB3")
{
if (long.TryParse(m_Container.Key, out var containerValue))
{
@@ -440,8 +448,8 @@ namespace AssetStudioCLI
{
assetItem.Text = assetItem.TypeString + assetItem.UniqueID;
}
var isMatchRegex = filters.Length == 0 || filters.Any(x => x.IsMatch(assetItem.Text));
var isFilteredType = formats.Length == 0 || formats.Contains(assetItem.Asset.type);
var isMatchRegex = nameFilters.Length == 0 || nameFilters.Any(x => x.IsMatch(assetItem.Text));
var isFilteredType = typeFilters.Length == 0 || typeFilters.Contains(assetItem.Asset.type);
if (isMatchRegex && isFilteredType && exportable)
{
exportableAssets.Add(assetItem);
@@ -453,7 +461,15 @@ namespace AssetStudioCLI
{
if (pptr.TryGet(out var obj))
{
objectAssetItemDic[obj].Container = container;
var item = objectAssetItemDic[obj];
if (containerFilters.Length == 0 || containerFilters.Any(x => x.IsMatch(container)))
{
item.Container = container;
}
else
{
exportableAssets.Remove(item);
}
}
}
containers.Clear();
@@ -474,7 +490,7 @@ namespace AssetStudioCLI
case AssetGroupOption.ByContainer: //container path
if (!string.IsNullOrEmpty(asset.Container))
{
exportPath = Path.HasExtension(asset.Container) ? Path.Combine(savePath, Path.GetDirectoryName(asset.Container)) : Path.Combine(savePath, asset.Container);
exportPath = Path.HasExtension(asset.Container) ? Path.Combine(savePath, Path.GetFileNameWithoutExtension(asset.Container)) : Path.Combine(savePath, asset.Container);
}
else
{

View File

@@ -101,14 +101,14 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\lib\vs2019\x86\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
@@ -120,7 +120,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
@@ -129,7 +129,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\lib\vs2019\x86\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
@@ -138,14 +138,14 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;wininet.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\lib\vs2019\x64\debug;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<IgnoreSpecificDefaultLibraries>LIBCMT;%(IgnoreSpecificDefaultLibraries)</IgnoreSpecificDefaultLibraries>
</Link>
</ItemDefinitionGroup>
@@ -157,7 +157,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_AS_DLL;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
</ClCompile>
<Link>
@@ -166,7 +166,7 @@
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>libfbxsdk-mt.lib;libxml2-mt.lib;zlib-mt.lib;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.2.1\lib\vs2019\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>C:\Program Files\Autodesk\FBX\FBX SDK\2020.3.2\lib\vs2019\x64\release;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemGroup>

View File

@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<TargetFramework>net6.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Perfare 2018-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>

View File

@@ -2,12 +2,12 @@
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFrameworks>net472;net5.0-windows;net6.0-windows</TargetFrameworks>
<TargetFramework>net6.0-windows</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
<ApplicationIcon>Resources\as.ico</ApplicationIcon>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Razmoth 2022; Copyright © Perfare 2018-2022</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>
@@ -74,22 +74,13 @@
</ContentWithTargetPath>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' != 'net472' ">
<PackageReference Include="OpenTK" Version="4.6.7" />
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.2-beta2" />
<PackageReference Include="OpenTK" Version="5.0.0-pre.8" />
<Reference Include="OpenTK.WinForms">
<HintPath>Libraries\OpenTK.WinForms.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup Condition=" '$(TargetFramework)' == 'net472' ">
<PackageReference Include="OpenTK" Version="3.1.0" />
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="CommandLineParser" Version="2.9.1" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
</ItemGroup>
<Target Name="CopyExtraFiles" AfterTargets="AfterBuild">
<Copy SourceFiles="$(SolutionDir)AssetStudioFBXNative\bin\Win32\$(Configuration)\AssetStudioFBXNative.dll" DestinationFolder="$(TargetDir)x86" ContinueOnError="true" />

View File

@@ -120,7 +120,7 @@
this.FMODpauseButton = new System.Windows.Forms.Button();
this.FMODplayButton = new System.Windows.Forms.Button();
this.fontPreviewBox = new System.Windows.Forms.RichTextBox();
this.glControl1 = new OpenTK.GLControl();
this.glControl = new OpenTK.WinForms.GLControl();
this.textPreviewBox = new System.Windows.Forms.TextBox();
this.classTextBox = new System.Windows.Forms.TextBox();
this.tabPage5 = new System.Windows.Forms.TabPage();
@@ -849,7 +849,7 @@
this.previewPanel.Controls.Add(this.assetInfoLabel);
this.previewPanel.Controls.Add(this.FMODpanel);
this.previewPanel.Controls.Add(this.fontPreviewBox);
this.previewPanel.Controls.Add(this.glControl1);
this.previewPanel.Controls.Add(this.glControl);
this.previewPanel.Controls.Add(this.textPreviewBox);
this.previewPanel.Controls.Add(this.classTextBox);
this.previewPanel.Dock = System.Windows.Forms.DockStyle.Fill;
@@ -1008,21 +1008,24 @@
this.fontPreviewBox.WordWrap = false;
//
// glControl1
//
this.glControl1.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.glControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.glControl1.Location = new System.Drawing.Point(0, 0);
this.glControl1.Name = "glControl1";
this.glControl1.Size = new System.Drawing.Size(768, 607);
this.glControl1.TabIndex = 4;
this.glControl1.Visible = false;
this.glControl1.VSync = false;
this.glControl1.Load += new System.EventHandler(this.glControl1_Load);
this.glControl1.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);
this.glControl1.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseDown);
this.glControl1.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseMove);
this.glControl1.MouseUp += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseUp);
this.glControl1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseWheel);
//
this.glControl.API = OpenTK.Windowing.Common.ContextAPI.OpenGL;
this.glControl.APIVersion = new System.Version(4, 6, 0, 0);
this.glControl.BackColor = System.Drawing.SystemColors.ControlDarkDark;
this.glControl.Dock = System.Windows.Forms.DockStyle.Fill;
this.glControl.Flags = OpenTK.Windowing.Common.ContextFlags.Default;
this.glControl.IsEventDriven = true;
this.glControl.Location = new System.Drawing.Point(0, 0);
this.glControl.Name = "glControl1";
this.glControl.Size = new System.Drawing.Size(768, 607);
this.glControl.TabIndex = 4;
this.glControl.Visible = false;
this.glControl.Load += new System.EventHandler(this.glControl1_Load);
this.glControl.Paint += new System.Windows.Forms.PaintEventHandler(this.glControl1_Paint);
this.glControl.MouseDown += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseDown);
this.glControl.MouseMove += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseMove);
this.glControl.MouseUp += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseUp);
this.glControl.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.glControl1_MouseWheel);
//
// textPreviewBox
//
@@ -1260,7 +1263,7 @@
private System.Windows.Forms.TextBox classTextBox;
private System.Windows.Forms.ToolStripMenuItem exportClassStructuresMenuItem;
private System.Windows.Forms.Label FMODcopyright;
private OpenTK.GLControl glControl1;
private OpenTK.WinForms.GLControl glControl;
private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
private System.Windows.Forms.ToolStripMenuItem showOriginalFileToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exportAnimatorwithselectedAnimationClipMenuItem;

View File

@@ -1,6 +1,6 @@
using AssetStudio;
using Newtonsoft.Json;
using OpenTK;
using OpenTK.Graphics;
using OpenTK.Graphics.OpenGL;
using System;
using System.Collections.Generic;
@@ -20,14 +20,11 @@ using System.Timers;
using System.Windows.Forms;
using static AssetStudioGUI.Studio;
using Font = AssetStudio.Font;
#if NET472
using Vector3 = OpenTK.Vector3;
using Vector4 = OpenTK.Vector4;
#else
using Vector3 = OpenTK.Mathematics.Vector3;
using Vector4 = OpenTK.Mathematics.Vector4;
using Matrix4 = OpenTK.Mathematics.Matrix4;
#endif
using OpenTK.Mathematics;
using SpirV;
namespace AssetStudioGUI
{
@@ -54,14 +51,14 @@ namespace AssetStudioGUI
private bool glControlLoaded;
private int mdx, mdy;
private bool lmdown, rmdown;
private int pgmID, pgmColorID, pgmBlackID;
private ProgramHandle pgmID, pgmColorID, pgmBlackID;
private int attributeVertexPosition;
private int attributeNormalDirection;
private int attributeVertexColor;
private int uniformModelMatrix;
private int uniformViewMatrix;
private int uniformProjMatrix;
private int vao;
private VertexArrayHandle vao;
private Vector3[] vertexData;
private Vector3[] normalData;
private Vector3[] normal2Data;
@@ -137,7 +134,7 @@ namespace AssetStudioGUI
Studio.Game = GameManager.GetGame(Properties.Settings.Default.selectedGame);
specifyGame.SelectedIndex = Properties.Settings.Default.selectedGame;
specifyGame.SelectedIndexChanged += new EventHandler(toolStripComboBox2_SelectedIndexChanged);
Logger.Info($"Target Game is {Studio.Game.DisplayName}");
Logger.Info($"Target Game is {Studio.Game.Name}");
CABManager.LoadMap(Studio.Game);
}
@@ -248,7 +245,7 @@ namespace AssetStudioGUI
}
else
{
Text = $"Studio v{Application.ProductVersion} - {Studio.Game.DisplayName} - {Path.GetFileName(assetsManager.assetsFileList[0].originalPath)} - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}";
Text = $"Studio v{Application.ProductVersion} - {Studio.Game.Name} - {Path.GetFileName(assetsManager.assetsFileList[0].originalPath)} - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}";
}
assetListView.VirtualListSize = visibleAssets.Count;
@@ -317,7 +314,7 @@ namespace AssetStudioGUI
private void AssetStudioForm_KeyDown(object sender, KeyEventArgs e)
{
if (glControl1.Visible)
if (glControl.Visible)
{
if (e.Control)
{
@@ -326,18 +323,18 @@ namespace AssetStudioGUI
case Keys.W:
//Toggle WireFrame
wireFrameMode = (wireFrameMode + 1) % 3;
glControl1.Invalidate();
glControl.Invalidate();
break;
case Keys.S:
//Toggle Shade
shadeMode = (shadeMode + 1) % 2;
glControl1.Invalidate();
glControl.Invalidate();
break;
case Keys.N:
//Normal mode
normalMode = (normalMode + 1) % 2;
CreateVAO();
glControl1.Invalidate();
glControl.Invalidate();
break;
}
}
@@ -701,7 +698,7 @@ namespace AssetStudioGUI
textPreviewBox.Visible = false;
fontPreviewBox.Visible = false;
FMODpanel.Visible = false;
glControl1.Visible = false;
glControl.Visible = false;
StatusStripUpdate("");
FMODreset();
@@ -734,7 +731,7 @@ namespace AssetStudioGUI
textPreviewBox.Visible = false;
fontPreviewBox.Visible = false;
FMODpanel.Visible = false;
glControl1.Visible = false;
glControl.Visible = false;
StatusStripUpdate("");
if (e.IsSelected)
{
@@ -744,10 +741,10 @@ namespace AssetStudioGUI
private void preview_Resize(object sender, EventArgs e)
{
if (glControlLoaded && glControl1.Visible)
if (glControlLoaded && glControl.Visible)
{
ChangeGLSize(glControl1.Size);
glControl1.Invalidate();
ChangeGLSize(glControl.Size);
glControl.Invalidate();
}
}
@@ -1219,7 +1216,7 @@ namespace AssetStudioGUI
}
}
#endregion
glControl1.Visible = true;
glControl.Visible = true;
CreateVAO();
StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) + "\n"
+ "'Mouse Left'=Rotate | 'Mouse Right'=Move | 'Mouse Wheel'=Zoom \n"
@@ -1308,7 +1305,7 @@ namespace AssetStudioGUI
assetInfoLabel.Text = null;
textPreviewBox.Visible = false;
fontPreviewBox.Visible = false;
glControl1.Visible = false;
glControl.Visible = false;
lastSelectedItem = null;
sortColumn = -1;
reverseSort = false;
@@ -1954,11 +1951,11 @@ namespace AssetStudioGUI
#region GLControl
private void InitOpenTK()
{
ChangeGLSize(glControl1.Size);
GL.ClearColor(System.Drawing.Color.CadetBlue);
ChangeGLSize(glControl.Size);
GL.ClearColor(Color4.Dimgray);
pgmID = GL.CreateProgram();
LoadShader("vs", ShaderType.VertexShader, pgmID, out int vsID);
LoadShader("fs", ShaderType.FragmentShader, pgmID, out int fsID);
LoadShader("vs", ShaderType.VertexShader, pgmID, out var vsID);
LoadShader("fs", ShaderType.FragmentShader, pgmID, out var fsID);
GL.LinkProgram(pgmID);
pgmColorID = GL.CreateProgram();
@@ -1979,7 +1976,7 @@ namespace AssetStudioGUI
uniformProjMatrix = GL.GetUniformLocation(pgmID, "projMatrix");
}
private static void LoadShader(string filename, ShaderType type, int program, out int address)
private static void LoadShader(string filename, ShaderType type, ProgramHandle program, out ShaderHandle address)
{
address = GL.CreateShader(type);
var str = (string)Properties.Resources.ResourceManager.GetObject(filename);
@@ -1989,50 +1986,47 @@ namespace AssetStudioGUI
GL.DeleteShader(address);
}
private static void CreateVBO(out int vboAddress, Vector3[] data, int address)
private static void CreateVBO(out BufferHandle vboAddress, Vector3[] data, int address)
{
GL.GenBuffers(1, out vboAddress);
GL.BindBuffer(BufferTarget.ArrayBuffer, vboAddress);
GL.BufferData(BufferTarget.ArrayBuffer,
(IntPtr)(data.Length * Vector3.SizeInBytes),
GL.CreateBuffer(out vboAddress);
GL.BindBuffer(BufferTargetARB.ArrayBuffer, vboAddress);
GL.BufferData(BufferTargetARB.ArrayBuffer,
data,
BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(address, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(address);
BufferUsageARB.StaticDraw);
GL.VertexAttribPointer((uint)address, 3, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray((uint)address);
}
private static void CreateVBO(out int vboAddress, Vector4[] data, int address)
private static void CreateVBO(out BufferHandle vboAddress, Vector4[] data, int address)
{
GL.GenBuffers(1, out vboAddress);
GL.BindBuffer(BufferTarget.ArrayBuffer, vboAddress);
GL.BufferData(BufferTarget.ArrayBuffer,
(IntPtr)(data.Length * Vector4.SizeInBytes),
GL.CreateBuffer(out vboAddress);
GL.BindBuffer(BufferTargetARB.ArrayBuffer, vboAddress);
GL.BufferData(BufferTargetARB.ArrayBuffer,
data,
BufferUsageHint.StaticDraw);
GL.VertexAttribPointer(address, 4, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray(address);
BufferUsageARB.StaticDraw);
GL.VertexAttribPointer((uint)address, 4, VertexAttribPointerType.Float, false, 0, 0);
GL.EnableVertexAttribArray((uint)address);
}
private static void CreateVBO(out int vboAddress, Matrix4 data, int address)
private static void CreateVBO(out BufferHandle vboAddress, Matrix4 data, int address)
{
GL.GenBuffers(1, out vboAddress);
GL.UniformMatrix4(address, false, ref data);
GL.CreateBuffer(out vboAddress);
GL.UniformMatrix4f(address, false, data);
}
private static void CreateEBO(out int address, int[] data)
private static void CreateEBO(out BufferHandle address, int[] data)
{
GL.GenBuffers(1, out address);
GL.BindBuffer(BufferTarget.ElementArrayBuffer, address);
GL.BufferData(BufferTarget.ElementArrayBuffer,
(IntPtr)(data.Length * sizeof(int)),
GL.CreateBuffer(out address);
GL.BindBuffer(BufferTargetARB.ElementArrayBuffer, address);
GL.BufferData(BufferTargetARB.ElementArrayBuffer,
data,
BufferUsageHint.StaticDraw);
BufferUsageARB.StaticDraw);
}
private void CreateVAO()
{
GL.DeleteVertexArray(vao);
GL.GenVertexArrays(1, out vao);
GL.CreateVertexArray(out vao);
GL.BindVertexArray(vao);
CreateVBO(out var vboPositions, vertexData, attributeVertexPosition);
if (normalMode == 0)
@@ -2049,8 +2043,8 @@ namespace AssetStudioGUI
CreateVBO(out var vboViewMatrix, viewMatrixData, uniformViewMatrix);
CreateVBO(out var vboProjMatrix, projMatrixData, uniformProjMatrix);
CreateEBO(out var eboElements, indiceData);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
GL.BindVertexArray(0);
GL.BindBuffer(BufferTargetARB.ArrayBuffer, BufferHandle.Zero);
GL.BindVertexArray(VertexArrayHandle.Zero);
}
private void ChangeGLSize(Size size)
@@ -2077,7 +2071,7 @@ namespace AssetStudioGUI
private void glControl1_Paint(object sender, PaintEventArgs e)
{
glControl1.MakeCurrent();
glControl.MakeCurrent();
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
GL.Enable(EnableCap.DepthTest);
GL.DepthFunc(DepthFunction.Lequal);
@@ -2085,11 +2079,11 @@ namespace AssetStudioGUI
if (wireFrameMode == 0 || wireFrameMode == 2)
{
GL.UseProgram(shadeMode == 0 ? pgmID : pgmColorID);
GL.UniformMatrix4(uniformModelMatrix, false, ref modelMatrixData);
GL.UniformMatrix4(uniformViewMatrix, false, ref viewMatrixData);
GL.UniformMatrix4(uniformProjMatrix, false, ref projMatrixData);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
GL.DrawElements(BeginMode.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0);
GL.UniformMatrix4f(uniformModelMatrix, false, modelMatrixData);
GL.UniformMatrix4f(uniformViewMatrix, false, viewMatrixData);
GL.UniformMatrix4f(uniformProjMatrix, false, projMatrixData);
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Fill);
GL.DrawElements(PrimitiveType.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0);
}
//Wireframe
if (wireFrameMode == 1 || wireFrameMode == 2)
@@ -2097,16 +2091,16 @@ namespace AssetStudioGUI
GL.Enable(EnableCap.PolygonOffsetLine);
GL.PolygonOffset(-1, -1);
GL.UseProgram(pgmBlackID);
GL.UniformMatrix4(uniformModelMatrix, false, ref modelMatrixData);
GL.UniformMatrix4(uniformViewMatrix, false, ref viewMatrixData);
GL.UniformMatrix4(uniformProjMatrix, false, ref projMatrixData);
GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
GL.DrawElements(BeginMode.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0);
GL.UniformMatrix4f(uniformModelMatrix, false, modelMatrixData);
GL.UniformMatrix4f(uniformViewMatrix, false, viewMatrixData);
GL.UniformMatrix4f(uniformProjMatrix, false, projMatrixData);
GL.PolygonMode(TriangleFace.FrontAndBack, PolygonMode.Line);
GL.DrawElements(PrimitiveType.Triangles, indiceData.Length, DrawElementsType.UnsignedInt, 0);
GL.Disable(EnableCap.PolygonOffsetLine);
}
GL.BindVertexArray(0);
GL.BindVertexArray(VertexArrayHandle.Zero);
GL.Flush();
glControl1.SwapBuffers();
glControl.SwapBuffers();
}
private void tabControl2_SelectedIndexChanged(object sender, EventArgs e)
@@ -2212,7 +2206,7 @@ namespace AssetStudioGUI
Properties.Settings.Default.Save();
Studio.Game = GameManager.GetGame(Properties.Settings.Default.selectedGame);
Logger.Info($"Target Game is {Studio.Game.DisplayName}");
Logger.Info($"Target Game is {Studio.Game.Name}");
ResetForm();
assetsManager.SpecifyUnityVersion = specifyUnityVersion.Text;
@@ -2234,10 +2228,10 @@ namespace AssetStudioGUI
private void glControl1_MouseWheel(object sender, MouseEventArgs e)
{
if (glControl1.Visible)
if (glControl.Visible)
{
viewMatrixData *= Matrix4.CreateScale(1 + e.Delta / 1000f);
glControl1.Invalidate();
glControl.Invalidate();
}
}
@@ -2276,7 +2270,7 @@ namespace AssetStudioGUI
dy *= 0.003f;
viewMatrixData *= Matrix4.CreateTranslation(-dx, dy, 0);
}
glControl1.Invalidate();
glControl.Invalidate();
}
}

View File

@@ -209,7 +209,7 @@ namespace AssetStudioGUI
var preloadEnd = preloadIndex + preloadSize;
for (int k = preloadIndex; k < preloadEnd; k++)
{
if (Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3")
if (Game.Name == "GI" || Game.Name == "GI_CB2" || Game.Name == "GI_CB3")
{
if (long.TryParse(m_Container.Key, out var containerValue))
{
@@ -392,7 +392,7 @@ namespace AssetStudioGUI
var preloadEnd = preloadIndex + preloadSize;
for (int k = preloadIndex; k < preloadEnd; k++)
{
if (Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3")
if (Game.Name == "GI" || Game.Name == "GI_CB2" || Game.Name == "GI_CB3")
{
if (long.TryParse(m_Container.Key, out var containerValue))
{
@@ -617,7 +617,7 @@ namespace AssetStudioGUI
case AssetGroupOption.ByContainer: //container path
if (!string.IsNullOrEmpty(asset.Container))
{
exportPath = Game.Name == "GI" || Game.Name == "CB2" || Game.Name == "CB3" ? Path.Combine(savePath, Path.GetDirectoryName(asset.Container)) : Path.Combine(savePath, asset.Container);
exportPath = Path.HasExtension(asset.Container) ? Path.Combine(savePath, Path.GetFileNameWithoutExtension(asset.Container)) : Path.Combine(savePath, asset.Container);
}
else
{

View File

@@ -32,4 +32,33 @@ namespace ACL
#endregion
}
public static class SRACL
{
private const string DLL_NAME = "sracl";
static SRACL()
{
DllLoader.PreloadDll(DLL_NAME);
}
public static void DecompressAll(uint[] data, out float[] values, out float[] times)
{
var pinned = GCHandle.Alloc(data, GCHandleType.Pinned);
var pData = pinned.AddrOfPinnedObject();
DecompressAll(pData, out var pValues, out var numValues, out var pTimes, out var numTimes);
pinned.Free();
values = new float[numValues];
Marshal.Copy(pValues, values, 0, numValues);
times = new float[numTimes];
Marshal.Copy(pTimes, times, 0, numTimes);
}
#region importfunctions
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void DecompressAll(IntPtr data, out IntPtr pValues, out int numValues, out IntPtr pTimes, out int numTimes);
#endregion
}
}

View File

@@ -1,35 +0,0 @@
using System;
using System.Runtime.InteropServices;
using AssetStudio.PInvoke;
namespace ACL
{
public static class SRACL
{
private const string DLL_NAME = "sracl";
static SRACL()
{
DllLoader.PreloadDll(DLL_NAME);
}
public static void DecompressAll(uint[] data, out float[] values, out float[] times)
{
var pinned = GCHandle.Alloc(data, GCHandleType.Pinned);
var pData = pinned.AddrOfPinnedObject();
DecompressAll(pData, out var pValues, out var numValues, out var pTimes, out var numTimes);
pinned.Free();
values = new float[numValues];
Marshal.Copy(pValues, values, 0, numValues);
times = new float[numTimes];
Marshal.Copy(pTimes, times, 0, numTimes);
}
#region importfunctions
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void DecompressAll(IntPtr data, out IntPtr pValues, out int numValues, out IntPtr pTimes, out int numTimes);
#endregion
}
}

View File

@@ -50,14 +50,14 @@ namespace AssetStudio
var lastSampleFrame = streamedFrames.Count > 1 ? streamedFrames[streamedFrames.Count - 2].time : 0.0f;
var lastFrame = Math.Max(lastDenseFrame, lastSampleFrame);
if (m_Clip.m_ACLClip.IsSet && Game.Name != "SR")
if (m_Clip.m_ACLClip.IsSet && Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
{
var lastACLFrame = ProcessACLClip(m_Clip, bindings, tos);
lastFrame = Math.Max(lastFrame, lastACLFrame);
}
ProcessStreams(streamedFrames, bindings, tos, m_Clip.m_DenseClip.m_SampleRate);
ProcessDenses(m_Clip, bindings, tos);
if (m_Clip.m_ACLClip.IsSet && Game.Name == "SR")
if (m_Clip.m_ACLClip.IsSet && (Game.Name == "SR_CB2" || Game.Name == "SR_CB3"))
{
var lastACLFrame = ProcessACLClip(m_Clip, bindings, tos);
lastFrame = Math.Max(lastFrame, lastACLFrame);
@@ -96,7 +96,7 @@ namespace AssetStudio
{
var curve = frame.keyList[curveIndex];
var index = curve.index;
if (animationClip.m_MuscleClip.m_Clip.m_ACLClip.IsSet && Game.Name != "SR")
if (animationClip.m_MuscleClip.m_Clip.m_ACLClip.IsSet && Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
index += (int)animationClip.m_MuscleClip.m_Clip.m_ACLClip.m_CurveCount;
var binding = bindings.FindBinding(index);
@@ -147,7 +147,7 @@ namespace AssetStudio
for (var curveIndex = 0; curveIndex < dense.m_CurveCount;)
{
var index = (int)streamCount + curveIndex;
if (clip.m_ACLClip.IsSet && Game.Name != "SR")
if (clip.m_ACLClip.IsSet && Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
index += (int)clip.m_ACLClip.m_CurveCount;
var binding = bindings.FindBinding(index);
var path = GetCurvePath(tos, binding.path);
@@ -177,7 +177,7 @@ namespace AssetStudio
float[] values;
float[] times;
var acl = clip.m_ACLClip;
if (Game.Name != "SR")
if (Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
{
acl.Process(out values, out times);
}
@@ -195,7 +195,7 @@ namespace AssetStudio
for (int curveIndex = 0; curveIndex < acl.m_CurveCount;)
{
var index = curveIndex;
if (Game.Name == "SR")
if (Game.Name == "SR_CB2" || Game.Name == "SR_CB3")
index += (int)(clip.m_StreamedClip.curveCount + clip.m_DenseClip.m_CurveCount);
GenericBinding binding = bindings.FindBinding(index);
string path = GetCurvePath(tos, binding.path);

View File

@@ -1,17 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<TargetFramework>net6.0</TargetFramework>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Razmoth 2022; Copyright © Perfare 2018-2022</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Mono.Cecil" Version="0.11.3" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta13" />
<PackageReference Include="SixLabors.ImageSharp.Drawing" Version="1.0.0-beta15" />
</ItemGroup>
<ItemGroup>

View File

@@ -45,9 +45,9 @@ namespace AssetStudio
public static byte[] ConvertToBytes<TPixel>(this Image<TPixel> image) where TPixel : unmanaged, IPixel<TPixel>
{
if (image.TryGetSinglePixelSpan(out var pixelSpan))
if (image.DangerousTryGetSinglePixelMemory(out var pixelSpan))
{
return MemoryMarshal.AsBytes(pixelSpan).ToArray();
return MemoryMarshal.AsBytes(pixelSpan.Span).ToArray();
}
return null;
}

View File

@@ -884,7 +884,7 @@ namespace AssetStudio
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant ?? m_Clip.ConvertValueArrayToGenericBinding();
var m_ACLClip = m_Clip.m_ACLClip;
var aclCount = m_ACLClip.m_CurveCount;
if (m_ACLClip.m_CurveCount != 0 && Game.Name != "SR")
if (m_ACLClip.m_CurveCount != 0 && Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
{
m_ACLClip.Process(out var values, out var times);
for (int frameIndex = 0; frameIndex < times.Length; frameIndex++)
@@ -906,7 +906,7 @@ namespace AssetStudio
for (int curveIndex = 0; curveIndex < frame.keyList.Length;)
{
var index = frame.keyList[curveIndex].index;
if (Game.Name != "SR")
if (Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
index += (int)aclCount;
ReadCurveData(iAnim, m_ClipBindingConstant, (int)index, frame.time, streamedValues, 0, ref curveIndex);
}
@@ -920,12 +920,12 @@ namespace AssetStudio
for (int curveIndex = 0; curveIndex < m_DenseClip.m_CurveCount;)
{
var index = streamCount + curveIndex;
if (Game.Name != "SR")
if (Game.Name != "SR_CB2" && Game.Name != "SR_CB3")
index += aclCount;
ReadCurveData(iAnim, m_ClipBindingConstant, (int)index, time, m_DenseClip.m_SampleArray, (int)frameOffset, ref curveIndex);
}
}
if (m_ACLClip.m_CurveCount != 0 && Game.Name == "SR")
if (m_ACLClip.m_CurveCount != 0 && Game.Name == "SR_CB2" && Game.Name != "SR_CB3")
{
m_ACLClip.ProcessSR(out var values, out var times);
for (int frameIndex = 0; frameIndex < times.Length; frameIndex++)

View File

@@ -44,7 +44,7 @@ namespace AssetStudio
var compressedLength = shader.compressedLengths[i][j];
var decompressedLength = shader.decompressedLengths[i][j];
var decompressedBytes = new byte[decompressedLength];
if (game.Name == "GI" || game.Name == "CB2" || game.Name == "CB3")
if (game.Name == "GI" || game.Name == "GI_CB2" || game.Name == "GI_CB3")
{
Buffer.BlockCopy(shader.compressedBlob, (int)offset, decompressedBytes, 0, (int)decompressedLength);
}

View File

@@ -84,20 +84,19 @@ namespace AssetStudio
var matrix = Matrix3x2.CreateScale(m_Sprite.m_PixelsToUnits);
matrix *= Matrix3x2.CreateTranslation(m_Sprite.m_Rect.width * m_Sprite.m_Pivot.X - textureRectOffset.X, m_Sprite.m_Rect.height * m_Sprite.m_Pivot.Y - textureRectOffset.Y);
path = path.Transform(matrix);
var graphicsOptions = new GraphicsOptions
{
Antialias = false,
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
};
var options = new DrawingOptions
{
GraphicsOptions = graphicsOptions
GraphicsOptions = new GraphicsOptions
{
Antialias = false,
AlphaCompositionMode = PixelAlphaCompositionMode.DestOut
}
};
using (var mask = new Image<Bgra32>(rect.Width, rect.Height, SixLabors.ImageSharp.Color.Black))
{
mask.Mutate(x => x.Fill(options, SixLabors.ImageSharp.Color.Red, path));
var bursh = new ImageBrush(mask);
spriteImage.Mutate(x => x.Fill(graphicsOptions, bursh));
spriteImage.Mutate(x => x.Fill(options, bursh));
spriteImage.Mutate(x => x.Flip(FlipMode.Vertical));
return spriteImage;
}

View File

@@ -7,6 +7,13 @@ namespace AssetStudio
{
public static class Texture2DExtensions
{
private static Configuration _configuration;
static Texture2DExtensions()
{
_configuration = Configuration.Default.Clone();
_configuration.PreferContiguousImageBuffers = true;
}
public static Image<Bgra32> ConvertToImage(this Texture2D m_Texture2D, bool flip)
{
var converter = new Texture2DConverter(m_Texture2D);
@@ -15,7 +22,7 @@ namespace AssetStudio
{
if (converter.DecodeTexture2D(buff))
{
var image = Image.LoadPixelData<Bgra32>(buff, m_Texture2D.m_Width, m_Texture2D.m_Height);
var image = Image.LoadPixelData<Bgra32>(_configuration, buff, m_Texture2D.m_Width, m_Texture2D.m_Height);
if (flip)
{
image.Mutate(x => x.Flip(FlipMode.Vertical));

View File

@@ -1,11 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net472;netstandard2.0;net5.0;net6.0</TargetFrameworks>
<TargetFramework>net6.0</TargetFramework>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<Version>0.18.30</Version>
<AssemblyVersion>0.18.30</AssemblyVersion>
<FileVersion>0.18.30</FileVersion>
<Version>0.18.60</Version>
<AssemblyVersion>0.18.60</AssemblyVersion>
<FileVersion>0.18.60</FileVersion>
<Copyright>Copyright © Perfare 2020-2022; Copyright © hozuki 2020</Copyright>
<DebugType>embedded</DebugType>
</PropertyGroup>