プロフィール

髭山髭人(ひげひと)

自分の書いた記事が、一人でも誰かの役に立てば...
活動信条の一つとして「貴方のメモは、誰かのヒント」というのがあります。

このサイトについて

本家HP packetroom.net から切り離した いわゆる技術メモ用のブログで、無料レンタルサーバーにて運用しています。広告表示はその義務なのでご容赦。
XREA さんには長年お世話になっています

モバマス再現保存部

概要とか

現在この記事は #モバマス再現保存部 なるDiscordサーバー参加者さんに向けた、情報提示や誘導などを行なう趣旨となっています。

なので、未参加の方からすると 何かいてあるかよくわからん みたいな感じになるかも...

  • メンバーの方へ
    複数記事と併せて、なるべく髭側で確認次第 回収表などを更新するよう心がけてはいますが、
    別タスクを優先することによる 更新遅れ・反映漏れ 等が起こり得ます。
    他Pさんの回収(提供)作業がかかわるものに関しては Discord チャンネル内のやりとりが鮮度高いはずなので、
    「お?」と感じたら、ログに目を通してご自身の中に落とし込んで判断いただけると幸いです。

雑な活動経緯

元々、(個人的に)保存活動されてた他Pさんからお声掛けを頂いて、髭はちょっとした技術提供ポジションでした。

現在は少し趣旨を変えて、髭側も独自でコミュニティ?を立ち上げて "それぞれのツテ"から協力者を募り、
半分独自・半分協力して進めている最中です。

サーバーへのリンク先(+雑な募集概要)は、作者プロフ経由から Twitterをご覧ください
https://packetroom.net/profile/

環境条件

「PC上のブラウザ(とりわけChrome等)にてUA調整でログインして遊べる方」となります。
( ※ AndApp系では無い事に注意 ) 手法は以下をご覧ください。

Tips / 手法

[ Tips-1 ] Chrome起動等メモ

  1. C:\ ドライブ直下に 任意のフォルダを作成
    本例:c:\socialgame\

  2. 任意の名前.txt テキストファイルをデスクトップなどに作成し、下記2行コピペして保存
    これは、巷でモバPが使っている手法の一つである、
    「Chromeのショートカット設定を弄って多重起動させる方法」 と同系統の性質を持ちます。

    Set WshShell = WScript.CreateObject("WScript.Shell")
    WshShell.Run "chrome --user-data-dir=c:\socialgame\mobamas"

    \socialgame\mobamas 部分は必要に応じて変えられます
    「よくわからん」って方は、そのまま表記例をなぞって進めてください。  

  3. 今作ったテキストファイル .txt の拡張子を .vbs へ変更
    PC設定で拡張子を非表示にしてる方向け >> 「windows 拡張子 表示」でググる

  4. その .vbs をダブルクリックとかで実行
    こうすると、別ユーザープロファイルでChromeが起動できます
    「いつもメインで使っている(ログインしている/ブクマなど管理している)Chromeとは異なるユーザーとして起動
    ...みたいな感じで解釈して貰えれば。

  5. UA偽装用の拡張機能をインストール
    UA(UserAgent)と呼ばれる情報を変更するプラグイン..みたいなものです。
    似たような性質のものが沢山リリースされていますが、本例では User Agent Switcher, URL sniffer を導入します。
    先程起動させた別のChromeで、今のリンクを開いてください。
    [1] ページ先にある右上の青い「Chromeに追加」ボタンからインストール
    [2] ブラウザ右上の拡張機能ボタン※から開き「今すぐ有効にする」にチェック
    ( ※ 灰色のパズルピースみたいなアイコンから拡張機能群を開けます。そこから画像内、赤丸のアイコンにアクセス )

    この時、メニューに表示される選択項目を「iPad」や「iPhone」あたりに変更しましょう。


    このUA変更設定を終えれば、いろんなウェブサイトに接続する際、
    「ども!こんにちは!え?私ですか。iPhoneから見てますぅ~(嘘八百)」
    「iPhone(とかモバイル)用のページあれば、そっち見せてくださぁい^^」
    ...みたいな体裁でアクセスできます。

  6. モバゲー(モバマス)にログイン
    https://sp.pf.mbga.jp/12008305/
    ※ 正しくUA偽装されていない(または判定漏れする)と AndApp版 とかに回されると思います

  7. Enjoy!!
    以降、先程作成した 任意の名前.vbs ファイルを実行し、
    起動した 別プロファイルのChromeでプレイする
    形となります。
    ( 当然ログイン済み + 拡張機能でUA偽装済み )
    http://sp.pf.mbga.jp/12008305/?guid=ON&url=http%3A%2F%2Fmobamas.net%2Fidolmaster%2Fmypage%3F
    ↑ のURLをホームにしておくと便利 〇
    ( Chrome メニューから「設定」→「起動時」→「特定のページまたはページセットを開く」 )

