v0.80.36
This commit is contained in:
@@ -13,11 +13,5 @@
|
||||
<PackageReference Include="K4os.Compression.LZ4" Version="1.3.4-beta" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.2" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Update="Keys.json">
|
||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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})";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,17 +253,38 @@ namespace AssetStudio.FbxInterop
|
||||
AsFbxMeshCreateElementNormal(mesh);
|
||||
}
|
||||
|
||||
for (int i = 0; i < importedMesh.hasUV.Length; i++)
|
||||
if (exportUV0UV1)
|
||||
{
|
||||
if (!importedMesh.hasUV[i]) { continue; }
|
||||
|
||||
if (i == 1 && !exportAllUvsAsDiffuseMaps)
|
||||
if (importedMesh.hasUV[0])
|
||||
{
|
||||
AsFbxMeshCreateNormalMapUV(mesh, 1);
|
||||
AsFbxMeshCreateDiffuseUV(mesh, 0);
|
||||
}
|
||||
else
|
||||
if (importedMesh.hasUV[1])
|
||||
{
|
||||
AsFbxMeshCreateDiffuseUV(mesh, i);
|
||||
if (exportAllUvsAsDiffuseMaps)
|
||||
{
|
||||
AsFbxMeshCreateDiffuseUV(mesh, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsFbxMeshCreateNormalMapUV(mesh, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < importedMesh.hasUV.Length; i++)
|
||||
{
|
||||
if (!importedMesh.hasUV[i]) { continue; }
|
||||
|
||||
if (i == 1 && !exportAllUvsAsDiffuseMaps)
|
||||
{
|
||||
AsFbxMeshCreateNormalMapUV(mesh, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
AsFbxMeshCreateDiffuseUV(mesh, i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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])
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
1817
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
1817
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
{
|
||||
@@ -269,7 +272,7 @@ namespace AssetStudioGUI
|
||||
{
|
||||
productName = "no productName";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Text = $"Studio v{Application.ProductVersion} - {productName} - {assetsManager.assetsFileList[0].unityVersion} - {assetsManager.assetsFileList[0].m_TargetPlatform}";
|
||||
|
||||
@@ -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;
|
||||
|
||||
94
AssetStudioGUI/CNUnityForm.Designer.cs
generated
94
AssetStudioGUI/CNUnityForm.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
1006
AssetStudioGUI/ExportOptions.Designer.cs
generated
1006
AssetStudioGUI/ExportOptions.Designer.cs
generated
File diff suppressed because it is too large
Load Diff
@@ -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;
|
||||
|
||||
@@ -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>
|
||||
@@ -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.
Binary file not shown.
Binary file not shown.
52
AssetStudioGUI/Properties/Settings.Designer.cs
generated
52
AssetStudioGUI/Properties/Settings.Designer.cs
generated
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user