// ==UserScript== // @name Dreadcast Script Manager // @namespace Dreadcast // @match https://www.dreadcast.net/Main // @match https://www.dreadcast.net/Forum // @match https://www.dreadcast.net/Forum/* // @match https://www.dreadcast.net/EDC // @match https://www.dreadcast.net/EDC/* // @version 1.3.0 // @author Pelagia/Isilin // @description Centralize all dreadcast scripts in one single source, integrated to the game. // @license https://github.com/Isilin/dreadcast-scripts?tab=GPL-3.0-1-ov-file // @require https://update.greasyfork.icu/scripts/507382/Dreadcast%20Development%20Kit.user.js // @grant GM_setValue // @grant GM_getValue // @grant GM_deleteValue // @grant GM_listValues // @grant GM_xmlhttpRequest // @grant GM_addStyle // @connect update.greasyfork.org // @connect docs.google.com // @connect googleusercontent.com // @connect sheets.googleapis.com // @connect raw.githubusercontent.com // @downloadURL none // ==/UserScript== // TODO remplacer petit à petit les scripts par les versions locales nettoyées. // TODO use a recent jquery with noConflict // TODO Reset button in Com'Back reset all the settings from DCSM (including scripts then). $(() => { // To check if a script is used in a DSM context. Util.isDSM = () => true; const LIST_TAG = 'dcsm_list'; const ALL_DISABLED_TAG = 'dcsm_all_disabled'; const INTRO_TAG = 'dcsm_intro_disabled'; const DEV_MODE_TAG = 'dcsm_dev_mode'; let settings, allDisabled, introDisabled, devMode; let newSettings, newAllDisabled, newDevMode; // ===== CORE ===== const initPersistence = () => { // Init persistent memory if needed. DC.LocalMemory.init(LIST_TAG, {}); DC.LocalMemory.init(ALL_DISABLED_TAG, false); DC.LocalMemory.init(INTRO_TAG, false); DC.LocalMemory.init(DEV_MODE_TAG, false); // TODO to delete at next major version. if (DC.LocalMemory.get('dcm_list') !== undefined) { DC.LocalMemory.set(LIST_TAG, DC.LocalMemory.get('dcm_list')); DC.LocalMemory.delete('dcm_list'); } if (DC.LocalMemory.get('dcm_all_disabled') !== undefined) { DC.LocalMemory.set( ALL_DISABLED_TAG, DC.LocalMemory.get('dcm_all_disabled'), ); DC.LocalMemory.delete('dcm_all_disabled'); } // Load the current settings. settings = DC.LocalMemory.get(LIST_TAG); allDisabled = DC.LocalMemory.get(ALL_DISABLED_TAG); introDisabled = DC.LocalMemory.get(INTRO_TAG); devMode = DC.LocalMemory.get(DEV_MODE_TAG); }; const synchronizeSettings = (settings, scripts) => { let tmp = settings; scripts.forEach((script) => { if (!Object.hasOwn(tmp, script.id)) { // Update the settings, if there is new scripts. tmp[script.id] = false; } }); // Remove in settings, scripts that doesn't exist anymore. tmp = Object.keys(tmp) .filter( (key) => scripts.find((script) => script.id === key) !== undefined, ) .reduce((obj, key) => { obj[key] = tmp[key]; return obj; }, {}); // Save the new settings in persistent memory. DC.LocalMemory.set(LIST_TAG, tmp); return tmp; }; const createScriptLine = (script, index) => { const line = $(` ${index} ${ script.icon && script.icon !== '' ? `` : '' } ${ script.experimental ? '[DEV]' : '' } ${script.name || ''} ${ script.authors || '' } ${ script.description || '' } `); $('.enabled_cell', line).append( DC.UI.Tooltip( 'Activer/Désactiver le script ne perdra pas sa configuration.', DC.UI.Checkbox( `${script.id}_check`, newSettings[script.id], () => (newSettings[script.id] = !newSettings[script.id]), ), ), ); if (script.settings) { $('.setting_cell', line).append( DC.UI.Tooltip( 'Settings', DC.UI.Button( `${script.id}_setting`, '', () => {}, ), ), ); } if (script.doc && script.doc !== '') { $('.doc_cell', line).append( DC.UI.Tooltip( 'Documentation', DC.UI.Button(`${script.id}_doc`, '', () => window.open(script.doc, '_blank'), ), ), ); } if (script.rp && script.rp !== '') { $('.rp_cell', line).append( DC.UI.Tooltip( 'Topic RP', DC.UI.Button( `${script.id}_rp`, '
RP
', () => window.open(script.doc, '_blank'), ), ), ); } if (script.contact && script.contact !== '') { $('.contact_cell', line).append( DC.UI.Tooltip( 'Contact', DC.UI.Button( `${script.id}_rp`, '', () => nav.getMessagerie().newMessage(script.contact), ), ), ); } return line; }; const createIntro = () => { if (Util.isGame() && !introDisabled) { introDisabled = true; DC.LocalMemory.set(INTRO_TAG, introDisabled); DC.UI.PopUp( 'dcsm_intro', 'Bienvenue sur le Dreadcast Script Manager !', $(`

