雑用担当の備忘録

技術的な話のみになります。翻訳データそのものはありません。 カテゴリ>その他>注意事項を必ず参照してください

カテゴリ:解析 > Unity5

Localization data は StreamingAssets/Localization の下の lsb ファイルです。
lsb ファイルは簡易的ではありますが暗号化されています。
lisbts01
0x00: u16  要素数 (0xB6)
0x02: u32  data 部の位置 (0x1026)
0x06: u8*要素数 key の長さ
0xBC: u16*要素数 data の長さ、開始位置は要素数によって変わる
0x228: 実際のデータ暗号化されている、開始位置は要素数によって変わる
データ部分こんな感じに暗号化されています
lisbts04
復号は

// seed 値
const SEED = [170, 17, 35, 52, 50, 33, 232, 59, 186, 18, 36, 53, 66, 49, 248, 91, 202, 19, 37, 54, 82, 161, 8, 123, 218, 20, 38, 55, 98, 193, 120, 155];

for i in 0..buffer.len() {
    // seed でマスクされているので戻す
    buffer[i] ^= SEED[i % SEED.len()];
}

このような処理で戻ります
復号化したデータが
lisbts02
key が並んでいるのがわかると思います。
data 部分は 0x02: 0x1026 からなので
lisbts03
0x1026 から Not a Meth Lab! というのがあるのがわかると思います。
後は最初に書いていた key の長さと data の長さを見て切り分ければいいだけです
data 部の文字コードは utf-8 です

