Wordle save file helper

Allows to you export and import your Wordle save data

  1. // ==UserScript==
  2. // @name Wordle save file helper
  3. // @namespace il0x89mvb33pzor0fqyj
  4. // @description Allows to you export and import your Wordle save data
  5. // @match https://www.nytimes.com/games/wordle/*
  6. // @grant GM.registerMenuCommand
  7. // @grant GM.setClipboard
  8. // @grant GM.getValue
  9. // @grant GM.setValue
  10. // @grant GM.deleteValue
  11. // @version 1.3
  12. // @run-at document-start
  13. // @inject-into content
  14. // @license MIT
  15. // ==/UserScript==
  16.  
  17. (function () {
  18. "use strict";
  19.  
  20.  
  21. function getLocalStorageAsString() {
  22. const result = Object.create(null);
  23.  
  24. for (let i = 0, l = localStorage.length; i < l; ++i) {
  25. const key = localStorage.key(i);
  26. if (key.startsWith("nyt-wordle-")) {
  27. result[key.substring(11)] = localStorage.getItem(key);
  28. }
  29. }
  30.  
  31. return JSON.stringify(result);
  32. }
  33.  
  34.  
  35. function importLocalStorageFromString(data) {
  36. try {
  37. data = JSON.parse(data);
  38. } catch (e) {
  39. return false;
  40. }
  41.  
  42. for (let [k, v] of Object.entries(data)) {
  43. if (!k.startsWith("nyt-wordle-")) {
  44. k = `nyt-wordle-${k}`;
  45. }
  46. localStorage.setItem(k, v);
  47. }
  48. return true;
  49. }
  50.  
  51.  
  52. async function autoSave() {
  53. const savedata = await GM.getValue("autosave");
  54.  
  55. if (savedata) {
  56. const playedSave = JSON.parse(JSON.parse(savedata).statistics).gamesPlayed;
  57. const playedActual = JSON.parse(localStorage.getItem("nyt-wordle-statistics")).gamesPlayed;
  58. if (playedActual < playedSave) {
  59. return;
  60. }
  61. }
  62.  
  63. // No save data, or number of games is equal/higher
  64. GM.setValue("autosave", getLocalStorageAsString());
  65. }
  66.  
  67.  
  68. // Save every minute while the tab is active,
  69. // and when it gains/loses focus
  70. let saveInterval;
  71.  
  72. function onFocus() {
  73. clearInterval(saveInterval);
  74. autoSave();
  75. saveInterval = setInterval(autoSave, 60000);
  76. }
  77.  
  78. function onBlur() {
  79. clearInterval(saveInterval);
  80. autoSave();
  81. }
  82.  
  83.  
  84. window.addEventListener("focus", onFocus);
  85. window.addEventListener("blur", onBlur);
  86.  
  87.  
  88. GM.registerMenuCommand("Export Wordle save data", () => {
  89. GM.setClipboard(btoa(getLocalStorageAsString()));
  90. alert("Save data copied to clipboard.");
  91. });
  92.  
  93.  
  94. GM.registerMenuCommand("Import Wordle save data", () => {
  95. const imported = prompt("Paste save data here:");
  96.  
  97. if (imported && importLocalStorageFromString(atob(imported))) {
  98. alert("Import successful!");
  99. location.reload();
  100. }
  101. });
  102.  
  103.  
  104. GM.registerMenuCommand("Restore latest autosave", async () => {
  105. const savedata = await GM.getValue("autosave");
  106.  
  107. if (savedata) {
  108. const playedSave = JSON.parse(JSON.parse(savedata).statistics).gamesPlayed;
  109.  
  110. if (confirm(`The autosave has ${playedSave} games on record. Really restore it?`) && importLocalStorageFromString(savedata)) {
  111. alert("Restore successful!");
  112. location.reload();
  113. }
  114. }
  115. });
  116.  
  117.  
  118. GM.registerMenuCommand("Delete autosave", () => {
  119. if (confirm("Really DELETE the stored autosave?")) {
  120. // Disable autosaving on this page load
  121. window.removeEventListener("focus", onFocus);
  122. window.removeEventListener("blur", onBlur);
  123. clearInterval(saveInterval);
  124.  
  125. GM.deleteValue("autosave");
  126.  
  127. alert("Autosave cleared.");
  128. }
  129. });
  130. })();