Export and import a save game of Tomb Raider OpenLara

Exports and imports the savegame.dat of Tomb Raider OpenLara from IndexedDB

// ==UserScript==
// @name         Export and import a save game of Tomb Raider OpenLara
// @namespace    Savegame
// @version      0.2
// @description  Exports and imports the savegame.dat of Tomb Raider OpenLara from IndexedDB
// @license      MIT
// @match        http://www.xproger.info/projects/OpenLara/
// @grant        none
// ==/UserScript==

(function() {
  'use strict';

  function importDatabase() {
    console.log('importDatabase');

    // open the db database with the version 22
    const request = indexedDB.open('db', 22);

    // handle the success event
    request.onsuccess = (event) => {
      const db = event.target.result;
      const database_transaction = db.transaction('FILE_DATA', 'readwrite');
      const store = database_transaction.objectStore('FILE_DATA');

      const savegameBlob = new Uint8Array([
0x4F,0x4C,0x53,0x32,0x28,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x01,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x2C,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x6D,0x00,0x02,0x00,0x30,0x00,0x00,0x00,
0x05,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x63,0x00,0x10,0x27,
0x6C,0x00,0x02,0x00,0x6D,0x00,0x04,0x00,0x34,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0xFF,0x00,0x6C,0x00,0x02,0x00,
0x6D,0x00,0x05,0x00,0x38,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x05,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0xFF,0x00,0x6C,0x00,0x03,0x00,0x6D,0x00,0x05,0x00,
0x96,0x00,0x01,0x00,0x38,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x05,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0xFF,0x00,0x6C,0x00,0x07,0x00,0x6D,0x00,0x06,0x00,
0x96,0x00,0x01,0x00,0x38,0x00,0x00,0x00,0x0A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x05,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0xFF,0x00,0x6C,0x00,0x0A,0x00,0x6D,0x00,0x06,0x00,
0x96,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x0B,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x07,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0x0A,0x00,0x65,0x00,0xD0,0x07,0x6A,0x00,0x01,0x00,
0x6C,0x00,0x0B,0x00,0x6D,0x00,0x09,0x00,0x96,0x00,0x01,0x00,0x40,0x00,0x00,0x00,0x0C,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0x0C,0x00,
0x65,0x00,0xD0,0x07,0x6A,0x00,0x01,0x00,0x6C,0x00,0x0E,0x00,0x6D,0x00,0x0D,0x00,0x96,0x00,0x01,0x00,
0x40,0x00,0x00,0x00,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,
0x63,0x00,0x10,0x27,0x64,0x00,0x0E,0x00,0x65,0x00,0xD0,0x07,0x6A,0x00,0x01,0x00,0x6C,0x00,0x0F,0x00,
0x6D,0x00,0x0E,0x00,0x96,0x00,0x02,0x00,0x40,0x00,0x00,0x00,0x0F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0x10,0x00,0x65,0x00,0xD0,0x07,
0x6A,0x00,0x01,0x00,0x6C,0x00,0x12,0x00,0x6D,0x00,0x0E,0x00,0x96,0x00,0x02,0x00,0x40,0x00,0x00,0x00,
0x10,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x07,0x00,0x00,0x00,0x63,0x00,0x10,0x27,
0x64,0x00,0x14,0x00,0x65,0x00,0xD0,0x07,0x6A,0x00,0x04,0x00,0x6C,0x00,0x14,0x00,0x6D,0x00,0x0F,0x00,
0x96,0x00,0x02,0x00,0x24,0x00,0x00,0x00,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x3C,0x00,0x00,0x00,0x13,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x06,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0x02,0x00,0x69,0x00,0x01,0x00,0x6A,0x00,0x30,0x00,
0x6C,0x00,0x09,0x00,0x6D,0x00,0x09,0x00,0x3C,0x00,0x00,0x00,0x15,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x63,0x00,0x10,0x27,0x64,0x00,0x06,0x00,0x66,0x00,0xD0,0x07,
0x69,0x00,0x02,0x00,0x6C,0x00,0x09,0x00,0x6D,0x00,0x09,0x00
      ]);
      let query = store.put(savegameBlob, "savegame.dat");

      query.onsuccess = (event) => {
        alert("Savegame data added. Reload the page.");
      }

      database_transaction.oncomplete = function () {
        db.close();
      };

    }
  }

  // export database
  function exportDatabase() {
    console.log('exportDatabase');

    // open the db database with the version 22
    const request = indexedDB.open('db', 22);

    // handle the success event
    request.onsuccess = (event) => {
      const db = event.target.result;
      const database_transaction = db.transaction('FILE_DATA', 'readonly');
      const store = database_transaction.objectStore('FILE_DATA');

      let query = store.get("savegame.dat");

      query.onsuccess = (event) => {
        if (!event.target.result) {
          console.log("savegame.dat not found");
        } else {
          console.log(event.target.result);

          const uint8Array = new Uint8Array(event.target.result);
          const blob = new Blob([uint8Array], { type: 'application/octet-stream' });
          const downloadLink = document.createElement("a");
          downloadLink.href = URL.createObjectURL(blob);
          downloadLink.download = "savegame.dat";
          downloadLink.click();
        }
      };

      query.onerror = (event) => {
        console.log(event.target.errorCode);
      }

      database_transaction.oncomplete = function () {
        db.close();
      };

    }
  }

  // create a button
  var button = document.createElement('button');
  button.innerHTML = 'Export';
  button.style.position = 'relative';

  // add button
  document.body.appendChild(button);

  // add event listener
  button.addEventListener('click', exportDatabase);

  // create an import button
  var button2 = document.createElement('button');
  button2.innerHTML = 'Import';
  button2.style.position = 'relative';

  // add button
  document.body.appendChild(button2);

  // add event listener
  button2.addEventListener('click', importDatabase);
})();
长期地址
遇到问题?请前往 GitHub 提 Issues。