牌譜をファイルに保存するにゃ

Last-modified: 2024-04-17 (水) 20:06:44
 

概要

雀魂の牌譜を簡単にファイル保存する方法にゃ!
普通に保存するだけだと、猫には読めない「バイナリ形式」ファイルになってしまうにゃ!
そこで、猫でも読める「JSON形式」に変換してから保存するにゃ!

 

準備するもの

  • パソコン
  • 雀魂アカウント(ウェブブラウザ版のアカウントで動作確認済みにゃ!DMM版でも動くかは不明にゃ!)
  • ウェブブラウザ(Chrome と Firefox で動作確認したにゃ!)

以上にゃ!

 

保存方法

Chromeを使って解説するにゃ!

 

1. 新しいタブを開くにゃ!
01.png

 

2. デベロッパーツールを起動するにゃ!
起動方法はいろいろあるにゃ!好きな方法を選ぶにゃ!

  • コントロールキーとシフトキーを押しながら「I」(アイ)のキーを押すにゃ!
  • F12キーを押すにゃ!
  • Chromeのメニューの「その他のツール」 → 「デベロッパー ツール」を選択するにゃ!

02.png

 

3. コンソールを表示するにゃ!
03.png
上の画像の赤丸部分をクリックするにゃ!

 

4.雀魂にログインするにゃ!
04.png

 

5. 下記のコードをコンソールにコピペして、エンターキーを押すにゃ!

function paifu(uuid = "") {
    if (!uuid) {
        uuid = prompt("UUID を入力してください。 / Please Enter a UUID.");
    }
    if (!uuid) {
        return;
    }
    uuid = uuid.replace(/^.*=(.*)_a.*$/, '$1');
    const pbWrapper = net.ProtobufManager.lookupType(".lq.Wrapper");
    const pbGameDetailRecords = net.ProtobufManager.lookupType(".lq.GameDetailRecords");
    function parseRecords(gameDetailRecords, json) {
        try {
            if (gameDetailRecords.version == 0) {
                for (let i in gameDetailRecords.records) {
                    const record = (pbWrapper.decode(gameDetailRecords.records[i]));
                    const pb = net.ProtobufManager.lookupType(record.name);
                    const data = JSON.parse(JSON.stringify((pb.decode(record.data))));
                    json.records[i] = {name:record.name, data:data};
                }
            }
            else if (gameDetailRecords.version == 210715) {
                for (let i in gameDetailRecords.actions) {
                    if (gameDetailRecords.actions[i].type == 1) {
                        const record = (pbWrapper.decode(gameDetailRecords.actions[i].result));
                        const pb = net.ProtobufManager.lookupType(record.name);
                        const data = JSON.parse(JSON.stringify((pb.decode(record.data))));
                        json.actions[i].result = {name:record.name, data:data};
                    }
                };
            }
            else {
                throw ("Unknown version: " + gameDetailRecords.version);
            }
        }
        catch (e) {
            console.log(e);
        }
        return json;
    }
    async function fetchData(url) {
        const response = await fetch(url);
        const arrayBuffer = await response.arrayBuffer();
        return new Uint8Array(arrayBuffer);
    }
    function download(data, uuid) {
        let a = document.createElement("a");
        a.href = URL.createObjectURL(
            new Blob([JSON.stringify(data, null, "  ")],
            {type: "text/plain"}));
        a.download = "mahjongsoul_paifu_" + uuid + ".txt";
        a.style.display = "none";
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
    }
    app.NetAgent.sendReq2Lobby(
        "Lobby",
        "fetchGameRecord",
        {game_uuid:uuid, client_version_string:GameMgr.Inst.getClientVersion()},
        async function(error, gameRecord) {
            if (gameRecord.data == "") {
                gameRecord.data = await fetchData(gameRecord.data_url);
            }
            const gameDetailRecordsWrapper = pbWrapper.decode(gameRecord.data);
            const gameDetailRecords = pbGameDetailRecords.decode(gameDetailRecordsWrapper.data);
            let gameDetailRecordsJson = JSON.parse(JSON.stringify(gameDetailRecords));
            gameDetailRecordsJson = parseRecords(gameDetailRecords, gameDetailRecordsJson);
            gameRecord.data = "";
            let gameRecordJson = JSON.parse(JSON.stringify(gameRecord));
            gameRecordJson.data = {name:gameDetailRecordsWrapper.name, data:gameDetailRecordsJson};
            download(gameRecordJson, uuid);
        });
}
 

05.png

 

6. コンソールに

paifu()

と入力して、エンターキーを押すにゃ!

 

7. 「UUIDを入力してください。」と表示されるにゃ!
ここに雀魂の牌譜URLをコピペするにゃ!
そして「OK」ボタンを押すにゃ!

 

06.png
牌譜URLとはこういったものにゃ!

 

07.png
牌譜URLをコピペしたところにゃ!

 

8. 以上で、牌譜ファイルがダウンロードされるにゃ!
ダウンロードしたファイルは「メモ帳」などのテキストエディタで開いて、中身を確認できるにゃ!
対局者の名前、使用キャラ、対局結果、牌山、自摸と打牌、スタンプ煽り、思考時間、回線切断、全部記録されているにゃ!
牌譜の読み方は別の機会に説明するにゃ!

 

注意

調子に乗って大量の牌譜を短時間にダウンロードしようとすると、雀魂のサーバはサイバー攻撃を受けていると判断するにゃ!
すると、雀魂サーバに接続できなくなるにゃ!
二度と麻雀を打てなくなってしまうにゃ!
牌譜ダウンロードは間隔を開けて行うようにするにゃ!
絶対守るにゃ!