以下のように取れると思います。
E1_S01_A_CHOICE_S01_026_01    Not a Meth Lab!
E1_S01_A_CHOICE_S01_026_02    Free candy!
E1_S01_A_CHOICE_S01_060_01    February 12.
E1_S01_A_CHOICE_S01_060_02    March 21.
E1_S01_A_CHOICE_S01_060_03    April 1.
E1_S01_A_CHOICE_S01_063_01    1775 Rowan st.
E1_S01_A_CHOICE_S01_063_02    1757 Rowan st.
E1_S01_A_CHOICE_S01_063_03    1575 Rowan st.
E1_S01_A_CHOICE_S01_071_01    The mill.
E1_S01_A_CHOICE_S01_071_02    Your bike.
E1_S01_A_CHOICE_S01_071_03    Let me inside, now.
E1_S01_A_CHOICE_S01_071_04    Walk away.
E1_S01_A_CHOICE_S01_077_01    What could it hurt?
E1_S01_A_CHOICE_S01_077_02    [*]Cute[/*] is relative.
E1_S01_A_CHOICE_S01_077_03    I don't do '[*]cute[/*]'.
E1_S01_A_CHOICE_S01_085_01    This isn't a [*]playground[/*]?
E1_S01_A_CHOICE_S01_085_02    I am not a kid!
E1_S01_A_CHOICE_S01_085_03    Fine. I'll sneak in.
E1_S01_A_CHOICE_S01_093_01    A girl like me?
E1_S01_A_CHOICE_S01_093_02    I'm not worried.
E1_S01_A_CHOICE_S01_093_03    Girls kick ass.
E1_S01_A_CHOICE_S01_093_04    Flowers on your bike?
E1_S01_A_CHOICE_S01_101_01    Who's your boss?

LISの前日譚です
lisbts00
概要:
  • Unity: UEから変わっています、会社が違うからですかね
  • Localization data: StreamingAssets/Localization の下の lsb ファイル

某所に記述した MonoBehaviour に関する解説をまとめておきます
題材は UGCW です。

ターゲットは
resources_00001.-161
resources_00001.-225

-161 は LoadingScreen をシリアライズしたファイル

LoadingScreen は

public class LoadingScreen : MonoBehaviour
{
 public Text tips;
 public Image picture;
 public Text version;
 public float showMinTime;
 public Sprite[] preloadingScreen;
 public LoadingScreen.PreloadingSet[] prelodingSet;
}
public struct LoadingScreen.PreloadingSet
{
 public string text;
}
UGCW01
Text, Image, Sprite はオブジェクトで objID(dword + ddword) で表されます
(0x20~0x23 + 0x24~0x2B)
00 00 00 00 85 FE 01 00 00 00 00 00 が tips の objID になります。
00 00 00 00 BE 03 02 00 00 00 00 00 が picture
00 00 00 00 00 00 00 00 00 00 00 00 が version(Null オブジェクト)

float は dword
0x44~0x47: 00 00 40 40
Little endian なので 0x40400000 になってこの実数値は 3.0
したがって showMinTime = 3.0

ここまでは固定のサイズになりますが
次の Sprite は配列なので可変になります。objID の倍数のサイズになる
0x48: 06 00 00 00
が配列長
従って preloadingScreen[6] になり Sprite の objID は 6 個存在する。
6(dword + ddword) なので 0x4C~0x93 までが preloadingScreen

PreloadingSet も配列なので
0x94 が配列長 0x10A の個数 preloadingSet がある

preloadingSet は string で

string は 文字列長+文字列+padding で構成される。

"AAAAA" の文字列は
05 00 00 00 41 41 41 41 41 00 00 00
と表される

05 00 00 00 の部分が文字列サイズで
41 41 41 41 41 が "AAAAA" の文字コード(utf-8)
00 00 00 は padding

padding が 00 00 00 の3バイトになるのは
41 41 41 41 41 が5バイトなので、4の倍数になるように調整する必要がある(アライメント)
今回は8バイトになるように 5+3 で 00 00 00 の padding が必要になる

"あああああ" の場合は
0F 00 00 00 E3 81 82 E3 81 82 E3 81 82 E3 81 82
E3 81 82 00
と表現され
'あ' の文字コードは E3 81 82 の部分
5(E3 81 82) = 5x3 = 15 = 0xF が文字列サイズ

文字列は 15 なので padding は 16 になるように 00 の1バイトとなる。


-225 のファイルは Language で

public class Language : MonoBehaviour
{
 public Language.LocalizationGroup[] Groups;
}
public class Language.LocalizationGroup
{
 public string[] Keys;
 public string[] Values;
}
UGCW02
Groups.length = 10 で
Groups[0].keys.length = 7 個ある
Groups[0].keys[0] = "OfficerRank_Captain"

Groups[0].values.length = 7 個ある
Groups[0].values[0] = "Captain"

ということです。

font について

SotD は bitmap font です。Unity の bitmap フォントは色々なパターン(NGUI 等)があるのですが今回は標準形の bitmap font で UnityEx 上で font (type 128) のファイル名の拡張子が font_raw で表示されているものです。ttf の方は dynamic font になります。

font_raw:

struct FontRaw {
    ascii_stzrt_offset: i32,
    tracking: f32,
    line_spacing: f32,
    character_spacing: i32,
    character_padding: i32,
    convert_case: i32,
    default_material: ObjId,
    character_rects_size: u32,      // 0 == dynamic font, 0 != bitmap font
    character_rects: Vec<CharacterInfo>,
    texture: ObjId,
    kerning_size: u32,
    kerning: Vec<PairData>,
    pixel_scale: f32,
    font_data_size: u32,            // 0 != dynamic font, 0 == bitmap font
    font_data: Vec<u8>,             // ttf image
    font_size: f32,
    ascent: f32,
    default_style: i32,
    font_name_size: u32,
    font_names: Vec<FontName>,
    fallback_fonts_size: u32,
    fallback_font: Vec<FallbackFont>,
    font_rendering_mode: i32,
}

ここで注目するのは、bitmap font は caracter_rects (座標情報)のデータが存在し dynamic font は font_data (ttf ファイルそのもの) が存在する。
つまり bitmap → dynamic への変換は
character_rects_size = 0;
character_rects はカット
kerning_size = 0;  << kerning はカット
kerning は無し
font_data_size = ttf ファイルサイズ
font_data = ttf ファイルデータと置き換える
とし
convert_case = -2;
とすると dynamic font へ変換されます。
後は、この変換された raw_font データを UnityEx にてインポートすると
SotD_01j
SotD_02j
SotD_03j

と表示されます。
フォントサイズは要調整のような気もするが…

Localization data:

LocalizationUtils にてロードしているのでキャストしている LocalizationTagBundle に注目する。
LocalizationTagBundle は単なる LocalizationTag のコンテナなので LocalizationTag に注目する。

public class LocalizationTag
{
    public int m_Id;
    public string m_Tag;
    public string m_E; // english
    public string m_F;   // french
    public string m_I;    // Italian
    public string m_G;  // German
    public string m_S;  // Spanish
    public string m_P;  // Portuguese
}

なのでこれっぽい。コンテナの方の LocalizationTagBundle で GameObjectID を検索する。
GameObjectID = 1780

resource.assets の MonoBehaviour (type:114) で 1780 にマッチするデータを抽出すると拡張子 -20 のデータだとわかる。(現時点のバージョン。この部分は更新により変動があります。)
-20 の中身を見ると、LocalizationTag があるのがわかります。
文字コードは UTF-8
で上記の情報より編集しやすいようにバイナリ<>テキストツールを作成するとよい。

オリジナル
SotD_01
Localization data 書き換え後
SotD_01e
オリジナル
SotD_02
Localization data 書き換え後
SotD_02e
オリジナル
SotD_03
Localization data 書き換え後
SotD_03e

はい、文字化けしています(表示されていない)。
bitmap フォントを使用しているのですがこれを dynamic フォントに変換すると正常に表示されるようになります。
フォントの話は次回

↑このページのトップヘ