[SCRIPT|TOOL] DashingDown


This is a script you can run in your browser to download the scenes’ text file from a game hosted at DashingDon or Cogdemos.ink.

:warning: Do no evil!

This is an honor-based system:

  • Do not use this script to keep illegal copies of games.
  • Do not use it on games whose author has requested not to peek into their code.
  • Preferably, use the script only on your own games or on those whose author has granted explicit permission.

:face_with_monocle: Observations

  • The script only automatizes something that is already possible to do manually.
  • The script will not download game assets, such as images and audio files.
  • It won’t work on compiled games.

Reasoning

Personally, when giving feedback on typos or awkward wording I like to be specific, pointing out the file name and if possible the code line. This means I’m constantly peeking into others’ code.


  • Easily reclaim your own lost game that only exists on DashingDon or Cogdemos.ink.
  • Easily access game files to study someone else’s code (code diving).
Installation

These instructions are for Chrome. However, they should be similar for other browsers.

  • Open the Bookmark Manager.
  • Create a new bookmark manually.
    • Name: DashingDown (or anything to your fancy)
    • URL (copy code below):
      javascript:function(){const e=window.location.href.replace("index.php",""),t=/dashingdon\.com/.test(e),s=/cogdemos\.ink/.test(e);if(!t&&!s)return void alert("You must be on Dashingdon or Cogdemos.ink to run the script.");if(t&&!/mygame/.test(e)||!/play/.test(e))return void alert("You must be on a game's page to run the script!");const o=e.match(/play\/(.+)/)[1].split("/")[1];try{JSZip}catch(e){const t=Object.assign(document.createElement("script"),{src:"https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js",crossorigin:"anonymous",referrerpolicy:"no-referrer"});document.head.appendChild(t)}setTimeout((async()=>{let t;if(/scenes\/?$/.test(e))t=[...document.querySelectorAll("a")],s&&(t=t.filter((e=>/^https:\/\/(www\.)?cogdemos.ink\/play/.test(e.href)&&e.href.endsWith(".txt"))));else{const o=`${e}${s?"/":""}scenes/`,r=await fetch(o).then((e=>e.status>=200&&e.status<300?e.text():null)),n=(new DOMParser).parseFromString(r,"text/html");if(s&&n.querySelector("main").innerText.toLowerCase().includes("does not share its source code"))return void alert("The author has opted to not share the game's source code.");t=[...n.querySelectorAll("a")],s&&(t=t.filter((e=>/^https:\/\/(www\.)?cogdemos.ink\/play/.test(e.href)&&e.href.endsWith(".txt"))))}const{files:r,promises:n}=t.reduce((function(t,o){const r=o.href.split("/").at(-1).trim();let n;s?n=o.href:(n=e.replace(/\/scenes\/?/,""),n=`${n}/scenes/${r}`);const c=fetch(n).then((e=>e.blob())).catch((e=>null));return t.files[r]=c,t.promises.push(c),t}),{files:{},promises:[]});await Promise.all(n);const c=new JSZip;Object.entries(r).forEach((([e,t])=>c.file(e,t,{binary:!0}))),c.generateAsync({type:"blob"}).then((e=>{const t=window.URL.createObjectURL(e),s=document.createElement("a");s.href=t,s.setAttribute("download",o+".zip"),s.click()}))}),500)}();
      
Use Instruction

Whenever you’re in a game’s page on DashignDon or Cogdemos.ink which you wish to download the text files, just click the bookmark you created and the script will fetch and zip all files for you.

Unminified Script Code

Here’s the unminified code of the script for anyone who’s interested.

