diff --git a/ArcFormats/ArcFormats.csproj b/ArcFormats/ArcFormats.csproj index e26c3db1..a34e7b66 100644 --- a/ArcFormats/ArcFormats.csproj +++ b/ArcFormats/ArcFormats.csproj @@ -142,6 +142,7 @@ + diff --git a/ArcFormats/KiriKiri/MoreCrypt.cs b/ArcFormats/KiriKiri/MoreCrypt.cs new file mode 100644 index 00000000..ab9f8401 --- /dev/null +++ b/ArcFormats/KiriKiri/MoreCrypt.cs @@ -0,0 +1,111 @@ +//! \file MoreCrypt.cs +//! \date 2018 Jan 24 +//! \brief PureMore/More filename scrambling scheme. +// +// Copyright (C) 2018 by morkt +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to +// deal in the Software without restriction, including without limitation the +// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +// sell copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +// + +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Runtime.Serialization; +using System.Security.Cryptography; +using System.Text; + +namespace GameRes.Formats.KiriKiri +{ + [Serializable] + public class PureMoreCrypt : NoCrypt + { + public string FileListName { get; set; } + + [NonSerialized] + Lazy> KnownNames; + + public PureMoreCrypt () + { + KnownNames = new Lazy> (ReadFileList); + } + + [OnDeserialized()] + void PostDeserialization (StreamingContext context) + { + KnownNames = new Lazy> (ReadFileList); + } + + public override string ReadName (BinaryReader header) + { + var name = base.ReadName (header); + if (null == name || name.Length != 36 || !name.HasExtension (".tlg")) + return name; + string mapped_name; + if (KnownNames.Value.TryGetValue (name, out mapped_name)) + name = mapped_name; + return name; + } + + Dictionary ReadFileList () + { + var dict = new Dictionary(); + if (string.IsNullOrEmpty (FileListName)) + return dict; + try + { + using (var sha = SHA256.Create()) + { + var str = new StringBuilder (36); + var bytes = new byte[0x100]; + FormatCatalog.Instance.ReadFileList (FileListName, name => { + int ext = name.LastIndexOf ('.'); + if (-1 == ext) + ext = name.Length; + int len = Encoding.Unicode.GetBytes (name, 0, ext, bytes, 0); + var hash = sha.ComputeHash (bytes, 0, len); + str.Clear(); + foreach (byte b in hash) + { + str.Append (CharMap[b]); + } + str.Append (".tlg"); + dict[str.ToString()] = name; + }); + } + } + catch (Exception X) + { + System.Diagnostics.Trace.WriteLine (X.Message, "[PureMoreCrypt]"); + } + return dict; + } + + [NonSerialized] + static readonly string CharMap = + "0123456789abcdefghijklmnopqrstuvwxyz"+ + "0123456789abcdefghijklmnopqrstuvwxyz"+ + "ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただ"+ + "ちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむ"+ + "めもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキ"+ + "ギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネ"+ + "ノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロ"+ + "ヮワヰヱヲンヴヵヶ零一二三四五六七八九十百千万億"; + } +}