Export and import a save game of Tomb Raider OpenLara

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

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==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);
})();