Melvor Idle - Timestamped Saves

Adds character name and a timestamp to the default filename when downloading a save

  1. // ==UserScript==
  2. // @name Melvor Idle - Timestamped Saves
  3. // @description Adds character name and a timestamp to the default filename when downloading a save
  4. // @version 2.10
  5. // @namespace Visua
  6. // @match https://melvoridle.com/*
  7. // @match https://www.melvoridle.com/*
  8. // @match https://test.melvoridle.com/*
  9. // @require https://cdnjs.cloudflare.com/ajax/libs/pako/1.0.11/pako.min.js
  10. // @grant none
  11. // ==/UserScript==
  12. /* jshint esversion: 6 */
  13.  
  14. ((main) => {
  15. var script = document.createElement('script');
  16. script.textContent = `try { (${main})(); } catch (e) { console.log(e); }`;
  17. document.body.appendChild(script).parentNode.removeChild(script);
  18. })(() => {
  19. 'use strict';
  20.  
  21. function replaceDownloadSave() {
  22. const _downloadSave = downloadSave;
  23. downloadSave = (backup = false) => {
  24. let saveString;
  25. try {
  26. if (!backup) {
  27. saveString = getSave();
  28. } else {
  29. saveString = backupSave;
  30. }
  31. const save = JSON.parse(pako.ungzip(atob(saveString), { to: 'string' }));
  32. if (Object.keys(save).length < 3) {
  33. throw new Error('Save might not contain any data');
  34. }
  35. } catch (e) {
  36. console.error('Melvor Idle - Timestamped Saves:', e);
  37. if (typeof saveString !== 'undefined') {
  38. console.error('Melvor Idle - Timestamped Saves: Save has unexpected format:', saveString);
  39. }
  40. _downloadSave();
  41. return;
  42. }
  43.  
  44. const file = new Blob([saveString], { type: 'text/plain' });
  45. const filename = `melvoridlesave - ${username} - ${timestamp()}.txt`;
  46. if (window.navigator.msSaveOrOpenBlob)
  47. window.navigator.msSaveOrOpenBlob(file, filename); // IE10+
  48. else {
  49. const a = document.createElement('a');
  50. const url = URL.createObjectURL(file);
  51. a.href = url;
  52. a.download = filename;
  53. document.body.appendChild(a);
  54. a.click();
  55. setTimeout(function () {
  56. document.body.removeChild(a);
  57. window.URL.revokeObjectURL(url);
  58. }, 100);
  59. }
  60. };
  61.  
  62. function timestamp() {
  63. const date = new Date();
  64. return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())} `
  65. + `${pad(date.getHours())}-${pad(date.getMinutes())}-${pad(date.getSeconds())}`;
  66. }
  67.  
  68. function pad(n) {
  69. return n < 10 ? `0${n}` : n;
  70. }
  71. }
  72.  
  73. function loadScript() {
  74. if (typeof confirmedLoaded !== 'undefined' && confirmedLoaded) {
  75. clearInterval(interval);
  76. console.log('Loading Timestamped Saves');
  77. replaceDownloadSave();
  78. $('#header-user-options-dropdown .dropdown-divider:first').before('<a class="dropdown-item d-flex align-items-center justify-content-between pointer-enabled" onclick="downloadSave();"><span>Download Save</span></a>');
  79. }
  80. }
  81.  
  82. const interval = setInterval(loadScript, 500);
  83. });