本例をなぞると c:\socialgame\mobamas というフォルダが作成されます。
ゲームへログインした時のCookieやキャッシュ、インストール済みの拡張機能等が本来使っていたChromeと分けられ、全てそこへ格納されます。
今後、遊ぶ機会が完全になくなったら、そのフォルダを消せば後片付け完了です。
( ※ 時々遊ぶ機会がある、みたいな場合は 残しておいた方がPCには優しいかも )

[ Tips-2 ] スクリプト実行方法

  1. 実行したいページ上F12 キーを押して DevTools と呼ばれる物を呼び出します
  2. 最初は一緒のページにくっついて表示されているので、分離させておきます。
    右上のメニューから、Dock side の一番左を選べばOK
  3. Console を開く
    上部横並び表示されている英語項目の中から Console を選択
    その下にある白く広い領域の中に、 青い > マークが(左端/行頭に)ある部分 を使います。
    以降、作業用のスクリプトを実行するにあたり、この箇所を頻繁に利用します

    そこが入力部分になっているので、実行したいスクリプトをまるっとコピペで貼り付けて、
    そのまま Enter キーを押して実行

[ Tips-2.1 ]実際に試してみる

プログラムのコード・命令が通る感覚を実際に試してみましょう。
> の入力欄に、半角で

1+1

と打ち込み、そのまま Enter を押してください。
2 と出力されたら成功です 😋

他にも例えば、

alert("小関麗奈");

と打ち込んで(コピペでもOK)実行すれば、DevToolsではなく、ページ側に直接アラートダイアログが表示される筈です。
( 実行後、ページ側でダイアログを閉じてください )

「お手軽な所から試してみたい」という場合は もう幾らかページの下にある、
アイドル .json 回収 > [Script-A] 個別アイドルの .json 即時ダウンロード
の項目などで実行・試してみてください。

[ Tips-2.2 ] その他豆知識

  • ログクリア
    > 部分から入力カーソルを外したうえで Ctrl + L を押すと、
    表示されている Console のログが全部消えます。
    見づらい場合はオススメ
  • 再入力
    入力欄 > での入力(カーソル有効)中に 上方向キー を押すと、
    1つ前に実行したスクリプトが再表示されます。
    ( 単純に言えば実行履歴 )
    同じスクリプトを短時間で都度実行したい場合にオススメ

[ Tips-3 ] 確認用ログについて

実行していただくスクリプトの中には、一覧/結果確認用として .txt が出力される性質を持つものがあります。
中には Excel や Googleスプレッドシートに貼り付けて管理する事を意識したフォーマットのもの が含まれます。
独自で表管理したり、連番でソートする場面があればびっくりするほど楽なのでドチャクソお勧めです。

  1. Googleドライブを開く
    https://drive.google.com/drive/my-drive
    https://drive.google.com/drive/my-drive
  2. 左上にある「新規」ボタンからGoogleスプレッドシートを作成
  3. それ開く
  4. 貼り付け用として書き出されたテキストをまるっとコピペ。
    多分ちゃんとセル?ごとに分かれてくれるはず
  5. ソートしたい部分のセルで、上の英語部分(A~等の当該セル)にカーソル合せる
  6. 小さい ▽ みたいなボタンがあるので、そこから「〇順でシートを並び替え」
  7. 見やすい!!!優勝!!!

アイドルギャラリー .json 回収

[Script-A] 個別アイドルの .json 即時ダウンロード

  • 実行場所
    各個人のアイドルギャラリーページ
{
    const _data = idol;
    const _blob = new Blob([JSON.stringify(_data,null,'\t')],{type:'application\/json'});
    const _url = URL.createObjectURL(_blob);
    const _link = document.createElement("a");
    const _name = idol?.detail_list[0]?.data?.real_name; 
    _link.href = _url;
    _link.download = `${_name}.json`;
    document.body.appendChild(_link);
    _link.click();
    document.body.removeChild(_link);
    URL.revokeObjectURL(_url);
}

[Script-B] 巡回かつ親愛埋め全MAXのみDLタイプ

  • 実行場所
    多分どこでもOK
  • 性質
    各アイドルのギャラリーを全巡回し、その中で
    実装済みカードが全て親愛MAX状態になっているアイドルのみ.json をDLします