(function () {
	const url = window.location.href.replace("index.php", "");
    const isDashingDown = /dashingdon\.com/.test(url);
    const isCogdemos = /cogdemos\.ink/.test(url);

	if (!isDashingDown && !isCogdemos) {
		alert('You must be on Dashingdon or Cogdemos.ink to run the script.');
		return;
	}

	if ((isDashingDown && !/mygame/.test(url)) || !/play/.test(url)) {
		alert("You must be on a game's page to run the script!");
		return;
	}

	const gameTitle = url.match(/play\/(.+)/)[1].split('/')[1];

	// add jszip to page
	try {
		JSZip;
	} catch (_) {
		const JSZipScript = Object.assign(document.createElement('script'), {
			src: 'https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js',
			// integrity:
			// 	'sha512-XMVd28F1oH/O71fzwBnV7HucLxVwtxf26XV8P4wPk26EDxuGZ91N8bsOttmnomcCD3CS5ZMRL50H0GgOHvegtg==',
			crossorigin: 'anonymous',
			referrerpolicy: 'no-referrer',
		});
		document.head.appendChild(JSZipScript);
	}

	setTimeout(async () => {
		let scenes;

		if (/scenes\/?$/.test(url)) {
			scenes = [...document.querySelectorAll('a')];

            if (isCogdemos) {
                scenes = scenes.filter(a => /^https:\/\/(www\.)?cogdemos.ink\/play/.test(a.href) && a.href.endsWith(".txt"));
            }
		} else {
            const _url = `${url}${isCogdemos?'/':''}scenes/`;

			const scenesPage = await fetch(_url).then(res =>
				res.status >= 200 && res.status < 300 ? res.text() : null
			);

            const parser = new DOMParser();

            const scenesDocument = parser.parseFromString(scenesPage, "text/html");

			if (isCogdemos && scenesDocument.querySelector("main").innerText.toLowerCase().includes("does not share its source code")) {
				alert("The author has opted to not share the game's source code.");
				return;
			}

            scenes = [...scenesDocument.querySelectorAll('a')];

            if (isCogdemos) {
                scenes = scenes.filter(a => /^https:\/\/(www\.)?cogdemos.ink\/play/.test(a.href) && a.href.endsWith(".txt"));
            }
		}

		const { files, promises } = scenes.reduce(
			function (acc, a) {
				const filename = a.href.split("/").at(-1).trim();

				let _url;

				if (isCogdemos) {
					_url = a.href;
				} else {
					_url = url.replace(/\/scenes\/?/, "");
					_url = `${_url}/scenes/${filename}`;
				}

				const blob = fetch(_url)
					.then(data => data.blob())
					.catch(e => null);

				acc.files[filename] = blob;
				acc.promises.push(blob);

				return acc;
			},
			{
				files: {},
				promises: [],
			}
		);

		await Promise.all(promises);

		// save to zip
		const zip = new JSZip();

		Object.entries(files).forEach(([filename, data]) =>
			zip.file(filename, data, { binary: true })
		);

		zip.generateAsync({ type: 'blob' }).then(data => {
			const objectURL = window.URL.createObjectURL(data);
			const a = document.createElement('a');
			a.href = objectURL;
			a.setAttribute('download', gameTitle + '.zip');
			a.click();
		});
	}, 500);
})();
23 Likes

Would it be possible to update it to work on cogdemos? I’ve tried to edit your code for that, but I’m too inept for it to work :grimacing:

1 Like

I’ll take a look when I have some time.

1 Like

The script has been updated to also work on Cogdemos.ink.

1 Like

It’s not working on my end, it creates the zip with the name of the game, but there’s no files, I’ve tried it with a few and they’re all empty.

It does work, but some authors have chosen not to share the source code of their games, Cogdemos offers this option to them. I’ve modified the code so it warns you in such cases instead of downloading an empty zip.

1 Like

The content of all the txt files I got is as follow:

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>404 Not Found</title>
</head><body>
<h1>Not Found</h1>
<p>The requested URL was not found on this server.</p>
<hr>
<address>Apache/2.4.52 (Ubuntu) Server at dashingdon.com Port 443</address>
</body></html>

Can I get more insight on this? I’m not sure where I did it wrong.

