Added UnityCN.
This commit is contained in:
@@ -15,5 +15,11 @@
|
|||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||||
<PackageReference Include="ZstdSharp.Port" Version="0.7.2" />
|
<PackageReference Include="ZstdSharp.Port" Version="0.7.2" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="Keys.json">
|
||||||
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ namespace AssetStudio
|
|||||||
BlocksInfoAtTheEnd = 0x80,
|
BlocksInfoAtTheEnd = 0x80,
|
||||||
OldWebPluginCompatibility = 0x100,
|
OldWebPluginCompatibility = 0x100,
|
||||||
BlockInfoNeedPaddingAtStart = 0x200,
|
BlockInfoNeedPaddingAtStart = 0x200,
|
||||||
|
UnityCNEncryption = 0x400
|
||||||
}
|
}
|
||||||
|
|
||||||
[Flags]
|
[Flags]
|
||||||
@@ -66,6 +67,7 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Game Game;
|
private Game Game;
|
||||||
|
private UnityCN UnityCN;
|
||||||
|
|
||||||
public Header m_Header;
|
public Header m_Header;
|
||||||
private Node[] m_DirectoryInfo;
|
private Node[] m_DirectoryInfo;
|
||||||
@@ -75,6 +77,7 @@ namespace AssetStudio
|
|||||||
|
|
||||||
|
|
||||||
private bool HasUncompressedDataHash = true;
|
private bool HasUncompressedDataHash = true;
|
||||||
|
private bool HasBlockInfoNeedPaddingAtStart = true;
|
||||||
|
|
||||||
public BundleFile(FileReader reader, Game game)
|
public BundleFile(FileReader reader, Game game)
|
||||||
{
|
{
|
||||||
@@ -100,6 +103,10 @@ namespace AssetStudio
|
|||||||
case "UnityFS":
|
case "UnityFS":
|
||||||
case "ENCR":
|
case "ENCR":
|
||||||
ReadHeader(reader);
|
ReadHeader(reader);
|
||||||
|
if (game.Type.IsUnityCN())
|
||||||
|
{
|
||||||
|
ReadUnityCN(reader);
|
||||||
|
}
|
||||||
ReadBlocksInfoAndDirectory(reader);
|
ReadBlocksInfoAndDirectory(reader);
|
||||||
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
using (var blocksStream = CreateBlocksStream(reader.FullPath))
|
||||||
{
|
{
|
||||||
@@ -312,6 +319,32 @@ namespace AssetStudio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ReadUnityCN(EndianBinaryReader reader)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
HasBlockInfoNeedPaddingAtStart = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = ArchiveFlags.UnityCNEncryption;
|
||||||
|
HasBlockInfoNeedPaddingAtStart = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((m_Header.flags & mask) != 0)
|
||||||
|
{
|
||||||
|
UnityCN = new UnityCN(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ReadBlocksInfoAndDirectory(FileReader reader)
|
private void ReadBlocksInfoAndDirectory(FileReader reader)
|
||||||
{
|
{
|
||||||
byte[] blocksInfoBytes;
|
byte[] blocksInfoBytes;
|
||||||
@@ -403,7 +436,7 @@ namespace AssetStudio
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ((m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
|
if (HasBlockInfoNeedPaddingAtStart && (m_Header.flags & ArchiveFlags.BlockInfoNeedPaddingAtStart) != 0)
|
||||||
{
|
{
|
||||||
reader.AlignStream(16);
|
reader.AlignStream(16);
|
||||||
}
|
}
|
||||||
@@ -439,14 +472,18 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
compressedBytesSpan = Mr0kUtils.Decrypt(compressedBytesSpan, (Mr0k)Game);
|
compressedBytesSpan = Mr0kUtils.Decrypt(compressedBytesSpan, (Mr0k)Game);
|
||||||
}
|
}
|
||||||
if (Game.Type.IsOPFP())
|
if (Game.Type.IsUnityCN() && ((int)blockInfo.flags & 0x100) != 0)
|
||||||
{
|
{
|
||||||
OPFPUtils.Decrypt(compressedBytesSpan, reader.FullPath);
|
UnityCN.DecryptBlock(compressedBytes, compressedSize, i);
|
||||||
}
|
}
|
||||||
if (Game.Type.IsNetEase() && i == 0)
|
if (Game.Type.IsNetEase() && i == 0)
|
||||||
{
|
{
|
||||||
NetEaseUtils.Decrypt(compressedBytesSpan);
|
NetEaseUtils.Decrypt(compressedBytesSpan);
|
||||||
}
|
}
|
||||||
|
if (Game.Type.IsOPFP())
|
||||||
|
{
|
||||||
|
OPFPUtils.Decrypt(compressedBytesSpan, reader.FullPath);
|
||||||
|
}
|
||||||
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
var uncompressedSize = (int)blockInfo.uncompressedSize;
|
||||||
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
var uncompressedBytes = BigArrayPool<byte>.Shared.Rent(uncompressedSize);
|
||||||
var uncompressedBytesSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
|
var uncompressedBytesSpan = uncompressedBytes.AsSpan(0, uncompressedSize);
|
||||||
|
|||||||
158
AssetStudio/Crypto/UnityCN.cs
Normal file
158
AssetStudio/Crypto/UnityCN.cs
Normal file
@@ -0,0 +1,158 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public class UnityCN
|
||||||
|
{
|
||||||
|
private const string Signature = "#$unity3dchina!@";
|
||||||
|
|
||||||
|
private static ICryptoTransform Encryptor;
|
||||||
|
|
||||||
|
public byte[] Index = new byte[0x10];
|
||||||
|
public byte[] Sub = new byte[0x10];
|
||||||
|
|
||||||
|
public UnityCN(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 = Convert.FromHexString(entry.Key);
|
||||||
|
|
||||||
|
Encryptor = aes.CreateEncryptor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.Error($"[UnityCN] 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.Slice(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 class 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 = Convert.FromHexString(Key);
|
||||||
|
if (bytes.Length != 0x10)
|
||||||
|
{
|
||||||
|
Logger.Warning($"[UnityCN] {this} has invalid key, size should be 16 bytes, skipping...");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() => $"{Name} ({Key})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ namespace AssetStudio
|
|||||||
{
|
{
|
||||||
int index = 0;
|
int index = 0;
|
||||||
Games.Add(index++, new(GameType.Normal));
|
Games.Add(index++, new(GameType.Normal));
|
||||||
|
Games.Add(index++, new(GameType.UnityCN));
|
||||||
Games.Add(index++, new Mhy0(GameType.GI, GIMhy0ShiftRow, GIMhy0Key, GIMhy0Mul, GIExpansionKey, GISBox, GIInitVector, GIInitSeed));
|
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_Pack, PackExpansionKey, blockKey: PackBlockKey));
|
||||||
Games.Add(index++, new Mr0k(GameType.GI_CB1));
|
Games.Add(index++, new Mr0k(GameType.GI_CB1));
|
||||||
@@ -116,6 +117,7 @@ namespace AssetStudio
|
|||||||
public enum GameType
|
public enum GameType
|
||||||
{
|
{
|
||||||
Normal,
|
Normal,
|
||||||
|
UnityCN,
|
||||||
GI,
|
GI,
|
||||||
GI_Pack,
|
GI_Pack,
|
||||||
GI_CB1,
|
GI_CB1,
|
||||||
@@ -142,6 +144,7 @@ namespace AssetStudio
|
|||||||
public static class GameTypes
|
public static class GameTypes
|
||||||
{
|
{
|
||||||
public static bool IsNormal(this GameType type) => type == GameType.Normal;
|
public static bool IsNormal(this GameType type) => type == GameType.Normal;
|
||||||
|
public static bool IsUnityCN(this GameType type) => type == GameType.UnityCN;
|
||||||
public static bool IsGI(this GameType type) => type == GameType.GI;
|
public static bool IsGI(this GameType type) => type == GameType.GI;
|
||||||
public static bool IsGIPack(this GameType type) => type == GameType.GI_Pack;
|
public static bool IsGIPack(this GameType type) => type == GameType.GI_Pack;
|
||||||
public static bool IsGICB1(this GameType type) => type == GameType.GI_CB1;
|
public static bool IsGICB1(this GameType type) => type == GameType.GI_CB1;
|
||||||
|
|||||||
86
AssetStudio/Keys.json
Normal file
86
AssetStudio/Keys.json
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"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"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Dynasty Legends 2",
|
||||||
|
"Key": "746169686567616D6573323032323032"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Evernight CN",
|
||||||
|
"Key": "68687878747478736868787874747873"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Xintianlong Babu",
|
||||||
|
"Key": "61323562623133346363326464333265"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Name": "Frostpunk: Beyond the Ice",
|
||||||
|
"Key": "7368756978696E673838383838383838"
|
||||||
|
}
|
||||||
|
]
|
||||||
74
AssetStudio/UnityCNManager.cs
Normal file
74
AssetStudio/UnityCNManager.cs
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace AssetStudio
|
||||||
|
{
|
||||||
|
public static class UnityCNManager
|
||||||
|
{
|
||||||
|
public const string KeysFileName = "Keys.json";
|
||||||
|
|
||||||
|
private static List<UnityCN.Entry> Entries = new List<UnityCN.Entry>();
|
||||||
|
|
||||||
|
static UnityCNManager()
|
||||||
|
{
|
||||||
|
var str = File.ReadAllText(KeysFileName);
|
||||||
|
Entries = JsonConvert.DeserializeObject<List<UnityCN.Entry>>(str);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SaveEntries(List<UnityCN.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 unityCN))
|
||||||
|
{
|
||||||
|
if (UnityCN.SetKey(unityCN))
|
||||||
|
{
|
||||||
|
Logger.Info($"[UnityCN] Selected Key is {unityCN}");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Info($"[UnityCN] No Key is selected !!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Logger.Error("Invalid Key !!");
|
||||||
|
Logger.Warning(GetEntries().Select(x => x.ToString()).ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool TryGetEntry(int index, out UnityCN.Entry key)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (index < 0 || index > Entries.Count)
|
||||||
|
{
|
||||||
|
throw new ArgumentOutOfRangeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
key = Entries[index];
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
Logger.Error($"[UnityCN] Invalid Index, check if list is not empty !!\n{e.Message}");
|
||||||
|
key = null;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
public static UnityCN.Entry[] GetEntries() => Entries.ToArray();
|
||||||
|
|
||||||
|
public new static string ToString() => string.Join("\n", GetEntries().Select((x, i) => $"{i}: {x.Name}"));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ namespace AssetStudioCLI
|
|||||||
optionsBinder.NameFilter,
|
optionsBinder.NameFilter,
|
||||||
optionsBinder.ContainerFilter,
|
optionsBinder.ContainerFilter,
|
||||||
optionsBinder.GameName,
|
optionsBinder.GameName,
|
||||||
|
optionsBinder.KeyIndex,
|
||||||
optionsBinder.MapOp,
|
optionsBinder.MapOp,
|
||||||
optionsBinder.MapType,
|
optionsBinder.MapType,
|
||||||
optionsBinder.MapName,
|
optionsBinder.MapName,
|
||||||
@@ -50,6 +51,7 @@ namespace AssetStudioCLI
|
|||||||
public Regex[] NameFilter { get; set; }
|
public Regex[] NameFilter { get; set; }
|
||||||
public Regex[] ContainerFilter { get; set; }
|
public Regex[] ContainerFilter { get; set; }
|
||||||
public string GameName { get; set; }
|
public string GameName { get; set; }
|
||||||
|
public int KeyIndex { get; set; }
|
||||||
public MapOpType MapOp { get; set; }
|
public MapOpType MapOp { get; set; }
|
||||||
public ExportListType MapType { get; set; }
|
public ExportListType MapType { get; set; }
|
||||||
public string MapName { get; set; }
|
public string MapName { get; set; }
|
||||||
@@ -69,6 +71,7 @@ namespace AssetStudioCLI
|
|||||||
public readonly Option<Regex[]> NameFilter;
|
public readonly Option<Regex[]> NameFilter;
|
||||||
public readonly Option<Regex[]> ContainerFilter;
|
public readonly Option<Regex[]> ContainerFilter;
|
||||||
public readonly Option<string> GameName;
|
public readonly Option<string> GameName;
|
||||||
|
public readonly Option<int> KeyIndex;
|
||||||
public readonly Option<MapOpType> MapOp;
|
public readonly Option<MapOpType> MapOp;
|
||||||
public readonly Option<ExportListType> MapType;
|
public readonly Option<ExportListType> MapType;
|
||||||
public readonly Option<string> MapName;
|
public readonly Option<string> MapName;
|
||||||
@@ -88,6 +91,7 @@ namespace AssetStudioCLI
|
|||||||
NameFilter = new Option<Regex[]>("--names", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify name regex filter(s).") { AllowMultipleArgumentsPerToken = true };
|
NameFilter = new Option<Regex[]>("--names", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify name regex filter(s).") { AllowMultipleArgumentsPerToken = true };
|
||||||
ContainerFilter = new Option<Regex[]>("--containers", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify container regex filter(s).") { AllowMultipleArgumentsPerToken = true };
|
ContainerFilter = new Option<Regex[]>("--containers", result => result.Tokens.Select(x => new Regex(x.Value, RegexOptions.IgnoreCase)).ToArray(), false, "Specify container regex filter(s).") { AllowMultipleArgumentsPerToken = true };
|
||||||
GameName = new Option<string>("--game", $"Specify Game.") { IsRequired = true };
|
GameName = new Option<string>("--game", $"Specify Game.") { IsRequired = true };
|
||||||
|
KeyIndex = new Option<int>("--key_index", "Specify key index.") { ArgumentHelpName = UnityCNManager.ToString() };
|
||||||
MapOp = new Option<MapOpType>("--map_op", "Specify which map to build.");
|
MapOp = new Option<MapOpType>("--map_op", "Specify which map to build.");
|
||||||
MapType = new Option<ExportListType>("--map_type", "AssetMap output type.");
|
MapType = new Option<ExportListType>("--map_type", "AssetMap output type.");
|
||||||
MapName = new Option<string>("--map_name", () => "assets_map", "Specify AssetMap file name.");
|
MapName = new Option<string>("--map_name", () => "assets_map", "Specify AssetMap file name.");
|
||||||
@@ -141,6 +145,7 @@ namespace AssetStudioCLI
|
|||||||
GroupAssetsType.SetDefaultValue(AssetGroupOption.ByType);
|
GroupAssetsType.SetDefaultValue(AssetGroupOption.ByType);
|
||||||
MapOp.SetDefaultValue(MapOpType.None);
|
MapOp.SetDefaultValue(MapOpType.None);
|
||||||
MapType.SetDefaultValue(ExportListType.XML);
|
MapType.SetDefaultValue(ExportListType.XML);
|
||||||
|
KeyIndex.SetDefaultValue(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FilterValidator(OptionResult result)
|
public void FilterValidator(OptionResult result)
|
||||||
@@ -174,6 +179,7 @@ namespace AssetStudioCLI
|
|||||||
NameFilter = bindingContext.ParseResult.GetValueForOption(NameFilter),
|
NameFilter = bindingContext.ParseResult.GetValueForOption(NameFilter),
|
||||||
ContainerFilter = bindingContext.ParseResult.GetValueForOption(ContainerFilter),
|
ContainerFilter = bindingContext.ParseResult.GetValueForOption(ContainerFilter),
|
||||||
GameName = bindingContext.ParseResult.GetValueForOption(GameName),
|
GameName = bindingContext.ParseResult.GetValueForOption(GameName),
|
||||||
|
KeyIndex = bindingContext.ParseResult.GetValueForOption(KeyIndex),
|
||||||
MapOp = bindingContext.ParseResult.GetValueForOption(MapOp),
|
MapOp = bindingContext.ParseResult.GetValueForOption(MapOp),
|
||||||
MapType = bindingContext.ParseResult.GetValueForOption(MapType),
|
MapType = bindingContext.ParseResult.GetValueForOption(MapType),
|
||||||
MapName = bindingContext.ParseResult.GetValueForOption(MapName),
|
MapName = bindingContext.ParseResult.GetValueForOption(MapName),
|
||||||
|
|||||||
@@ -25,6 +25,19 @@ namespace AssetStudioCLI
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (game.Type.IsUnityCN())
|
||||||
|
{
|
||||||
|
if (!UnityCNManager.TryGetEntry(o.KeyIndex, out var unityCN))
|
||||||
|
{
|
||||||
|
Console.WriteLine("Invalid key index !!");
|
||||||
|
Console.WriteLine($"Available Options: \n{UnityCNManager.ToString()}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
UnityCN.SetKey(unityCN);
|
||||||
|
Logger.Info($"[UnityCN] Selected Key is {unityCN}");
|
||||||
|
}
|
||||||
|
|
||||||
Studio.Game = game;
|
Studio.Game = game;
|
||||||
Logger.Default = new ConsoleLogger();
|
Logger.Default = new ConsoleLogger();
|
||||||
AssetsHelper.Minimal = Settings.Default.minimalAssetMap;
|
AssetsHelper.Minimal = Settings.Default.minimalAssetMap;
|
||||||
|
|||||||
@@ -109,6 +109,9 @@
|
|||||||
<setting name="enableModelPreview" serializeAs="String">
|
<setting name="enableModelPreview" serializeAs="String">
|
||||||
<value>False</value>
|
<value>False</value>
|
||||||
</setting>
|
</setting>
|
||||||
|
<setting name="selectedUnityCNKey" serializeAs="String">
|
||||||
|
<value>0</value>
|
||||||
|
</setting>
|
||||||
</AssetStudioGUI.Properties.Settings>
|
</AssetStudioGUI.Properties.Settings>
|
||||||
</userSettings>
|
</userSettings>
|
||||||
</configuration>
|
</configuration>
|
||||||
69
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
69
AssetStudioGUI/AssetStudioGUIForm.Designer.cs
generated
@@ -44,12 +44,15 @@ namespace AssetStudioGUI
|
|||||||
abortStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
abortStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
optionsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
displayAll = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
enablePreview = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
enableModelPreview = new System.Windows.Forms.ToolStripMenuItem();
|
enableModelPreview = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
modelsOnly = new System.Windows.Forms.ToolStripMenuItem();
|
modelsOnly = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
|
toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
|
displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
enableResolveDependencies = new System.Windows.Forms.ToolStripMenuItem();
|
enableResolveDependencies = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
skipContainer = new System.Windows.Forms.ToolStripMenuItem();
|
skipContainer = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
displayInfo = new System.Windows.Forms.ToolStripMenuItem();
|
toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
toolStripMenuItem14 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
specifyUnityVersion = new System.Windows.Forms.ToolStripTextBox();
|
||||||
toolStripMenuItem18 = new System.Windows.Forms.ToolStripMenuItem();
|
toolStripMenuItem18 = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
@@ -164,9 +167,8 @@ namespace AssetStudioGUI
|
|||||||
exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
exportAnimatorwithselectedAnimationClipMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
goToSceneHierarchyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
showOriginalFileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
toolStripSeparator10 = new System.Windows.Forms.ToolStripSeparator();
|
specifyUnityCNKey = new System.Windows.Forms.ToolStripMenuItem();
|
||||||
toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
|
toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
|
||||||
toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
|
|
||||||
menuStrip1.SuspendLayout();
|
menuStrip1.SuspendLayout();
|
||||||
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
((System.ComponentModel.ISupportInitialize)splitContainer1).BeginInit();
|
||||||
splitContainer1.Panel1.SuspendLayout();
|
splitContainer1.Panel1.SuspendLayout();
|
||||||
@@ -258,7 +260,7 @@ namespace AssetStudioGUI
|
|||||||
//
|
//
|
||||||
// optionsToolStripMenuItem
|
// optionsToolStripMenuItem
|
||||||
//
|
//
|
||||||
optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { displayAll, toolStripSeparator10, enablePreview, enableModelPreview, modelsOnly, toolStripSeparator11, displayInfo, enableResolveDependencies, skipContainer, toolStripSeparator12, toolStripMenuItem14, toolStripMenuItem18, toolStripMenuItem19, showExpOpt });
|
optionsToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] { displayAll, toolStripSeparator10, enablePreview, enableModelPreview, modelsOnly, toolStripSeparator11, displayInfo, enableResolveDependencies, skipContainer, toolStripSeparator12, toolStripMenuItem14, specifyUnityCNKey, toolStripSeparator13, toolStripMenuItem18, toolStripMenuItem19, showExpOpt });
|
||||||
optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
optionsToolStripMenuItem.Name = "optionsToolStripMenuItem";
|
||||||
optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
|
optionsToolStripMenuItem.Size = new System.Drawing.Size(61, 20);
|
||||||
optionsToolStripMenuItem.Text = "Options";
|
optionsToolStripMenuItem.Text = "Options";
|
||||||
@@ -272,6 +274,11 @@ namespace AssetStudioGUI
|
|||||||
displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can export the RAW file.";
|
displayAll.ToolTipText = "Check this option will display all types assets. Not extractable assets can export the RAW file.";
|
||||||
displayAll.CheckedChanged += displayAll_CheckedChanged;
|
displayAll.CheckedChanged += displayAll_CheckedChanged;
|
||||||
//
|
//
|
||||||
|
// toolStripSeparator10
|
||||||
|
//
|
||||||
|
toolStripSeparator10.Name = "toolStripSeparator10";
|
||||||
|
toolStripSeparator10.Size = new System.Drawing.Size(222, 6);
|
||||||
|
//
|
||||||
// enablePreview
|
// enablePreview
|
||||||
//
|
//
|
||||||
enablePreview.Checked = true;
|
enablePreview.Checked = true;
|
||||||
@@ -299,6 +306,22 @@ namespace AssetStudioGUI
|
|||||||
modelsOnly.Text = "Filter models only";
|
modelsOnly.Text = "Filter models only";
|
||||||
modelsOnly.CheckedChanged += modelsOnly_CheckedChanged;
|
modelsOnly.CheckedChanged += modelsOnly_CheckedChanged;
|
||||||
//
|
//
|
||||||
|
// toolStripSeparator11
|
||||||
|
//
|
||||||
|
toolStripSeparator11.Name = "toolStripSeparator11";
|
||||||
|
toolStripSeparator11.Size = new System.Drawing.Size(222, 6);
|
||||||
|
//
|
||||||
|
// displayInfo
|
||||||
|
//
|
||||||
|
displayInfo.Checked = true;
|
||||||
|
displayInfo.CheckOnClick = true;
|
||||||
|
displayInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
||||||
|
displayInfo.Name = "displayInfo";
|
||||||
|
displayInfo.Size = new System.Drawing.Size(225, 22);
|
||||||
|
displayInfo.Text = "Display asset information";
|
||||||
|
displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, format, audio bitrate, etc.";
|
||||||
|
displayInfo.CheckedChanged += displayAssetInfo_Check;
|
||||||
|
//
|
||||||
// enableResolveDependencies
|
// enableResolveDependencies
|
||||||
//
|
//
|
||||||
enableResolveDependencies.Checked = true;
|
enableResolveDependencies.Checked = true;
|
||||||
@@ -316,20 +339,13 @@ namespace AssetStudioGUI
|
|||||||
skipContainer.Name = "skipContainer";
|
skipContainer.Name = "skipContainer";
|
||||||
skipContainer.Size = new System.Drawing.Size(225, 22);
|
skipContainer.Size = new System.Drawing.Size(225, 22);
|
||||||
skipContainer.Text = "Skip container recovery";
|
skipContainer.Text = "Skip container recovery";
|
||||||
skipContainer.ToolTipText = "Skips the container recovery step.\nImproves loading when dealing with a large num" +
|
skipContainer.ToolTipText = "Skips the container recovery step.\nImproves loading when dealing with a large number of files.";
|
||||||
"ber of files.";
|
|
||||||
skipContainer.CheckedChanged += skipContainer_CheckedChanged;
|
skipContainer.CheckedChanged += skipContainer_CheckedChanged;
|
||||||
//
|
//
|
||||||
// displayInfo
|
// toolStripSeparator12
|
||||||
//
|
//
|
||||||
displayInfo.Checked = true;
|
toolStripSeparator12.Name = "toolStripSeparator12";
|
||||||
displayInfo.CheckOnClick = true;
|
toolStripSeparator12.Size = new System.Drawing.Size(222, 6);
|
||||||
displayInfo.CheckState = System.Windows.Forms.CheckState.Checked;
|
|
||||||
displayInfo.Name = "displayInfo";
|
|
||||||
displayInfo.Size = new System.Drawing.Size(225, 22);
|
|
||||||
displayInfo.Text = "Display asset information";
|
|
||||||
displayInfo.ToolTipText = "Toggle the overlay that shows information about each asset, eg. image size, format, audio bitrate, etc.";
|
|
||||||
displayInfo.CheckedChanged += displayAssetInfo_Check;
|
|
||||||
//
|
//
|
||||||
// toolStripMenuItem14
|
// toolStripMenuItem14
|
||||||
//
|
//
|
||||||
@@ -1292,20 +1308,17 @@ namespace AssetStudioGUI
|
|||||||
showOriginalFileToolStripMenuItem.Visible = false;
|
showOriginalFileToolStripMenuItem.Visible = false;
|
||||||
showOriginalFileToolStripMenuItem.Click += showOriginalFileToolStripMenuItem_Click;
|
showOriginalFileToolStripMenuItem.Click += showOriginalFileToolStripMenuItem_Click;
|
||||||
//
|
//
|
||||||
// toolStripSeparator10
|
// specifyUnityCNKey
|
||||||
//
|
//
|
||||||
toolStripSeparator10.Name = "toolStripSeparator10";
|
specifyUnityCNKey.Name = "specifyUnityCNKey";
|
||||||
toolStripSeparator10.Size = new System.Drawing.Size(222, 6);
|
specifyUnityCNKey.Size = new System.Drawing.Size(225, 22);
|
||||||
|
specifyUnityCNKey.Text = "Specify UnityCN Key";
|
||||||
|
specifyUnityCNKey.Click += specifyUnityCNKey_Click;
|
||||||
//
|
//
|
||||||
// toolStripSeparator11
|
// toolStripSeparator13
|
||||||
//
|
//
|
||||||
toolStripSeparator11.Name = "toolStripSeparator11";
|
toolStripSeparator13.Name = "toolStripSeparator13";
|
||||||
toolStripSeparator11.Size = new System.Drawing.Size(222, 6);
|
toolStripSeparator13.Size = new System.Drawing.Size(222, 6);
|
||||||
//
|
|
||||||
// toolStripSeparator12
|
|
||||||
//
|
|
||||||
toolStripSeparator12.Name = "toolStripSeparator12";
|
|
||||||
toolStripSeparator12.Size = new System.Drawing.Size(222, 6);
|
|
||||||
//
|
//
|
||||||
// AssetStudioGUIForm
|
// AssetStudioGUIForm
|
||||||
//
|
//
|
||||||
@@ -1491,6 +1504,8 @@ namespace AssetStudioGUI
|
|||||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator10;
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator11;
|
||||||
private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator12;
|
||||||
|
private System.Windows.Forms.ToolStripMenuItem specifyUnityCNKey;
|
||||||
|
private System.Windows.Forms.ToolStripSeparator toolStripSeparator13;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -157,6 +157,7 @@ namespace AssetStudioGUI
|
|||||||
Logger.Info($"Target Game type is {Studio.Game.Type}");
|
Logger.Info($"Target Game type is {Studio.Game.Type}");
|
||||||
|
|
||||||
MapNameComboBox.SelectedIndexChanged += new EventHandler(specifyNameComboBox_SelectedIndexChanged);
|
MapNameComboBox.SelectedIndexChanged += new EventHandler(specifyNameComboBox_SelectedIndexChanged);
|
||||||
|
UnityCNManager.SetKey(Properties.Settings.Default.selectedUnityCNKey);
|
||||||
}
|
}
|
||||||
private void AssetStudioGUIForm_DragEnter(object sender, DragEventArgs e)
|
private void AssetStudioGUIForm_DragEnter(object sender, DragEventArgs e)
|
||||||
{
|
{
|
||||||
@@ -274,6 +275,10 @@ namespace AssetStudioGUI
|
|||||||
{
|
{
|
||||||
productName = Studio.Game.Name;
|
productName = Studio.Game.Name;
|
||||||
}
|
}
|
||||||
|
else if (Studio.Game.Type.IsUnityCN() && UnityCNManager.TryGetEntry(Properties.Settings.Default.selectedUnityCNKey, out var unityCN))
|
||||||
|
{
|
||||||
|
productName = unityCN.Name;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
productName = "no productName";
|
productName = "no productName";
|
||||||
@@ -2300,6 +2305,12 @@ namespace AssetStudioGUI
|
|||||||
assetBrowser.Show();
|
assetBrowser.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void specifyUnityCNKey_Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
|
var unitycn = new UnityCNForm();
|
||||||
|
unitycn.Show();
|
||||||
|
}
|
||||||
|
|
||||||
#region FMOD
|
#region FMOD
|
||||||
private void FMODinit()
|
private void FMODinit()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -120,9 +120,6 @@
|
|||||||
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="menuStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>312, 17</value>
|
<value>312, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
|
||||||
<value>432, 17</value>
|
|
||||||
</metadata>
|
|
||||||
<data name="fontPreviewBox.Text" xml:space="preserve">
|
<data name="fontPreviewBox.Text" xml:space="preserve">
|
||||||
<value>abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWYZ
|
<value>abcdefghijklmnopqrstuvwxyz ABCDEFGHIJKLMNOPQRSTUVWYZ
|
||||||
1234567890.:,;'\"(!?)+-*/=
|
1234567890.:,;'\"(!?)+-*/=
|
||||||
@@ -141,6 +138,9 @@ The quick brown fox jumps over the lazy dog. 1234567890
|
|||||||
|
|
||||||
The quick brown fox jumps over the lazy dog. 1234567890</value>
|
The quick brown fox jumps over the lazy dog. 1234567890</value>
|
||||||
</data>
|
</data>
|
||||||
|
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
|
<value>432, 17</value>
|
||||||
|
</metadata>
|
||||||
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="timer.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>553, 17</value>
|
<value>553, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|||||||
@@ -120,6 +120,12 @@
|
|||||||
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="exportUvsTooltip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>17, 17</value>
|
<value>17, 17</value>
|
||||||
</metadata>
|
</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">
|
<metadata name="keyToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>162, 17</value>
|
<value>162, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
@@ -129,6 +135,9 @@
|
|||||||
<metadata name="resolveToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
<metadata name="resolveToolTip.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
|
||||||
<value>273, 17</value>
|
<value>273, 17</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
<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="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
<metadata name="$this.TrayHeight" type="System.Int32, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||||
<value>57</value>
|
<value>57</value>
|
||||||
</metadata>
|
</metadata>
|
||||||
|
|||||||
13
AssetStudioGUI/Properties/Settings.Designer.cs
generated
13
AssetStudioGUI/Properties/Settings.Designer.cs
generated
@@ -12,7 +12,7 @@ namespace AssetStudioGUI.Properties {
|
|||||||
|
|
||||||
|
|
||||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.5.0.0")]
|
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.6.0.0")]
|
||||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||||
|
|
||||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||||
@@ -442,5 +442,16 @@ namespace AssetStudioGUI.Properties {
|
|||||||
this["enableModelPreview"] = value;
|
this["enableModelPreview"] = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||||
|
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||||
|
[global::System.Configuration.DefaultSettingValueAttribute("0")]
|
||||||
|
public int selectedUnityCNKey {
|
||||||
|
get {
|
||||||
|
return ((int)(this["selectedUnityCNKey"]));
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
this["selectedUnityCNKey"] = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,5 +107,8 @@
|
|||||||
<Setting Name="enableModelPreview" Type="System.Boolean" Scope="User">
|
<Setting Name="enableModelPreview" Type="System.Boolean" Scope="User">
|
||||||
<Value Profile="(Default)">False</Value>
|
<Value Profile="(Default)">False</Value>
|
||||||
</Setting>
|
</Setting>
|
||||||
|
<Setting Name="selectedUnityCNKey" Type="System.Int32" Scope="User">
|
||||||
|
<Value Profile="(Default)">0</Value>
|
||||||
|
</Setting>
|
||||||
</Settings>
|
</Settings>
|
||||||
</SettingsFile>
|
</SettingsFile>
|
||||||
94
AssetStudioGUI/UnityCNForm.Designer.cs
generated
Normal file
94
AssetStudioGUI/UnityCNForm.Designer.cs
generated
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
namespace AssetStudioGUI
|
||||||
|
{
|
||||||
|
partial class UnityCNForm
|
||||||
|
{
|
||||||
|
/// <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.specifyUnityCNList = new System.Windows.Forms.DataGridView();
|
||||||
|
this.NameField = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
this.KeyField = new System.Windows.Forms.DataGridViewTextBoxColumn();
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.specifyUnityCNList)).BeginInit();
|
||||||
|
this.SuspendLayout();
|
||||||
|
//
|
||||||
|
// specifyUnityCNList
|
||||||
|
//
|
||||||
|
this.specifyUnityCNList.AllowUserToResizeColumns = false;
|
||||||
|
this.specifyUnityCNList.AllowUserToResizeRows = false;
|
||||||
|
this.specifyUnityCNList.ClipboardCopyMode = System.Windows.Forms.DataGridViewClipboardCopyMode.EnableWithoutHeaderText;
|
||||||
|
this.specifyUnityCNList.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
|
||||||
|
this.specifyUnityCNList.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
|
||||||
|
this.NameField,
|
||||||
|
this.KeyField});
|
||||||
|
this.specifyUnityCNList.Dock = System.Windows.Forms.DockStyle.Fill;
|
||||||
|
this.specifyUnityCNList.Location = new System.Drawing.Point(0, 0);
|
||||||
|
this.specifyUnityCNList.MultiSelect = false;
|
||||||
|
this.specifyUnityCNList.Name = "specifyUnityCNList";
|
||||||
|
this.specifyUnityCNList.RowHeadersWidthSizeMode = System.Windows.Forms.DataGridViewRowHeadersWidthSizeMode.DisableResizing;
|
||||||
|
this.specifyUnityCNList.RowTemplate.Height = 25;
|
||||||
|
this.specifyUnityCNList.Size = new System.Drawing.Size(408, 204);
|
||||||
|
this.specifyUnityCNList.TabIndex = 0;
|
||||||
|
this.specifyUnityCNList.RowHeaderMouseDoubleClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.specifyUnityCNList_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";
|
||||||
|
//
|
||||||
|
// UnityCNForm
|
||||||
|
//
|
||||||
|
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
|
||||||
|
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
|
||||||
|
this.ClientSize = new System.Drawing.Size(408, 204);
|
||||||
|
this.Controls.Add(this.specifyUnityCNList);
|
||||||
|
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.Fixed3D;
|
||||||
|
this.MaximizeBox = false;
|
||||||
|
this.MinimizeBox = false;
|
||||||
|
this.Name = "UnityCNForm";
|
||||||
|
this.ShowIcon = false;
|
||||||
|
this.ShowInTaskbar = false;
|
||||||
|
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
|
||||||
|
this.Text = "UnityCNForm";
|
||||||
|
this.TopMost = true;
|
||||||
|
((System.ComponentModel.ISupportInitialize)(this.specifyUnityCNList)).EndInit();
|
||||||
|
this.ResumeLayout(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
private System.Windows.Forms.DataGridView specifyUnityCNList;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn NameField;
|
||||||
|
private System.Windows.Forms.DataGridViewTextBoxColumn KeyField;
|
||||||
|
}
|
||||||
|
}
|
||||||
77
AssetStudioGUI/UnityCNForm.cs
Normal file
77
AssetStudioGUI/UnityCNForm.cs
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using AssetStudio;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
|
namespace AssetStudioGUI
|
||||||
|
{
|
||||||
|
public partial class UnityCNForm : Form
|
||||||
|
{
|
||||||
|
public UnityCNForm()
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
var keys = UnityCNManager.GetEntries();
|
||||||
|
|
||||||
|
for (int i = 0; i < keys.Length; i++)
|
||||||
|
{
|
||||||
|
var key = keys[i];
|
||||||
|
var rowIdx = specifyUnityCNList.Rows.Add();
|
||||||
|
|
||||||
|
specifyUnityCNList.Rows[rowIdx].Cells["NameField"].Value = key.Name;
|
||||||
|
specifyUnityCNList.Rows[rowIdx].Cells["KeyField"].Value = key.Key;
|
||||||
|
}
|
||||||
|
|
||||||
|
var index = Properties.Settings.Default.selectedUnityCNKey;
|
||||||
|
if (index >= specifyUnityCNList.RowCount)
|
||||||
|
{
|
||||||
|
index = 0;
|
||||||
|
}
|
||||||
|
specifyUnityCNList.CurrentCell = specifyUnityCNList.Rows[index].Cells[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
private void specifyUnityCNList_RowHeaderMouseDoubleClick(object sender, DataGridViewCellMouseEventArgs e)
|
||||||
|
{
|
||||||
|
var keys = new List<UnityCN.Entry>();
|
||||||
|
for (int i = specifyUnityCNList.Rows.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var row = specifyUnityCNList.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 unityCN = new UnityCN.Entry(name, key);
|
||||||
|
|
||||||
|
if (unityCN.Validate())
|
||||||
|
{
|
||||||
|
keys.Add(unityCN);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (specifyUnityCNList.CurrentCell.RowIndex == row.Index)
|
||||||
|
{
|
||||||
|
var previousRow = specifyUnityCNList.Rows.Cast<DataGridViewRow>().ElementAtOrDefault(i - 1);
|
||||||
|
if (previousRow != null)
|
||||||
|
{
|
||||||
|
specifyUnityCNList.CurrentCell = previousRow.Cells[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i != specifyUnityCNList.RowCount - 1)
|
||||||
|
{
|
||||||
|
specifyUnityCNList.Rows.RemoveAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UnityCNManager.SaveEntries(keys.Reverse<UnityCN.Entry>().ToList());
|
||||||
|
UnityCNManager.SetKey(specifyUnityCNList.CurrentRow.Index);
|
||||||
|
|
||||||
|
Properties.Settings.Default.selectedUnityCNKey = specifyUnityCNList.CurrentRow.Index;
|
||||||
|
Properties.Settings.Default.Save();
|
||||||
|
|
||||||
|
DialogResult = DialogResult.OK;
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
126
AssetStudioGUI/UnityCNForm.resx
Normal file
126
AssetStudioGUI/UnityCNForm.resx
Normal file
@@ -0,0 +1,126 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<root>
|
||||||
|
<!--
|
||||||
|
Microsoft ResX Schema
|
||||||
|
|
||||||
|
Version 2.0
|
||||||
|
|
||||||
|
The primary goals of this format is to allow a simple XML format
|
||||||
|
that is mostly human readable. The generation and parsing of the
|
||||||
|
various data types are done through the TypeConverter classes
|
||||||
|
associated with the data types.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
... ado.net/XML headers & schema ...
|
||||||
|
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||||
|
<resheader name="version">2.0</resheader>
|
||||||
|
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||||
|
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||||
|
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||||
|
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||||
|
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||||
|
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||||
|
</data>
|
||||||
|
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||||
|
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||||
|
<comment>This is a comment</comment>
|
||||||
|
</data>
|
||||||
|
|
||||||
|
There are any number of "resheader" rows that contain simple
|
||||||
|
name/value pairs.
|
||||||
|
|
||||||
|
Each data row contains a name, and value. The row also contains a
|
||||||
|
type or mimetype. Type corresponds to a .NET class that support
|
||||||
|
text/value conversion through the TypeConverter architecture.
|
||||||
|
Classes that don't support this are serialized and stored with the
|
||||||
|
mimetype set.
|
||||||
|
|
||||||
|
The mimetype is used for serialized objects, and tells the
|
||||||
|
ResXResourceReader how to depersist the object. This is currently not
|
||||||
|
extensible. For a given mimetype the value must be set accordingly:
|
||||||
|
|
||||||
|
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||||
|
that the ResXResourceWriter will generate, however the reader can
|
||||||
|
read any of the formats listed below.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.binary.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.soap.base64
|
||||||
|
value : The object must be serialized with
|
||||||
|
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
|
||||||
|
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||||
|
value : The object must be serialized into a byte array
|
||||||
|
: using a System.ComponentModel.TypeConverter
|
||||||
|
: and then encoded with base64 encoding.
|
||||||
|
-->
|
||||||
|
<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>
|
||||||
Reference in New Issue
Block a user