This commit is contained in:
Razmoth
2023-03-12 22:14:22 +04:00
parent 701d76faad
commit 63f4b24b71
29 changed files with 1533 additions and 2237 deletions

View File

@@ -14,10 +14,4 @@
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
</ItemGroup>
<ItemGroup>
<None Update="Keys.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
</ItemGroup>
</Project>

View File

@@ -443,7 +443,7 @@ namespace AssetStudio
foreach (var offset in offsets)
{
stream.Offset = offset;
var dummyPath = Path.Combine("//?/block:/", reader.FileName, offset.ToString("X8"));
var dummyPath = Path.Combine(reader.FileName, offset.ToString("X8"));
var subReader = new FileReader(dummyPath, stream, true);
LoadBundleFile(subReader, reader.FullPath, offset);
}
@@ -454,7 +454,7 @@ namespace AssetStudio
do
{
stream.Offset = stream.RelativePosition;
var dummyPath = Path.Combine("//?/block:/", reader.FileName, stream.RelativePosition.ToString("X8"));
var dummyPath = Path.Combine(reader.FileName, stream.RelativePosition.ToString("X8"));
var subReader = new FileReader(dummyPath, stream, true);
LoadBundleFile(subReader, reader.FullPath, stream.RelativePosition);
} while (stream.Remaining > 0);
@@ -480,7 +480,7 @@ namespace AssetStudio
foreach (var offset in offsets)
{
stream.Offset = offset;
var dummyPath = Path.Combine("//?/blk:/", reader.FileName, offset.ToString("X8"));
var dummyPath = Path.Combine(reader.FileName, offset.ToString("X8"));
var subReader = new FileReader(dummyPath, stream, true);
switch (subReader.FileType)
{
@@ -499,7 +499,7 @@ namespace AssetStudio
do
{
stream.Offset = stream.RelativePosition;
var dummyPath = Path.Combine("//?/blk:/", reader.FileName, stream.RelativePosition.ToString("X8"));
var dummyPath = Path.Combine(reader.FileName, stream.RelativePosition.ToString("X8"));
var subReader = new FileReader(dummyPath, stream, true);
switch (subReader.FileType)
{
@@ -626,10 +626,10 @@ namespace AssetStudio
case ClassIDType.Animation:
obj = new Animation(objectReader);
break;
case ClassIDType.AnimationClip:
case ClassIDType.AnimationClip when ExportableTypes[ClassIDType.AnimationClip]:
obj = new AnimationClip(objectReader);
break;
case ClassIDType.Animator:
case ClassIDType.Animator when ExportableTypes[ClassIDType.Animator]:
obj = new Animator(objectReader);
break;
case ClassIDType.AnimatorController:
@@ -638,7 +638,7 @@ namespace AssetStudio
case ClassIDType.AnimatorOverrideController:
obj = new AnimatorOverrideController(objectReader);
break;
case ClassIDType.AssetBundle:
case ClassIDType.AssetBundle when ExportableTypes[ClassIDType.AssetBundle]:
obj = new AssetBundle(objectReader);
break;
case ClassIDType.AudioClip:
@@ -647,30 +647,29 @@ namespace AssetStudio
case ClassIDType.Avatar:
obj = new Avatar(objectReader);
break;
case ClassIDType.Font:
case ClassIDType.Font when ExportableTypes[ClassIDType.Font]:
obj = new Font(objectReader);
break;
case ClassIDType.GameObject:
case ClassIDType.GameObject when ExportableTypes[ClassIDType.GameObject]:
obj = new GameObject(objectReader);
break;
case ClassIDType.IndexObject:
case ClassIDType.IndexObject when ExportableTypes[ClassIDType.MiHoYoBinData]:
obj = new IndexObject(objectReader);
break;
case ClassIDType.Material:
case ClassIDType.Material when ExportableTypes[ClassIDType.Material]:
obj = new Material(objectReader);
break;
case ClassIDType.Mesh:
case ClassIDType.Mesh when ExportableTypes[ClassIDType.Mesh]:
obj = new Mesh(objectReader);
break;
case ClassIDType.MeshFilter:
obj = new MeshFilter(objectReader);
break;
case ClassIDType.MeshRenderer:
if (Renderer.Skipped)
goto default;
case ClassIDType.MeshRenderer when ExportableTypes[ClassIDType.Renderer]:
obj = new MeshRenderer(objectReader);
break;
case ClassIDType.MiHoYoBinData:
case ClassIDType.MiHoYoBinData when ExportableTypes[ClassIDType.MiHoYoBinData]:
obj = new MiHoYoBinData(objectReader);
break;
case ClassIDType.MonoBehaviour:
@@ -688,24 +687,22 @@ namespace AssetStudio
case ClassIDType.RectTransform:
obj = new RectTransform(objectReader);
break;
case ClassIDType.Shader:
case ClassIDType.Shader when ExportableTypes[ClassIDType.Shader]:
obj = new Shader(objectReader);
break;
case ClassIDType.SkinnedMeshRenderer:
if (Renderer.Skipped)
goto default;
case ClassIDType.SkinnedMeshRenderer when ExportableTypes[ClassIDType.Renderer]:
obj = new SkinnedMeshRenderer(objectReader);
break;
case ClassIDType.Sprite:
case ClassIDType.Sprite when ExportableTypes[ClassIDType.Sprite]:
obj = new Sprite(objectReader);
break;
case ClassIDType.SpriteAtlas:
obj = new SpriteAtlas(objectReader);
break;
case ClassIDType.TextAsset:
case ClassIDType.TextAsset when ExportableTypes[ClassIDType.TextAsset]:
obj = new TextAsset(objectReader);
break;
case ClassIDType.Texture2D:
case ClassIDType.Texture2D when ExportableTypes[ClassIDType.Texture2D]:
obj = new Texture2D(objectReader);
break;
case ClassIDType.Transform:

View File

@@ -15,7 +15,6 @@ namespace AssetStudio
BlocksInfoAtTheEnd = 0x80,
OldWebPluginCompatibility = 0x100,
BlockInfoNeedPaddingAtStart = 0x200,
CNUnityEncryption = 0x400
}
[Flags]
@@ -23,7 +22,6 @@ namespace AssetStudio
{
CompressionTypeMask = 0x3f,
Streamed = 0x40,
CNUnity = 0x100
}
public enum CompressionType
@@ -66,7 +64,6 @@ namespace AssetStudio
}
private Game Game;
private CNUnity CNUnity;
public Header m_Header;
private Node[] m_DirectoryInfo;
@@ -311,30 +308,6 @@ namespace AssetStudio
private void ReadBlocksInfoAndDirectory(FileReader reader)
{
if (Game.Type.IsCNUnity())
{
ArchiveFlags mask;
var version = ParseVersion();
//Flag changed it in these versions
if (version[0] < 2020 || //2020 and earlier
(version[0] == 2020 && version[1] == 3 && version[2] <= 34) || //2020.3.34 and earlier
(version[0] == 2021 && version[1] == 3 && version[2] <= 2) || //2021.3.2 and earlier
(version[0] == 2022 && version[1] == 3 && version[2] <= 1)) //2022.3.1 and earlier
{
mask = ArchiveFlags.BlockInfoNeedPaddingAtStart;
}
else
{
mask = ArchiveFlags.CNUnityEncryption;
}
if ((m_Header.flags & mask) != 0)
{
CNUnity = new CNUnity(reader);
}
}
byte[] blocksInfoBytes;
if (m_Header.version >= 7 && !Game.Type.IsSRGroup())
{
@@ -424,7 +397,7 @@ namespace AssetStudio
};
}
}
if (!Game.Type.IsCNUnity() && (m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
if ((m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
{
reader.AlignStream(16);
}
@@ -460,10 +433,6 @@ namespace AssetStudio
{
compressedBytesSpan = Mr0kUtils.Decrypt(compressedBytesSpan, (Mr0k)Game);
}
if (Game.Type.IsCNUnity() && (blockInfo.flags & StorageBlockFlags.CNUnity) != 0)
{
CNUnity.DecryptBlock(compressedBytesSpan, compressedSize, i);
}
if (Game.Type.IsOPFP())
{
OPFPUtils.Decrypt(compressedBytesSpan, reader.FullPath);

View File

@@ -19,8 +19,6 @@ namespace AssetStudio
public abstract class Renderer : Component
{
public static bool Skipped;
public PPtr<Material>[] m_Materials;
public StaticBatchInfo m_StaticBatchInfo;
public uint[] m_SubsetIndices;

View File

@@ -1,158 +0,0 @@
using System;
using System.Text;
using System.Security.Cryptography;
namespace AssetStudio
{
public class CNUnity
{
private const string Signature = "#$unity3dchina!@";
public static ICryptoTransform Encryptor;
public byte[] Index = new byte[0x10];
public byte[] Sub = new byte[0x10];
public CNUnity(EndianBinaryReader reader)
{
reader.ReadUInt32();
var infoBytes = reader.ReadBytes(0x10);
var infoKey = reader.ReadBytes(0x10);
reader.Position += 1;
var signatureBytes = reader.ReadBytes(0x10);
var signatureKey = reader.ReadBytes(0x10);
reader.Position += 1;
DecryptKey(signatureKey, signatureBytes);
var str = Encoding.UTF8.GetString(signatureBytes);
if (str != Signature)
throw new Exception("Invalid Signature !!");
DecryptKey(infoKey, infoBytes);
infoBytes = infoBytes.ToUInt4Array();
infoBytes.AsSpan(0, 0x10).CopyTo(Index);
var subBytes = infoBytes.AsSpan(0x10, 0x10);
for (var i = 0; i < subBytes.Length; i++)
{
var idx = (i % 4 * 4) + (i / 4);
Sub[idx] = subBytes[i];
}
}
public static bool SetKey(Entry entry)
{
try
{
using var aes = Aes.Create();
aes.Mode = CipherMode.ECB;
aes.Key = entry.GenerateKey();
Encryptor = aes.CreateEncryptor();
}
catch(Exception e)
{
Logger.Error($"[CNUnity] Invalid key !!\n{e.Message}");
return false;
}
return true;
}
public void DecryptBlock(Span<byte> bytes, int size, int index)
{
var offset = 0;
while (offset < size)
{
offset += Decrypt(bytes[offset..], index++, size - offset);
}
}
private void DecryptKey(byte[] key, byte[] data)
{
if (Encryptor != null)
{
key = Encryptor.TransformFinalBlock(key, 0, key.Length);
for (int i = 0; i < 0x10; i++)
data[i] ^= key[i];
}
}
private int DecryptByte(Span<byte> bytes, ref int offset, ref int index)
{
var b = Sub[((index >> 2) & 3) + 4] + Sub[index & 3] + Sub[((index >> 4) & 3) + 8] + Sub[((byte)index >> 6) + 12];
bytes[offset] = (byte)((Index[bytes[offset] & 0xF] - b) & 0xF | 0x10 * (Index[bytes[offset] >> 4] - b));
b = bytes[offset];
offset++;
index++;
return b;
}
private int Decrypt(Span<byte> bytes, int index, int remaining)
{
var offset = 0;
var curByte = DecryptByte(bytes, ref offset, ref index);
var byteHigh = curByte >> 4;
var byteLow = curByte & 0xF;
if (byteHigh == 0xF)
{
int b;
do
{
b = DecryptByte(bytes, ref offset, ref index);
byteHigh += b;
} while (b == 0xFF);
}
offset += byteHigh;
if (offset < remaining)
{
DecryptByte(bytes, ref offset, ref index);
DecryptByte(bytes, ref offset, ref index);
if (byteLow == 0xF)
{
int b;
do
{
b = DecryptByte(bytes, ref offset, ref index);
} while(b == 0xFF);
}
}
return offset;
}
public record Entry
{
public string Name { get; private set; }
public string Key { get; private set; }
public Entry(string name, string key)
{
Name = name;
Key = key;
}
public bool Validate()
{
var bytes = GenerateKey();
if (bytes.Length != 0x10)
{
Logger.Warning($"[CNUnity] {this} has invalid key, size should be 16 bytes, skipping...");
return false;
}
return true;
}
public byte[] GenerateKey() => Convert.FromHexString(Key);
public override string ToString() => $"{Name} ({Key})";
}
}
}

View File

@@ -12,7 +12,6 @@ namespace AssetStudio
{
int index = 0;
Games.Add(index++, new(GameType.Normal));
Games.Add(index++, new Game(GameType.CNUnity));
Games.Add(index++, new Mhy0(GameType.GI, GIMhy0ShiftRow, GIMhy0Key, GIMhy0Mul, GIExpansionKey, GISBox, GIInitVector, GIInitSeed));
Games.Add(index++, new Mr0k(GameType.GI_Pack, PackExpansionKey, blockKey: PackBlockKey));
Games.Add(index++, new Mr0k(GameType.GI_CB1));
@@ -31,6 +30,7 @@ namespace AssetStudio
Games.Add(index++, new Game(GameType.FantasyOfWind));
Games.Add(index++, new Game(GameType.ShiningNikki));
}
public static Game GetGame(GameType gameType) => GetGame((int)gameType);
public static Game GetGame(int index)
{
if (!Games.TryGetValue(index, out var format))
@@ -124,7 +124,6 @@ namespace AssetStudio
SR_CB3,
TOT,
Naraka,
CNUnity,
EnsembleStars,
OPFP,
AlchemyStars,
@@ -147,7 +146,6 @@ namespace AssetStudio
public static bool IsSRCB3(this GameType type) => type == GameType.SR_CB3;
public static bool IsTOT(this GameType type) => type == GameType.TOT;
public static bool IsNaraka(this GameType type) => type == GameType.Naraka;
public static bool IsCNUnity(this GameType type) => type == GameType.CNUnity;
public static bool IsOPFP(this GameType type) => type == GameType.OPFP;
public static bool IsGIGroup(this GameType type) => type switch
{

View File

@@ -1,70 +0,0 @@
[
{
"Name": "PGR GLB/KR",
"Key": "6B75726F6B75726F6B75726F6B75726F"
},
{
"Name": "PGR CN/JP/TW",
"Key": "7935585076714C4F72436F6B57524961"
},
{
"Name": "Archeland/Kalpa of Universe",
"Key": "426C61636B4A61636B50726F6A656374"
},
{
"Name": "Archeland 1.1.14",
"Key": "50726F6A65637441726368654C616E64"
},
{
"Name": "Neural Cloud",
"Key": "31636162383436663532393031633965"
},
{
"Name": "Higan: Eruthyll",
"Key": "45317832633361346C35693662377572"
},
{
"Name": "White Chord",
"Key": "79756C6F6E6731383638676E6F6C7579"
},
{
"Name": "Mecharashi",
"Key": "33384338334631333245374637413041"
},
{
"Name": "Castlevania: Moon Night Fantasy",
"Key": "31323334353637383132333435363738"
},
{
"Name": "Huā Yì Shān Xīn Zhī Yuè",
"Key": "494E484A6E68647970716B3534377864"
},
{
"Name": "Doula Continent",
"Key": "52346366773339474644326661785756"
},
{
"Name": "Bless Global",
"Key": "6C6F6E67747567616D652E796A66623F"
},
{
"Name": "Starside",
"Key": "41394A3542384D4A50554D3539464B57"
},
{
"Name": "Resonance Soltice",
"Key": "5265736F6E616E63655265626F726E52"
},
{
"Name": "Oblivion Override",
"Key": "7179666D6F6F6E323331323433343532"
},
{
"Name": "Dawnlands",
"Key": "636F6465737339353237636F64657373"
},
{
"Name": "BB",
"Key": "5F6C4E3F3A3F233F3F3F3F663F1A3F3F"
}
]

View File

@@ -1,68 +0,0 @@
using System;
using System.IO;
using System.Linq;
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Reflection;
namespace AssetStudio
{
public static class CNUnityKeyManager
{
public const string KeysFileName = "Keys.json";
private static List<CNUnity.Entry> Entries = new List<CNUnity.Entry>();
static CNUnityKeyManager()
{
var str = File.ReadAllText(KeysFileName);
Entries = JsonConvert.DeserializeObject<List<CNUnity.Entry>>(str);
}
public static void SaveEntries(List<CNUnity.Entry> entries)
{
Entries.Clear();
Entries.AddRange(entries);
var str = JsonConvert.SerializeObject(Entries);
File.WriteAllText(KeysFileName, str);
}
public static void SetKey(int index)
{
if (TryGetEntry(index, out var cnunity))
{
if (CNUnity.SetKey(cnunity))
{
Logger.Info($"[CNUnity] Selected Key is {cnunity}");
}
else
{
Logger.Info($"[CNUnity] No Key is selected !!");
}
}
}
public static bool TryGetEntry(int index, out CNUnity.Entry key)
{
try
{
if (index < 0 || index > Entries.Count)
{
throw new ArgumentOutOfRangeException();
}
key = Entries[index];
}
catch(Exception e)
{
Logger.Error($"[CNUnity] Invalid Index, check if list is not empty !!\n{e.Message}");
key = null;
return false;
}
return true;
}
public static CNUnity.Entry[] GetEntries() => Entries.ToArray();
}
}

View File

@@ -28,7 +28,7 @@ namespace AssetStudio
{
public static void Export(string path, IImported imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1, float scaleFactor, int versionIndex, bool isAscii)
{
var file = new FileInfo(path);
var dir = file.Directory;
@@ -43,7 +43,7 @@ namespace AssetStudio
var name = Path.GetFileName(path);
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, versionIndex, isAscii))
using (var exporter = new FbxExporter(name, imported, allNodes, skins, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, versionIndex, isAscii))
{
exporter.Initialize();
exporter.ExportAll(blendShape, animation, eulerFilter, filterPrecision);

View File

@@ -16,11 +16,12 @@ namespace AssetStudio.FbxInterop
private readonly bool _castToBone;
private readonly float _boneSize;
private readonly bool _exportAllUvsAsDiffuseMaps;
private readonly bool _exportUV0UV1;
private readonly float _scaleFactor;
private readonly int _versionIndex;
private readonly bool _isAscii;
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
internal FbxExporter(string fileName, IImported imported, bool allNodes, bool exportSkins, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1, float scaleFactor, int versionIndex, bool isAscii)
{
_context = new FbxExporterContext();
@@ -31,6 +32,7 @@ namespace AssetStudio.FbxInterop
_castToBone = castToBone;
_boneSize = boneSize;
_exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps;
_exportUV0UV1 = exportUV0UV1;
_scaleFactor = scaleFactor;
_versionIndex = versionIndex;
_isAscii = isAscii;
@@ -173,7 +175,7 @@ namespace AssetStudio.FbxInterop
{
foreach (var meshFrame in meshFrames)
{
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins, _exportAllUvsAsDiffuseMaps);
_context.ExportMeshFromFrame(rootFrame, meshFrame, _imported.MeshList, _imported.MaterialList, _imported.TextureList, _exportSkins, _exportAllUvsAsDiffuseMaps, _exportUV0UV1);
}
}

View File

@@ -173,12 +173,12 @@ namespace AssetStudio.FbxInterop
AsFbxPrepareMaterials(_pContext, materialCount, textureCount);
}
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
internal void ExportMeshFromFrame(ImportedFrame rootFrame, ImportedFrame meshFrame, List<ImportedMesh> meshList, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, bool exportSkins, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1)
{
var meshNode = _frameToNode[meshFrame];
var mesh = ImportedHelpers.FindMesh(meshFrame.Path, meshList);
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins, exportAllUvsAsDiffuseMaps);
ExportMesh(rootFrame, materialList, textureList, meshNode, mesh, exportSkins, exportAllUvsAsDiffuseMaps, exportUV0UV1);
}
private IntPtr ExportTexture(ImportedTexture texture)
@@ -207,7 +207,7 @@ namespace AssetStudio.FbxInterop
return pTex;
}
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins, bool exportAllUvsAsDiffuseMaps)
private void ExportMesh(ImportedFrame rootFrame, List<ImportedMaterial> materialList, List<ImportedTexture> textureList, IntPtr frameNode, ImportedMesh importedMesh, bool exportSkins, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1)
{
var boneList = importedMesh.BoneList;
var totalBoneCount = 0;
@@ -253,6 +253,26 @@ namespace AssetStudio.FbxInterop
AsFbxMeshCreateElementNormal(mesh);
}
if (exportUV0UV1)
{
if (importedMesh.hasUV[0])
{
AsFbxMeshCreateDiffuseUV(mesh, 0);
}
if (importedMesh.hasUV[1])
{
if (exportAllUvsAsDiffuseMaps)
{
AsFbxMeshCreateDiffuseUV(mesh, 1);
}
else
{
AsFbxMeshCreateNormalMapUV(mesh, 1);
}
}
}
else
{
for (int i = 0; i < importedMesh.hasUV.Length; i++)
{
if (!importedMesh.hasUV[i]) { continue; }
@@ -266,6 +286,7 @@ namespace AssetStudio.FbxInterop
AsFbxMeshCreateDiffuseUV(mesh, i);
}
}
}
if (importedMesh.hasTangent)
{
@@ -367,7 +388,8 @@ namespace AssetStudio.FbxInterop
AsFbxMeshElementNormalAdd(mesh, 0, normal.X, normal.Y, normal.Z);
}
for (var uvIndex = 0; uvIndex < importedMesh.hasUV.Length; uvIndex += 1)
var uvSize = exportUV0UV1 ? 2 : importedMesh.hasUV.Length;
for (var uvIndex = 0; uvIndex < uvSize; uvIndex += 1)
{
if (importedMesh.hasUV[uvIndex])
{

View File

@@ -76,18 +76,12 @@
<setting name="encrypted" serializeAs="String">
<value>True</value>
</setting>
<setting name="skipRenderer" serializeAs="String">
<value>False</value>
</setting>
<setting name="selectedGame" serializeAs="String">
<value>0</value>
</setting>
<setting name="enableResolveDependencies" serializeAs="String">
<value>True</value>
</setting>
<setting name="selectedCNUnityKey" serializeAs="String">
<value>0</value>
</setting>
<setting name="selectedAssetMapType" serializeAs="String">
<value>0</value>
</setting>
@@ -100,6 +94,12 @@
<setting name="skipContainer" serializeAs="String">
<value>False</value>
</setting>
<setting name="exportUV0UV1" serializeAs="String">
<value>False</value>
</setting>
<setting name="exportableTypes" serializeAs="String">
<value>{"GameObject":true,"Material":true,"Texture2D":true,"Mesh":true,"Renderer":true,"Shader":true,"TextAsset":true,"AnimationClip":true,"Font":true,"Sprite":true,"Animator":true,"MiHoYoBinData":true,"AssetBundle":true}</value>
</setting>
</AssetStudioGUI.Properties.Settings>
</userSettings>
</configuration>

File diff suppressed because it is too large Load Diff

View File

@@ -107,13 +107,17 @@ namespace AssetStudioGUI
displayAll.Checked = Properties.Settings.Default.displayAll;
displayInfo.Checked = Properties.Settings.Default.displayInfo;
enablePreview.Checked = Properties.Settings.Default.enablePreview;
enableResolveDependencies.Checked = Properties.Settings.Default.enableResolveDependencies;
skipContainer.Checked = Properties.Settings.Default.skipContainer;
assetsManager.ResolveDependencies = enableResolveDependencies.Checked;
Renderer.Skipped = Properties.Settings.Default.skipRenderer;
assetsManager.ResolveDependencies = Properties.Settings.Default.enableResolveDependencies;
MiHoYoBinData.Exportable = Properties.Settings.Default.exportMiHoYoBinData;
MiHoYoBinData.Encrypted = Properties.Settings.Default.encrypted;
MiHoYoBinData.Key = Properties.Settings.Default.key;
var types = JsonConvert.DeserializeObject<Dictionary<ClassIDType, bool>>(Properties.Settings.Default.exportableTypes);
foreach (var exportable in types)
{
if (assetsManager.ExportableTypes.ContainsKey(exportable.Key))
assetsManager.ExportableTypes[exportable.Key] = exportable.Value;
}
}
private void InitializeLogger()
@@ -152,7 +156,6 @@ namespace AssetStudioGUI
Logger.Info($"Target Game type is {Studio.Game.Type}");
CABMapNameComboBox.SelectedIndexChanged += new EventHandler(specifyNameComboBox_SelectedIndexChanged);
CNUnityKeyManager.SetKey(Properties.Settings.Default.selectedCNUnityKey);
}
private void AssetStudioGUIForm_DragEnter(object sender, DragEventArgs e)
{
@@ -494,22 +497,6 @@ namespace AssetStudioGUI
Properties.Settings.Default.enablePreview = enablePreview.Checked;
Properties.Settings.Default.Save();
}
private void enableResolveDependencies_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.enableResolveDependencies = enableResolveDependencies.Checked;
Properties.Settings.Default.Save();
assetsManager.ResolveDependencies = enableResolveDependencies.Checked;
}
private void skipContainer_CheckedChanged(object sender, EventArgs e)
{
Properties.Settings.Default.skipContainer = skipContainer.Checked;
Properties.Settings.Default.Save();
SkipContainer = skipContainer.Checked;
}
private void displayAssetInfo_Check(object sender, EventArgs e)
{
if (displayInfo.Checked && assetInfoLabel.Text != null)
@@ -529,6 +516,12 @@ namespace AssetStudioGUI
{
var exportOpt = new ExportOptions();
exportOpt.ShowDialog(this);
var types = JsonConvert.DeserializeObject<Dictionary<ClassIDType, bool>>(Properties.Settings.Default.exportableTypes);
foreach (var exportable in types)
{
if (assetsManager.ExportableTypes.ContainsKey(exportable.Key))
assetsManager.ExportableTypes[exportable.Key] = exportable.Value;
}
}
private void assetListView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e)
@@ -1737,7 +1730,7 @@ namespace AssetStudioGUI
{
return;
}
if (skipContainer.Checked)
if (Properties.Settings.Default.skipContainer)
{
Logger.Info("Skip container is enabled, aborting...");
return;
@@ -1937,12 +1930,6 @@ namespace AssetStudioGUI
InvokeUpdate(miscToolStripMenuItem, true);
}
private void toolStripMenuItem23_Click(object sender, EventArgs e)
{
var form = new CNUnityForm();
form.Show();
}
private void resetToolStripMenuItem_Click(object sender, EventArgs e)
{
ResetForm();
@@ -1978,7 +1965,7 @@ namespace AssetStudioGUI
private async void loadAIToolStripMenuItem_Click(object sender, EventArgs e)
{
if (skipContainer.Checked)
if (Properties.Settings.Default.skipContainer)
{
Logger.Info("Skip container is enabled, aborting...");
return;

View File

@@ -1,94 +0,0 @@
namespace AssetStudioGUI
{
partial class CNUnityForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.specifyCNUnityList = new System.Windows.Forms.DataGridView();
this.NameField = new System.Windows.Forms.DataGridViewTextBoxColumn();
this.KeyField = new System.Windows.Forms.DataGridViewTextBoxColumn();
((System.ComponentModel.ISupportInitialize)(this.specifyCNUnityList)).BeginInit();
this.SuspendLayout();
//
// specifyCNUnityList
//
this.specifyCNUnityList.AllowUserToResizeColumns = false;
this.specifyCNUnityList.AllowUserToResizeRows = false;
this.specifyCNUnityList.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
this.specifyCNUnityList.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.specifyCNUnityList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.NameField,
this.KeyField});
this.specifyCNUnityList.Dock = System.Windows.Forms.DockStyle.Fill;
this.specifyCNUnityList.Location = new System.Drawing.Point(0, 0);
this.specifyCNUnityList.MultiSelect = false;
this.specifyCNUnityList.Name = "specifyCNUnityList";
this.specifyCNUnityList.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
this.specifyCNUnityList.RowTemplate.Height = 25;
this.specifyCNUnityList.Size = new System.Drawing.Size(432, 229);
this.specifyCNUnityList.TabIndex = 0;
this.specifyCNUnityList.RowHeaderMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.specifyCNUnityList_RowHeaderMouseDoubleClick);
//
// NameField
//
this.NameField.HeaderText = "Name";
this.NameField.Name = "NameField";
this.NameField.Width = 140;
//
// KeyField
//
this.KeyField.AutoSizeMode = System.Windows.Forms.DataGridViewAutoSizeColumnMode.Fill;
this.KeyField.HeaderText = "Key";
this.KeyField.Name = "KeyField";
//
// CNUnityForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(432, 229);
this.Controls.Add(this.specifyCNUnityList);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "CNUnityForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
this.Text = "CNUnityForm";
this.TopMost = true;
((System.ComponentModel.ISupportInitialize)(this.specifyCNUnityList)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView specifyCNUnityList;
private System.Windows.Forms.DataGridViewTextBoxColumn NameField;
private System.Windows.Forms.DataGridViewTextBoxColumn KeyField;
}
}

View File

@@ -1,126 +0,0 @@
using System;
using System.Windows.Forms;
using System.Collections.Generic;
using AssetStudio;
using System.Linq;
namespace AssetStudioGUI
{
public partial class CNUnityForm : Form
{
public CNUnityForm()
{
InitializeComponent();
var keys = CNUnityKeyManager.GetEntries();
for (int i = 0; i < keys.Length; i++)
{
var key = keys[i];
var rowIdx = specifyCNUnityList.Rows.Add();
specifyCNUnityList.Rows[rowIdx].Cells["NameField"].Value = key.Name;
specifyCNUnityList.Rows[rowIdx].Cells["KeyField"].Value = key.Key;
}
var index = Properties.Settings.Default.selectedCNUnityKey;
if (index >= specifyCNUnityList.RowCount)
{
index = 0;
}
specifyCNUnityList.CurrentCell = specifyCNUnityList.Rows[index].Cells[0];
}
private void OKbutton_Click(object sender, EventArgs e)
{
var keys = new List<CNUnity.Entry>();
for (int i = specifyCNUnityList.Rows.Count - 1; i >= 0; i--)
{
var row = specifyCNUnityList.Rows[i];
var name = row.Cells["NameField"].Value as string;
var key = row.Cells["KeyField"].Value as string;
if (!(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(key)))
{
var cnunity = new CNUnity.Entry(name, key);
if (cnunity.Validate())
{
keys.Add(cnunity);
continue;
}
}
if (specifyCNUnityList.CurrentCell.RowIndex == row.Index)
{
var previousRow = specifyCNUnityList.Rows.Cast<DataGridViewRow>().ElementAtOrDefault(i - 1);
if (previousRow != null)
{
specifyCNUnityList.CurrentCell = previousRow.Cells[0];
}
}
if (i != specifyCNUnityList.RowCount - 1)
{
specifyCNUnityList.Rows.RemoveAt(i);
}
}
CNUnityKeyManager.SaveEntries(keys.Reverse<CNUnity.Entry>().ToList());
CNUnityKeyManager.SetKey(specifyCNUnityList.CurrentRow.Index);
Properties.Settings.Default.selectedCNUnityKey = specifyCNUnityList.CurrentRow.Index;
Properties.Settings.Default.Save();
DialogResult = DialogResult.OK;
Close();
}
private void Cancel_Click(object sender, EventArgs e)
{
DialogResult = DialogResult.Cancel;
Close();
}
private void specifyCNUnityList_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
{
var keys = new List<CNUnity.Entry>();
for (int i = specifyCNUnityList.Rows.Count - 1; i >= 0; i--)
{
var row = specifyCNUnityList.Rows[i];
var name = row.Cells["NameField"].Value as string;
var key = row.Cells["KeyField"].Value as string;
if (!(string.IsNullOrEmpty(name) || string.IsNullOrEmpty(key)))
{
var cnunity = new CNUnity.Entry(name, key);
if (cnunity.Validate())
{
keys.Add(cnunity);
continue;
}
}
if (specifyCNUnityList.CurrentCell.RowIndex == row.Index)
{
var previousRow = specifyCNUnityList.Rows.Cast<DataGridViewRow>().ElementAtOrDefault(i - 1);
if (previousRow != null)
{
specifyCNUnityList.CurrentCell = previousRow.Cells[0];
}
}
if (i != specifyCNUnityList.RowCount - 1)
{
specifyCNUnityList.Rows.RemoveAt(i);
}
}
CNUnityKeyManager.SaveEntries(keys.Reverse<CNUnity.Entry>().ToList());
CNUnityKeyManager.SetKey(specifyCNUnityList.CurrentRow.Index);
Properties.Settings.Default.selectedCNUnityKey = specifyCNUnityList.CurrentRow.Index;
Properties.Settings.Default.Save();
DialogResult = DialogResult.OK;
Close();
}
}
}

View File

@@ -1,66 +0,0 @@
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="NameField.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
<metadata name="KeyField.UserAddedColumn" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>True</value>
</metadata>
</root>

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,8 @@
using AssetStudio;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
namespace AssetStudioGUI
@@ -31,19 +34,35 @@ namespace AssetStudioGUI
exportBlendShape.Checked = Properties.Settings.Default.exportBlendShape;
castToBone.Checked = Properties.Settings.Default.castToBone;
exportAllUvsAsDiffuseMaps.Checked = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
exportUV0UV1.Checked = Properties.Settings.Default.exportUV0UV1;
boneSize.Value = Properties.Settings.Default.boneSize;
scaleFactor.Value = Properties.Settings.Default.scaleFactor;
fbxVersion.SelectedIndex = Properties.Settings.Default.fbxVersion;
fbxFormat.SelectedIndex = Properties.Settings.Default.fbxFormat;
skipRenderer.Checked = Properties.Settings.Default.skipRenderer;
exportMiHoYoBinData.Checked = Properties.Settings.Default.exportMiHoYoBinData;
collectAnimations.Checked = Properties.Settings.Default.collectAnimations;
encrypted.Checked = Properties.Settings.Default.encrypted;
key.Value = Properties.Settings.Default.key;
exportableTypes.Items.AddRange(Studio.assetsManager.ExportableTypes.Keys.Select(x => x.ToString()).ToArray());
var types = JsonConvert.DeserializeObject<Dictionary<ClassIDType, bool>>(Properties.Settings.Default.exportableTypes);
foreach (var exportable in types)
{
var idx = exportableTypes.Items.IndexOf(exportable.Key.ToString());
if (idx != -1)
exportableTypes.SetItemChecked(idx, exportable.Value);
}
}
private void OKbutton_Click(object sender, EventArgs e)
{
var types = new Dictionary<ClassIDType, bool>();
for (int i = 0; i < exportableTypes.Items.Count; i++)
{
var type = Enum.Parse<ClassIDType>(exportableTypes.Items[i].ToString());
var state = exportableTypes.GetItemChecked(i);
types.Add(type, state);
}
Properties.Settings.Default.exportableTypes = JsonConvert.SerializeObject(types);
Properties.Settings.Default.assetGroupOption = assetGroupOptions.SelectedIndex;
Properties.Settings.Default.restoreExtensionName = restoreExtensionName.Checked;
Properties.Settings.Default.convertTexture = converttexture.Checked;
@@ -65,17 +84,15 @@ namespace AssetStudioGUI
Properties.Settings.Default.exportBlendShape = exportBlendShape.Checked;
Properties.Settings.Default.castToBone = castToBone.Checked;
Properties.Settings.Default.exportAllUvsAsDiffuseMaps = exportAllUvsAsDiffuseMaps.Checked;
Properties.Settings.Default.exportUV0UV1 = exportUV0UV1.Checked;
Properties.Settings.Default.boneSize = boneSize.Value;
Properties.Settings.Default.scaleFactor = scaleFactor.Value;
Properties.Settings.Default.fbxVersion = fbxVersion.SelectedIndex;
Properties.Settings.Default.fbxFormat = fbxFormat.SelectedIndex;
Properties.Settings.Default.skipRenderer = skipRenderer.Checked;
Properties.Settings.Default.exportMiHoYoBinData = exportMiHoYoBinData.Checked;
Properties.Settings.Default.collectAnimations = collectAnimations.Checked;
Properties.Settings.Default.encrypted = encrypted.Checked;
Properties.Settings.Default.key = (byte)key.Value;
Properties.Settings.Default.Save();
Renderer.Skipped = !Properties.Settings.Default.skipRenderer;
MiHoYoBinData.Key = (byte)key.Value;
MiHoYoBinData.Encrypted = encrypted.Checked;
DialogResult = DialogResult.OK;

View File

@@ -60,13 +60,16 @@
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
<metadata name="keyToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>162, 17</value>
</metadata>
<metadata name="keyToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>162, 17</value>
<metadata name="skipToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>404, 17</value>
</metadata>
<metadata name="resolveToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>273, 17</value>
</metadata>
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>57</value>
</metadata>
</root>

View File

@@ -360,11 +360,12 @@ namespace AssetStudioGUI
var castToBone = Properties.Settings.Default.castToBone;
var boneSize = (int)Properties.Settings.Default.boneSize;
var exportAllUvsAsDiffuseMaps = Properties.Settings.Default.exportAllUvsAsDiffuseMaps;
var exportUV0UV1 = Properties.Settings.Default.exportUV0UV1;
var scaleFactor = (float)Properties.Settings.Default.scaleFactor;
var fbxVersion = Properties.Settings.Default.fbxVersion;
var fbxFormat = Properties.Settings.Default.fbxFormat;
ModelExporter.ExportFbx(exportPath, convert, eulerFilter, filterPrecision,
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, fbxVersion, fbxFormat == 1);
exportAllNodes, exportSkins, exportAnimations, exportBlendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, fbxVersion, fbxFormat == 1);
}
public static bool ExportDumpFile(AssetItem item, string exportPath)

Binary file not shown.

Binary file not shown.

View File

@@ -12,7 +12,7 @@ namespace AssetStudioGUI.Properties {
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.4.0.0")]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
@@ -311,18 +311,6 @@ namespace AssetStudioGUI.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool skipRenderer {
get {
return ((bool)(this["skipRenderer"]));
}
set {
this["skipRenderer"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -347,18 +335,6 @@ namespace AssetStudioGUI.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
public int selectedCNUnityKey {
get {
return ((int)(this["selectedCNUnityKey"]));
}
set {
this["selectedCNUnityKey"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("0")]
@@ -406,5 +382,31 @@ namespace AssetStudioGUI.Properties {
this["skipContainer"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool exportUV0UV1 {
get {
return ((bool)(this["exportUV0UV1"]));
}
set {
this["exportUV0UV1"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("{\"GameObject\":true,\"Material\":true,\"Texture2D\":true,\"Mesh\":true,\"Renderer\":true,\"" +
"Shader\":true,\"TextAsset\":true,\"AnimationClip\":true,\"Font\":true,\"Sprite\":true,\"An" +
"imator\":true,\"MiHoYoBinData\":true,\"AssetBundle\":true}")]
public string exportableTypes {
get {
return ((string)(this["exportableTypes"]));
}
set {
this["exportableTypes"] = value;
}
}
}
}

View File

@@ -74,18 +74,12 @@
<Setting Name="encrypted" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="skipRenderer" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="selectedGame" Type="System.Int32" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="enableResolveDependencies" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">True</Value>
</Setting>
<Setting Name="selectedCNUnityKey" Type="System.Int32" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
<Setting Name="selectedAssetMapType" Type="System.Int32" Scope="User">
<Value Profile="(Default)">0</Value>
</Setting>
@@ -98,5 +92,11 @@
<Setting Name="skipContainer" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="exportUV0UV1" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="exportableTypes" Type="System.String" Scope="User">
<Value Profile="(Default)">{"GameObject":true,"Material":true,"Texture2D":true,"Mesh":true,"Renderer":true,"Shader":true,"TextAsset":true,"AnimationClip":true,"Font":true,"Sprite":true,"Animator":true,"MiHoYoBinData":true,"AssetBundle":true}</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@@ -4,6 +4,13 @@ using AssetStudio.PInvoke;
namespace ACLLibs
{
public struct DecompressedClip
{
public IntPtr Values;
public int ValuesCount;
public IntPtr Times;
public int TimesCount;
}
public static class ACL
{
private const string DLL_NAME = "acl";
@@ -13,27 +20,30 @@ namespace ACLLibs
}
public static void DecompressAll(byte[] 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();
var decompressedClip = new DecompressedClip();
DecompressAll(data, ref decompressedClip);
values = new float[numValues];
Marshal.Copy(pValues, values, 0, numValues);
values = new float[decompressedClip.ValuesCount];
Marshal.Copy(decompressedClip.Values, values, 0, decompressedClip.ValuesCount);
times = new float[numTimes];
Marshal.Copy(pTimes, times, 0, numTimes);
times = new float[decompressedClip.TimesCount];
Marshal.Copy(decompressedClip.Times, times, 0, decompressedClip.TimesCount);
Dispose(ref decompressedClip);
}
#region importfunctions
[DllImport(DLL_NAME)]
private static extern void DecompressAll(IntPtr data, out IntPtr pValues, out int numValues, out IntPtr pTimes, out int numTimes);
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void DecompressAll(byte[] data, ref DecompressedClip decompressedClip);
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void Dispose(ref DecompressedClip decompressedClip);
#endregion
}
public static partial class SRACL
public static class SRACL
{
private const string DLL_NAME = "sracl";
static SRACL()
@@ -42,22 +52,25 @@ namespace ACLLibs
}
public static void DecompressAll(byte[] 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();
var decompressedClip = new DecompressedClip();
DecompressAll(data, ref decompressedClip);
values = new float[numValues];
Marshal.Copy(pValues, values, 0, numValues);
values = new float[decompressedClip.ValuesCount];
Marshal.Copy(decompressedClip.Values, values, 0, decompressedClip.ValuesCount);
times = new float[numTimes];
Marshal.Copy(pTimes, times, 0, numTimes);
times = new float[decompressedClip.TimesCount];
Marshal.Copy(decompressedClip.Times, times, 0, decompressedClip.TimesCount);
Dispose(ref decompressedClip);
}
#region importfunctions
[DllImport(DLL_NAME)]
private static extern void DecompressAll(IntPtr data, out IntPtr pValues, out int numValues, out IntPtr pTimes, out int numTimes);
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void DecompressAll(byte[] data, ref DecompressedClip decompressedClip);
[DllImport(DLL_NAME, CallingConvention = CallingConvention.Cdecl)]
private static extern void Dispose(ref DecompressedClip decompressedClip);
#endregion
}

View File

@@ -3,9 +3,9 @@
public static class ModelExporter
{
public static void ExportFbx(string path, IImported imported, bool eulerFilter, float filterPrecision,
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, float scaleFactor, int versionIndex, bool isAscii)
bool allNodes, bool skins, bool animation, bool blendShape, bool castToBone, float boneSize, bool exportAllUvsAsDiffuseMaps, bool exportUV0UV1, float scaleFactor, int versionIndex, bool isAscii)
{
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allNodes, skins, animation, blendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, scaleFactor, versionIndex, isAscii);
Fbx.Exporter.Export(path, imported, eulerFilter, filterPrecision, allNodes, skins, animation, blendShape, castToBone, boneSize, exportAllUvsAsDiffuseMaps, exportUV0UV1, scaleFactor, versionIndex, isAscii);
}
}
}