DCSS Webtiles Extension Module Loader

Load the DWEM from other Webtiles sites as well.

  1. // ==UserScript==
  2. // @name DCSS Webtiles Extension Module Loader
  3. // @description Load the DWEM from other Webtiles sites as well.
  4. // @version 1.8
  5. // @author refracta
  6. // @match http://webzook.net:8080/*
  7. // @match https://crawl.kelbi.org/*
  8. // @match https://crawl.dcss.io/*
  9. // @match https://crawl.akrasiac.org:8443/*
  10. // @match https://underhound.eu:8080/*
  11. // @match https://cbro.berotato.org:8443/*
  12. // @match http://lazy-life.ddo.jp:8080/*
  13. // @match http://lazy-life.ddo.jp:8000/*
  14. // @match https://crawl.xtahua.com/*
  15. // @match https://crawl.project357.org/*
  16. // @match http://joy1999.codns.com:8081/*
  17. // @grant none
  18. // @run-at document-start
  19. // @namespace https://greasyfork.org/users/467840
  20. // ==/UserScript==
  21.  
  22. (function () {
  23. 'use strict';
  24. const [head] = document.getElementsByTagName('head');
  25.  
  26. async function haltRequireJS() {
  27. let disableRJSInjection = true;
  28. for (const funcName of ['appendChild', 'insertBefore']) {
  29. head['_' + funcName] = head[funcName];
  30. head[funcName] = function (tag) {
  31. if (disableRJSInjection && (tag.getAttribute('data-requirecontext') !== null || tag.getAttribute('data-requiremodule') !== null)) {
  32. return tag;
  33. }
  34. return this['_' + funcName].apply(this, arguments);
  35. }
  36. }
  37.  
  38. const scripts = head.getElementsByTagName('script');
  39. let rjsScript = Array.from(scripts).find(s => s.src?.endsWith('require.js'));
  40. if (!rjsScript) {
  41. rjsScript = {src: "/static/scripts/contrib/require.js", getAttribute: () => "/static/scripts/app"};
  42. }
  43. rjsScript?.remove?.();
  44.  
  45. const config = (() => {
  46. const dataMain = rjsScript.getAttribute('data-main');
  47. let mainScript = dataMain;
  48. const src = mainScript.split('/');
  49. mainScript = src.pop();
  50. const baseUrl = src.length ? src.join('/') + '/' : './';
  51. mainScript = mainScript.replace(/\.js$/, '');
  52. if (/^\/|:|\?|\.js$/.test(mainScript)) {
  53. mainScript = dataMain;
  54. }
  55. return {deps: [mainScript], baseUrl};
  56. })();
  57.  
  58. window.require = window.define = window.requirejs = undefined;
  59. const newRJSScript = document.createElement('script');
  60. newRJSScript.src = rjsScript.src;
  61. await new Promise(resolve => {
  62. newRJSScript.onload = newRJSScript.onreadystatechange = () => {
  63. if (!newRJSScript.readyState || /loaded|complete/.test(newRJSScript.readyState)) {
  64. newRJSScript.onload = newRJSScript.onreadystatechange = null;
  65. resolve();
  66. }
  67. };
  68. head.appendChild(newRJSScript);
  69. });
  70.  
  71. window.startMainScript = async () => {
  72. disableRJSInjection = false;
  73. require.config(config);
  74. };
  75. }
  76.  
  77. (async () => {
  78. await haltRequireJS();
  79. // localStorage.DWEM_MODULES = JSON.stringify(['https://example.org/module.js', ...]);
  80. // If DWEM_MODULES is not set, the following modules are loaded by default:
  81. localStorage.DWEM_MODULES = JSON.stringify([
  82. ...JSON.parse(localStorage.DWEM_MODULES || '[]'),
  83. ...['io-hook', 'site-information', 'websocket-factory', 'rc-manager', 'module-manager', 'sound-support', 'convenience-module', 'advanced-rc-editor']
  84. .map(m => "../modules/" + m + "/index.js")
  85. ]);
  86. localStorage.DWEM_LATEST_DURATION ||= 300;
  87. localStorage.DWEM_LATEST_TIME ||= 0;
  88. if (localStorage.DWEM_DEBUG === 'true') {
  89. await import(localStorage.DWEM_DEBUG_LOADER);
  90. } else {
  91. const currentTime = Date.now();
  92. if (localStorage.DWEM_LATEST_TIME && localStorage.DWEM_LATEST_DURATION) {
  93. const latestTime = parseInt(localStorage.DWEM_LATEST_TIME);
  94. const duration = parseInt(localStorage.DWEM_LATEST_DURATION);
  95. const cacheAge = (currentTime - latestTime) / 1000;
  96. console.log(`DWEM_LATEST Cache Age: ${cacheAge}s`);
  97. console.log(`DWEM_LATEST Cache Duration: ${duration}s`);
  98. if (cacheAge > duration) {
  99. try {
  100. localStorage.DWEM_LATEST = (await fetch(`https://api.github.com/repos/refracta/dcss-webtiles-extension-module/commits/main`).then(r => r.json())).sha;
  101. localStorage.DWEM_LATEST_TIME = Date.now();
  102. } catch (e) {
  103. }
  104. }
  105. }
  106. localStorage.DWEM_LATEST = localStorage.DWEM_LATEST || 'latest';
  107. await import(`https://cdn.jsdelivr.net/gh/refracta/dcss-webtiles-extension-module@${localStorage.DWEM_LATEST}/loader/dwem-core-loader.js`);
  108. }
  109. })();
  110. })();