Merci d'avoir installé le DreaCast Script Manager (DCSM).


Cet utilitaire va vous permettre de gérer vos scripts directement en jeu. Pensez à désactiver/désinstaller dans votre GreaseMonkey/TamperMonkey (ou équivalent), les scripts que vous activerez dans le DCSM, pour éviter des doublons.


La suite se passe dans Paramètres > Scripts & Skins.


Vous pourrez obtenir des réponses à vos questions sur le wiki, sur le forum, ou en me contactant directement par Com' HRP : (JD Pelagia).


Bon jeu ! (Vous ne verrez plus cette fenêtre d'information par la suite).

`), ); } }; const createUI = (scripts, settings) => { DC.UI.addSubMenuTo( 'Paramètres ▾', DC.UI.SubMenu( 'Scripts & Skins', () => { // On récupère une config temporaire qu'on appliquera uniquement si sauvegardée. newSettings = settings; newAllDisabled = allDisabled; newDevMode = devMode; const sections = [ { id: 'all', label: 'Tous' }, { id: 'game', label: 'Jeu' }, { id: 'forum', label: 'Forum' }, { id: 'edc', label: 'EDC' }, ]; const categories = [ { id: 'all', label: 'Tous' }, { id: 'mailing', label: 'Messagerie' }, { id: 'chat', label: 'Chat' }, { id: 'silhouette', label: 'Silhouette' }, { id: 'ui', label: 'UI' }, { id: 'mech', label: 'Mécaniques' }, { id: 'fix', label: 'Correctifs' }, { id: 'misc', label: 'Autres' }, ]; const content = $(`

Mode développeur

Tout désactiver

Filtrer :
${sections .map( (section, index) => `
`, ) .join('')}
Filtrer :
${categories .map( (category, index) => `
`, ) .join('')}
# Nom Auteurs Actif
`); $(document).on('change', "input[name='category']", (e) => { const category = e.target.value; const section = $("input[name='section']:checked").val(); const search = $("input[name='search_script']").val().toLowerCase(); // Empty the table $('tbody', content).empty(); // Add filtered lines scripts .filter( (script) => (script.section.includes(section) || section === 'all') && (script.category.includes(category) || category === 'all') && (script.name.toLowerCase().includes(search) || script.description.toLowerCase().includes(search)), ) .forEach((script, index) => { const line = createScriptLine(script, index); $('tbody', content).append(line); }); }); $(document).on('change', "input[name='section']", (e) => { const section = e.target.value; const category = $("input[name='category']:checked").val(); const search = $("input[name='search_script']").val().toLowerCase(); // Empty the table $('tbody', content).empty(); // Add filtered lines scripts .filter( (script) => (script.section.includes(section) || section === 'all') && (script.category.includes(category) || category === 'all') && (script.name.toLowerCase().includes(search) || script.description.toLowerCase().includes(search)), ) .forEach((script, index) => { const line = createScriptLine(script, index); $('tbody', content).append(line); }); }); $(document).on('input', "input[name='search_script']", (e) => { const search = e.target.value.toLowerCase(); const category = $("input[name='category']:checked").val(); const section = $("input[name='section']:checked").val(); // Empty the table $('tbody', content).empty(); // Add filtered lines scripts .filter( (script) => (script.section.includes(section) || section === 'all') && (script.category.includes(category) || category === 'all') && (script.name.toLowerCase().includes(search) || script.description.toLowerCase().includes(search)), ) .forEach((script, index) => { const line = createScriptLine(script, index); $('tbody', content).append(line); }); }); // Sauvegarder les paramètres. content.append( DC.UI.TextButton('scripts_refresh', 'Sauvegarder', () => { settings = newSettings; allDisabled = newAllDisabled; devMode = newDevMode; DC.LocalMemory.set(LIST_TAG, settings); DC.LocalMemory.set(ALL_DISABLED_TAG, allDisabled); DC.LocalMemory.set(DEV_MODE_TAG, devMode); location.replace('https://www.dreadcast.net/Main'); // Better than reload() with Chrome. }), ); content.append( $( `

⚠ Sauvegarder votre configuration va raffraichir la page.
Pensez à sauvegarder votre travail en cours avant.

`, ), ); const resetConfig = () => { const list = DC.LocalMemory.list(); list.forEach((key) => { DC.LocalMemory.delete(key); }); }; // Import/Export content.append( $( '
', ), ); $('#config_buttons', content).append( DC.UI.TextButton( 'config_reset', ' Réinitialiser', () => { resetConfig(); location.replace('https://www.dreadcast.net/Main'); }, ), ); $('#config_buttons', content).append( DC.UI.TextButton( 'config_import', ' Importer la configuration', () => { resetConfig(); const anchor = document.createElement('input'); anchor.style.display = 'none'; anchor.type = 'file'; anchor.accept = 'application.json'; anchor.onchange = (e) => { var reader = new FileReader(); reader.onload = (e) => { const data = JSON.parse(e.target.result); Object.keys(data).forEach((key) => { DC.LocalMemory.set(key, data[key]); }); }; reader.readAsText(e.target.files[0]); document.body.removeChild(anchor); location.replace('https://www.dreadcast.net/Main'); }; document.body.appendChild(anchor); anchor.click(); }, ), ); $('#config_buttons', content).append( DC.UI.TextButton( 'config_export', ' Exporter la configuration', function () { const list = DC.LocalMemory.list(); let data = {}; list.forEach((key) => { data[key] = DC.LocalMemory.get(key); }); const anchor = document.createElement('a'); anchor.style.display = 'none'; anchor.href = URL.createObjectURL( new Blob([JSON.stringify(data)], { type: 'application/json', }), ); anchor.download = 'dcsm_config.json'; document.body.appendChild(anchor); anchor.click(); document.body.removeChild(anchor); }, ), ); // Switch button pour désactiver tous les scripts. $('#scripts_all_switch', content).append( DC.UI.Checkbox( 'scripts_all_check', newAllDisabled, () => (newAllDisabled = !newAllDisabled), ), ); // Switch button pour le développeur mode. $('#developper_mode_switch', content).append( DC.UI.Tooltip( 'Attention, ces scripts sont encore en développement !', DC.UI.Checkbox( 'developper_mode_check', newDevMode, () => (newDevMode = !newDevMode), ), ), ); scripts .filter((script) => devMode || !script.experimental) .forEach((script, index) => { const line = createScriptLine(script, index); $('tbody', content).append(line); }); return DC.UI.PopUp('scripts_modal', 'Scripts & Skins', content); }, true, ), 5, ); }; // =============== $(document).ready(() => { initPersistence(); createIntro(); // Load list of scripts DC.Network.loadJson( 'https://raw.githubusercontent.com/Isilin/dreadcast-scripts/DCSMv1.2.0/data/scripts.json', ) .then((scripts) => { settings = synchronizeSettings(settings, scripts); // Create the interface. if (Util.isGame()) { createUI(scripts, settings); } // Load the scripts if (!allDisabled) { const context = Util.getContext(); scripts .filter((script) => script.section.includes(context)) .filter((script) => devMode || !script.experimental) .forEach((script) => { if (settings[script.id]) { DC.Network.loadScript(script.url) .then(() => { console.info( `DCSM - '${script.name}' script has been loaded successfully.`, ); }) .catch((err) => { console.error( `DCSM - Error loading '${script.name}' script: ` + err, ); }); } }); } }) .catch((err) => { console.error('DCSM - Error loading the list of scripts :' + err); }); }); });