搜尋

首頁  >  問答  >  主體

取得模擬器錯誤

<p>我一直在嘗試對我在網上找到的 GBA 模擬器 (https://gba.44670.org/) 進行逆向工程,並使用 HTML 提取器來嘗試複製它。我希望它能夠離線工作,所以我將所有腳本下載到我的電腦上,並在那裡運行。但是,此後,「選擇檔案」按鈕不再出現,取而代之的是「正在加載,請稍候...」文字行。深入研究程式碼,我發現它與 WASM 有關。代碼如下:</p> <pre class="brush:php;toolbar:false;"><div id="wasm-loading"> Loading, please wait... </div> <div id="select-rom" hidden> <input type="file" id="romFile" onchange="onFileSelected()" hidden /></p> <button onclick="$id('romFile').click()" id="btn-choose">Choose File...</button> </div></pre> <p>程式碼中對 WASM 的其他提及位於 .js 檔案 app.js 中:</p> <pre class="brush:php;toolbar:false;">function wasmReady() { romBuffer = Module._emuGetSymbol(1) var ptr = Module._emuGetSymbol(2) wasmSaveBuf = Module.HEAPU8.subarray(ptr, ptr wasmSaveBufLen) ptr = Module._emuGetSymbol(3) imgFrameBuffer = new Uint8ClampedArray(Module.HEAPU8.buffer).subarray(ptr, ptr 240 * 160 * 4) idata = new ImageData(imgFrameBuffer, 240, 160) isWasmReady = true document.getElementById('wasm-loading').hidden = true document.getElementById('select-rom').hidden = false }</pre> <p>我期望一旦我下載了腳本,它就會像平常一樣工作。我的意思是,它仍然可以訪問它需要的腳本,對吧?我嘗試透過更改 <code>document.getElementById('select-rom').hidden = false</code> 中的 true/false 語句來隱藏文本,反之亦然,但似乎沒有任何效果。有任何想法嗎?提前致謝。 </p> <p>(順便說一句,我正在vscode.dev 中尋找檔案路徑。它看起來像這樣: <code><script src="/Scripts/44gba.js"></script> < ;script src="/Scripts /app.js"></script> <script src="/Scripts/localforage.js"></script> <script src=/Scripts/pako.min .js></script></code> )</p>
P粉447495069P粉447495069498 天前871

全部回覆(1)我來回復

  • P粉550823577

    P粉5508235772023-09-02 11:05:59

    要使用腳本將應用程式保留在本地,請記住兩件事:

    1. 腳本已經寫完畢,將在目前App目錄結構中尋找資源(js、css、圖片)
    2. 大多數瀏覽器中的請求和檔案讀取都會被 CORS 阻止,除非您停用 CORS 預檢檢查。

    也就是說,複製您在回應中得到的相同 HTML (https://gba.44670.org/ ),這將保留檔案結構。這是我得到的內容(index.html):

    <html lang="en"><head>
        <!-- Required meta tags -->
        <meta charset="utf-8">
        <meta name="apple-mobile-web-app-capable" content="yes">
        <meta name="apple-mobile-web-app-status-bar-style" content="black">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height">
        <link rel="apple-touch-icon" href="icon.png">
        <link rel="manifest" href="manifest.json">
        <title>44VBA</title>
    
    </head>
    
    <body>
        <style>
            a,
            a:visited {
                color: white;
            }
    
            html,
            body {
                position: fixed;
                overflow: hidden;
                -webkit-user-select: none;
                user-select: none;
                -webkit-touch-callout: none;
                touch-action: none;
                cursor: inherit;
            }
    
            body {
    
                background-color: #000000;
                color: #FFFFFF;
                padding: 0;
                margin: 0;
                width: 100vw;
                height: 100vh;
                font-family: 'Myriad Set Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;
            }
    
            hr {
                color: white;
            }
    
            button {
                border: 2px solid white;
                background: transparent;
                color: white;
                padding: .5em;
            }
    
            .vk-round {
                text-align: center;
                vertical-align: middle;
                border-radius: 50%;
                display: inline-block;
            }
    
    
            .vk {
                color: rgba(0, 0, 0, 0.2);
                background-color: rgba(255, 255, 255, 0.25);
                position: absolute;
                z-index: 1;
                text-align: center;
                vertical-align: middle;
                display: inline-block;
            }
    
            .vk-hide {
                background-color: transparent !important
            }
    
            .vk-touched {
                background-color: rgba(255, 255, 255, 0.75) !important
            }
    
            .menu {
                background: rgb(32, 43, 56);
                position: absolute;
                left: 0;
                top: 0;
                width: 100vw;
                height: 100vh;
                z-index: 999;
            }
    
            #gba-canvas {
                position: absolute;
                z-index: -1;
            }
    
            #vk-layer {
                position: absolute;
                left: 0;
                top: 0;
                width: 100%;
                height: 100%;
                z-index: 3;
                touch-action: none;
            }
    
            #msg-layer {
                position: absolute;
                left: 0;
                width: 100%;
                top: 40vh;
                background: rgba(0, 0, 0, 0.5);
                z-index: 2;
            }
    
            textarea {
                background: transparent;
                color: #fff;
                border: 2px solid white;
    
            }
    
            /* textarea placeholder */
            textarea::placeholder {
                color: #666;
            }
        </style>
        <div id="pause-menu" class="menu" style="background: rgba(32,43,56,0.7);" hidden="">
            <button onclick="setPauseMenu(false)"> ← Back </button>
            <hr>
            Savegame management:<br>
            <button onclick="savBackupBtn()">Backup</button>
            <input type="file" id="sav-file" onchange="savRestoreBtn()" hidden="">
            <button onclick="$id('sav-file').click()">Restore</button>
            <hr>
            <label for="cfg-scale-mode">Screen filter:</label>
            <select id="cfg-scale-mode">
                <option value="0">Pixelated</option>
                <option value="1">Smooth</option>
                <option value="2">XBRZ</option>
            </select><br>
            <input type="checkbox" id="cfg-mute">
            <label for="cfg-mute">Mute Sound</label><br>
            <input type="checkbox" id="cfg-turbo">
            <label for="cfg-turbo">Turbo mode</label><br>
            <div id="div-cht">
                Cheat Codes(backup your savegame before using it):<br>
                <textarea id="txt-code" style="width:100%" rows="10" placeholder="Cheat code:
    GamesharkAdv: XXXXXXXX YYYYYYYY
    CodeBreaker: XXXXXXXX YYYY"></textarea><br>
                <button onclick="chtSaveBtn()">Save Cheat Codes</button>
            </div>
            <hr>
            Cloud Save:<span id="span-cloud-id"></span><br>
            <button onclick="dpOnConnectButtonClicked()" id="btn-dp-connect">Connect Dropbox</button><br>
            <button onclick="dpManualBtn(true)">↑ Upload</button>|<button onclick="dpManualBtn(false)">↓ Download</button><br>
        </div>
        <div id="welcome" class="menu">
            <h1 id="title">44VBA</h1>
            <hr>
            <div id="wasm-loading" hidden="">
                Loading, please wait...
            </div>
            <div id="select-rom">
                <input type="file" id="romFile" onchange="onFileSelected()" hidden=""><p></p>
                <button onclick="$id('romFile').click()" id="btn-choose">Choose File...</button>
            </div>
            <hr>
            Ver. 20230107 | <a href="https://github.com/44670/44vba">GitHub</a>
            <p>
                Your files are processed locally and won't be uploaded to any server.<br>
                This software should not be used to play games you have not legally obtained.<br>
                "GBA", "Game Boy Advance" are trademarks of Nintendo Co.,Ltd, This site is not associated with Nintendo in
                any way.
            </p>
            <div id="ios-hint" hidden="">
                Due to iOS limitations, please open this site(https://gba.44670.org) in <b>Safari</b>, and add it to your
                <b>Home Screen</b> by <b>Share Menu</b> to continue.
                <p style="text-align: center;">⬇⬇⬇</p>
            </div>
        </div>
        <div id="msg-layer" hidden="">
            <p id="msg-text">Gamepad disconnected.</p>
        </div>
        <div id="vk-layer" hidden="">
            <div class="vk-rect vk" data-k="menu" style="top: 25px; left: 591px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">Menu</div>
            <div class="vk-rect vk" data-k="turbo" style="top: 25px; left: 0px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">F.F.</div>
            <div class="vk-rect vk" data-k="l" style="top: 75px; left: 0px; width: 150px; height: 50px; font-size: 35px; line-height: 50px;">L</div>
            <div class="vk-rect vk" data-k="r" style="top: 75px; left: 591px; width: 150px; height: 50px; font-size: 35px; line-height: 50px;">R</div>
            <div class="vk-round vk" data-k="a" style="top: 175px; left: 676px; width: 65px; height: 65px; font-size: 35px; line-height: 65px;">A</div>
            <div class="vk-round vk" data-k="b" style="top: 200px; left: 585px; width: 65px; height: 65px; font-size: 35px; line-height: 65px;">B</div>
            <div class="vk-rect vk" data-k="select" style="top: 605px; left: 205.5px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">Select</div>
            <div class="vk-rect vk" data-k="start" style="top: 605px; left: 385.5px; width: 150px; height: 25px; font-size: 35px; line-height: 25px;">Start</div>
            <div class=" vk" data-k="left" style="top: 200px; left: 0px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">←</div>
            <div class=" vk" data-k="right" style="top: 200px; left: 100px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">→</div>
            <div class=" vk" data-k="up" style="top: 150px; left: 50px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">↑</div>
            <div class=" vk" data-k="down" style="top: 250px; left: 50px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;">↓</div>
            <div class=" vk vk-hide" style="top: 150px; left: 0px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="ul"></div>
            <div class=" vk vk-hide" style="top: 150px; left: 100px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="ur"></div>
            <div class=" vk vk-hide" style="top: 250px; left: 0px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="dl"></div>
            <div class=" vk vk-hide" style="top: 250px; left: 100px; width: 50px; height: 50px; font-size: 35px; line-height: 50px;" data-k="dr"></div>
        </div>
        <canvas width="240" height="160" id="gba-canvas" style="width: 741px; height: 494px; left: 0px; image-rendering: pixelated;"></canvas>
        <script src="pako.min.js"></script>
        <script src="localforage.js"></script>
        <script src="app.js"></script>
        <script src="build/44gba.js"></script>
    
    
    
    
    </body></html>

    然後您可以看到腳本路徑,您將按照該路徑建立檔案:

    <script src="pako.min.js"></script>
    <script src="localforage.js"></script>
    <script src="app.js"></script>
    <script src="build/44gba.js"></script>

    此外,您還需要下載 WASM 檔案(壓縮後 651KB,未壓縮 7.7MB)。您可以在此處下載壓縮包(您可以在開發工具的「網路」標籤中找到它):https ://gba.44670.org/build/44gba.wasm

    #最後,下載所有必要的檔案(如果需要,也可以下載圖示和圖片,但不是必要的):

    #您將得到如下所示的結構:

    現在,如果您可以從瀏覽器停用 CORS,那就太好了。但如果沒有,您必須從本機 HTTP 伺服器提供服務。一種選擇是安裝 NPM 套件: https://www.npmjs.com/package/http-伺服器,執行 npm install --global http-server。之後,只需導航到終端中的專案目錄並啟動伺服器:

    npx http-server ./ --port 4000

    您將看到正確的螢幕並加載 ROM,然後就完成了。

    編輯:透過簡單的 Hack 解決本地 CORS 問題

    #由於我知道您現在使用的是ChromeOS,而且從技術上講還不知道如何使用Node、NPM 和HTTP-Server 來處理它,因此我為您做了一些修改,並將WASM 二進位內容直接放入< code>build/44gba.js,並在函數readBinary 上傳回該二進位內容,以便繞過CORS 問題。您可以直接啟動index.html。以下是新build/44gba.js 文件的鏈接,只需將其內容替換為以下文件:https://sendeyo.com/en/b02f94b524,你們都很好。以下是更改內容:

    const wasmData = `0061 736d 0100 0000 01c9 011e 6001 7f00
    6002 7f7f 0060 0000 6001 7f01 7f60 037f
    ...  ...  ...  ...  ...  ...  ...  ...
    0a00 41c0 8106 0b04 7064 6202`;
    
    // other codes ...
    
    readBinary = filename=>{
        var ret = new Uint8Array(wasmData);
        return ret;
        /* var ret = read_(filename, true);
        if (!ret.buffer) {
            ret = new Uint8Array(ret)
        }
        return ret
        */
    }
    
    // other codes ...

    回覆
    0
  • 取消回覆