I figured out the issue. I introduced a bug when I adjusted the script to also work on Cogdemos. It should work now. @Silver_Eye

1 Like

Alright, all the files it fetches now are normal. Thanks

It’s not that, I know how to access the scenes manually, I’ve done so to see if it was actually locked, I’ve also cleared my cache in case it was that, as well as using a different browser and it’s still empty idk why it doesn’t work for me; I guess I’ll resign myself to do it manually.

What’s the game? Post the link here, please.

For posterity’s sake, I had a problem where Firefox was showing a blank page saying “true” rather than downloading the file. I fixed it by changing the code to read like this:

javascript:(function(){const e=window.location.href.replace("index.php",""),t=/dashingdon\.com/.test(e),s=/cogdemos\.ink/.test(e);if(!t&&!s)return void alert("You must be on Dashingdon or Cogdemos.ink to run the script.");if(t&&!/mygame/.test(e)||!/play/.test(e))return void alert("You must be on a game's page to run the script!");const r=e.match(/play\/(.+)/)[1].split("/")[1];try{JSZip}catch(e){const t=Object.assign(document.createElement("script"),{src:"https://cdnjs.cloudflare.com/ajax/libs/jszip/3.10.1/jszip.min.js",crossorigin:"anonymous",referrerpolicy:"no-referrer"});document.head.appendChild(t)}setTimeout((async()=>{let t;if(/scenes\/?$/.test(e))t=[...document.querySelectorAll("a")],s&&(t=t.filter((e=>e.href.startsWith("https://www.cogdemos.ink/play")&&e.href.endsWith(".txt"))));else{const r=`${e}${s?"/":""}scenes/`,o=await fetch(r).then((e=>e.status>=200&&e.status<300?e.text():null)),n=(new DOMParser).parseFromString(o,"text/html");if(s&&n.querySelector("main").innerText.toLowerCase().includes("does not share its source code"))return void alert("The author has opted to not share the game's source code.");t=[...n.querySelectorAll("a")],s&&(t=t.filter((e=>e.href.startsWith("https://www.cogdemos.ink/play")&&e.href.endsWith(".txt"))))}const{files:o,promises:n}=t.reduce((function(t,r){const o=r.href.split("/").at(-1).trim();let n;s?n=r.href:(n=e.replace(/\/scenes\/?/,""),n=`${n}/scenes/${o}`);const i=fetch(n).then((e=>e.blob())).catch((e=>null));return t.files[o]=i,t.promises.push(i),t}),{files:{},promises:[]});await Promise.all(n);const i=new JSZip;Object.entries(o).forEach((([e,t])=>i.file(e,t,{binary:!0}))),i.generateAsync({type:"blob"}).then((e=>{const t=window.URL.createObjectURL(e),s=document.createElement("a");s.href=t,s.setAttribute("download",r+".zip"),s.click()}))}),500)}());

Basically, it just uses parentheses instead of the exclamation point before “function”. Apparently a known issue with Firefox bookmarklets.

1 Like

https://cogdemos.ink/play/jjcb/a-tale-of-heroes

This is the first I tried it with, but when it didn’t work I tried it with several of the public games on cogdemos, and none have worked for me: I’m using Opera and changed to Edge as well later on, if that matters.

That’s weird. I think they changed something on cogdemos, the URLs are different and it broke the script. In any case, I fixed it again. It should work now.

1 Like

Now nothing downloads, there’s no pop up indicating anything either :worried:

I get it. It’s because you’re already at the scenes page instead of the game page. Hopefully this is the last bug. Try again now.

Btw, you don’t have to e at the scenes page to run the script (but it should work there as well).

Sorry for the late response, but I was not in scenes when I tried it, I’ll try it tomorrow when I’m not working to see if I can or not.

Yeah still unable to, but you don’t need to bother if it’s just a me thing, as I’ve said I can do it manually.