[Script-B]全ギャラリー巡回+特殊DLタイプ


(async()=>{

    const _galleryList = await fetch("https://mkt.packetroom.net/script/idol_gallery_list.json",{mode:"cors"}).then(_res=>_res.json()).catch(_err=>{ console.warn(`${_err} アクセス失敗`);});

    const _dlTargetDefObj = [];
    _galleryList.forEach(_e=>{
        const _nameKey = Object.keys(_e)[0];
        const _hash = _e[_nameKey];
        const _url = `https://sp.pf.mbga.jp/12008305/?guid=ON&url=http://mobamas.net/idolmaster/idol_gallery/idol_detail/${_hash}`;
        const _dlFileName = `${_nameKey}`;
        console.info(_nameKey , _hash);
        _dlTargetDefObj.push( { "idol_name" : _nameKey , "url" : _url , "optionExt" : ".json"}  );
    });
    const _resultList = [];
    console.info("================== 巡回アクセス & DL処理を開始します ==================");
    function _fileDl(_dlInfo , _index) {
        return new Promise((resolve,reject) => {
            const _idolName = _dlInfo["idol_name"];
            const _url = _dlInfo["url"];
            setTimeout(async () => {
                const _restext = await fetch(_url,{ method: "GET"})
                .then(_res=>{
                    if(!_res.ok){
                        throw new Error(_res.statusText);
                    }else{
                        return _res.text();
                    }
                })
                .catch(_err=>{
                    console.warn(`${_idolName} アクセス失敗`);
                });
                let _idolObject = {};
                let _sucess = false;
                // === 何らかのレス 取得成功と判断
                if(_restext){
                    const _dPsr = new DOMParser();
                    const _doc = _dPsr.parseFromString(_restext , "text/html");
                    const _scr = [..._doc.scripts].find(_e=> _e.textContent.length>6000);
                    let _details,_strys,_imgs;
                    try{
                        const _m = _scr.textContent.match(/idol\.detail_list = (\[.*);\nidol\.idol_story_list = (\[.*\]);\nidol\.images = ({.*});\n/);
                        _details = JSON.parse(_m[1]);
                        _strys = JSON.parse(_m[2]);
                        _imgs = JSON.parse(_m[3]);
                        _idolObject["detail_list"] = _details;
                        _idolObject["idol_story_list"] = _strys;
                        _idolObject["images"] = _imgs;
                        _sucess = true;
                    }catch(_err){ console.error(_err); }
                    if(!_sucess){ console.error("パース関連の予期せぬ例外:失敗,中断"); reject(); return; }
                    let _lMax = 0;
                    let _cardCount = _details.length;
                    const _cID = _details[0].profile.card_id; // ソートカテゴリ用
                    const _name = _idolName;//_details[0].profile.card_name;
                    _details.forEach(_i=>{ (_i.is_max_love?(_lMax++):0); });
                    console.info(`${_name} 親愛MAX数 ${_lMax} / ${_cardCount} ${(_lMax==_cardCount?"◎":"")}`);
                    if(_cardCount>1 && _lMax==_cardCount){
                        const _dlUrl = URL.createObjectURL( new Blob([JSON.stringify(_idolObject , null , "\t")] , {type: "application/json"}) );
                        const _a = document.createElement('a');
                        _a.href = _dlUrl;
                        _a.download = `${_idolName}.json`;
                        document.body.appendChild(_a); _a.click();
                        console.info(`${_a.download} をDLしました`);
                        document.body.removeChild(_a);
                        URL.revokeObjectURL(_dlUrl);
                    }else{
                        console.info(`DL対象外です`);
                    }
                }
                if(_sucess != true){
                    console.warn(_idolName , "失敗判定");
                    _resultList.push("failed");
                }
                resolve();
            }, 100);    // DL間隔ミリ秒。あまり縮めないほうが良い
        });
    }
    // 実処理開始
    (async () => {
        await _dlTargetDefObj.reduce((promise, _dlInfo , _currentIndex) => {
            return promise.then(async () => {
                await _fileDl(_dlInfo , _currentIndex);
            });
        }, Promise.resolve());
        console.info("=== ギャラリーページへのアタッチ終了 ====");
        const _missingList = []; // 欠番処理
    })();

})();


回収表

実質全回収済み

追加ボイスなどがあれば適宜。

  • 更新されたもの
    • [笑顔のガーディアン]関裕美
    • [お屋敷セレクション]川島瑞樹
    • [憧れモード]佐々木千枝
    • [新春コレクション]上条春菜
    • [サイバーグラス]荒木比奈
    • [聖なる乙女]望月聖