forked from sent/waves
175 lines
6.1 KiB
HTML
175 lines
6.1 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="en">
|
|
|
|
|
|
<head>
|
|
<meta charset="utf8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
<meta name="description" content="Extract the original Scratch project from HTML or zip files generated by TurboWarp Packager, forkphorus packager, or HTMLifier.">
|
|
<meta name="theme-color" content="#ff4c4c">
|
|
<title>Unpackager for TurboWarp, forkphorus, and HTMLifier</title>
|
|
<style>
|
|
:root {
|
|
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
}
|
|
@media (prefers-color-scheme: dark) {
|
|
:root {
|
|
color: #eee;
|
|
background-color: #111;
|
|
color-scheme: dark;
|
|
}
|
|
a {
|
|
color: #4af;
|
|
}
|
|
}
|
|
|
|
h1, h2, h3 {
|
|
font-weight: normal;
|
|
}
|
|
|
|
main {
|
|
max-width: 480px;
|
|
margin: auto;
|
|
}
|
|
|
|
.code {
|
|
font-family: monospace;
|
|
}
|
|
|
|
input[type=file] {
|
|
width: 100%;
|
|
}
|
|
|
|
.download-section a {
|
|
display: block;
|
|
}
|
|
|
|
.drag-effect {
|
|
opacity: 0;
|
|
position: fixed;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
box-sizing: border-box;
|
|
border: 10px dashed rgb(110, 110, 255);
|
|
pointer-events: none;
|
|
transition: .2s opacity;
|
|
}
|
|
.dragging .drag-effect {
|
|
opacity: 1;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<main>
|
|
<h1>Unpackager for TurboWarp, forkphorus, and HTMLifier</h1>
|
|
|
|
<p>Select or drop an HTML or zip file generated by <a href="https://packager.turbowarp.org/">TurboWarp Packager</a>, <a href="https://forkphorus.github.io/packager/">forkphorus packager</a>, or <a href="https://sheeptester.github.io/htmlifier/">HTMLifier</a> and the unpackager will extract the original Scratch project.</p>
|
|
|
|
<input type="file" class="file-input" accept=".zip, .html" multiple autocomplete="off">
|
|
|
|
<p class="download-section"></p>
|
|
|
|
<h2>Limitations</h2>
|
|
<p>Having access to a packaged version of a project does not necessarily mean that you are legally allowed to unpackage the project, modify it, or redistribute it. We are not lawyers and will not provide legal advice on this matter.</p>
|
|
<p>The TurboWarp Packager removes comments and script positions from packaged projects, so you may have to manually clean up the scripts.</p>
|
|
<p>HTMLifier converts Scratch 2 projects to Scratch 3, so some information may be lost from those projects.</p>
|
|
|
|
<h2>Bugs</h2>
|
|
<p>Report bugs (such as files that couldn't be unpackaged) <a href="https://github.com/TurboWarp/unpackager/issues">on GitHub</a>.</p>
|
|
|
|
<h2>Code</h2>
|
|
<p>Unpackager is <a href="https://github.com/TurboWarp/unpackager">open source</a>.</p>
|
|
|
|
<h2>Privacy</h2>
|
|
<p>Files are processed locally on your computer and never sent to any server.</p>
|
|
|
|
<h2>I don't want people to unpackage my projects</h2>
|
|
<p>All of these project packagers work by embedding the project file and a project runner into the same file. When you open the file, some code passes that project file to the project runner. The unpackager simply does the same process.</p>
|
|
<p>This problem is not unique to Scratch projects. Anything web-based has similar issues, as do game engines like Unity.</p>
|
|
<p>We know this makes some people uncomfortable, but realistically you shouldn't worry. If you're worried about people stealing your assets, copyright law still exists. If you're selling something, pirates were never going to pay. Cheaters will always find a way. All of these problems existed long before the unpackager did.</p>
|
|
<p>If this still bothers you, the topic to research is "DRM".</p>
|
|
</main>
|
|
|
|
<div class="drag-effect"></div>
|
|
|
|
<script src="dependencies/jszip.min.js"></script>
|
|
<script src="unpackager.js"></script>
|
|
<script>
|
|
(function() {
|
|
'use strict';
|
|
|
|
const fileInput = document.querySelector('.file-input');
|
|
const downloadSection = document.querySelector('.download-section');
|
|
|
|
const processFile = async (file) => {
|
|
const unpackaged = await unpackage(file);
|
|
const type = unpackaged.type;
|
|
const data = unpackaged.data;
|
|
const name = `${file.name}.${type}`;
|
|
|
|
const blob = new Blob([data], {
|
|
type: `application/x.scratch.${type}`
|
|
});
|
|
const url = URL.createObjectURL(blob);
|
|
|
|
const link = document.createElement('a');
|
|
link.href = url;
|
|
link.download = name;
|
|
link.textContent = `Download ${name} (${(blob.size / 1000 / 1000).toFixed(2)}MB)`;
|
|
downloadSection.appendChild(link);
|
|
link.click();
|
|
};
|
|
|
|
const processInput = async () => {
|
|
const file = fileInput.files[0];
|
|
if (!file) {
|
|
return;
|
|
}
|
|
|
|
while (downloadSection.firstChild) {
|
|
URL.revokeObjectURL(downloadSection.firstChild.href);
|
|
downloadSection.firstChild.remove();
|
|
}
|
|
|
|
try {
|
|
for (const file of fileInput.files) {
|
|
await processFile(file);
|
|
}
|
|
} catch (e) {
|
|
console.error(e);
|
|
alert(`An error occurred, please report this with the file you tried to unpackage.\n\n${e}`);
|
|
}
|
|
};
|
|
|
|
fileInput.addEventListener('change', (e) => {
|
|
processInput();
|
|
});
|
|
|
|
document.documentElement.addEventListener('drop', (e) => {
|
|
document.documentElement.classList.remove('dragging');
|
|
if (e.dataTransfer.types.includes('Files')) {
|
|
e.preventDefault();
|
|
fileInput.files = e.dataTransfer.files;
|
|
processInput();
|
|
}
|
|
});
|
|
|
|
document.documentElement.addEventListener('dragleave', (e) => {
|
|
document.documentElement.classList.remove('dragging');
|
|
});
|
|
|
|
document.documentElement.addEventListener('dragover', (e) => {
|
|
if (e.dataTransfer.types.includes('Files')) {
|
|
document.documentElement.classList.add('dragging');
|
|
e.preventDefault();
|
|
e.dataTransfer.dropEffect = 'copy';
|
|
}
|
|
});
|
|
}());
|
|
</script>
|
|
</body>
|
|
</html>
|