Swarmsimhax
<!doctype html>
<html>
<head>
<style>
body {
font-family: 'Courier New', Courier, monospace;
background-color: #000000;
color: white;
margin: 0;
padding: 20px;
}
h1, h3, h4 {
color: white;
}
textarea {
background-color: #800080;
color: white;
border: 1px solid #white;
border-radius: 5px;
padding: 5px;
font-family: 'Courier New', Courier, monospace;
position: relative;
}
hr {
border: none;
height: 1px;
background-color: #800080;
margin: 10px 0;
}
.encoded-container {
position: relative;
display: inline-block;
}
.copy-button, .clear-button, .paste-button {
position: absolute;
background-color: #800080;
color: white;
border: 1px solid black;
border-radius: 3px;
font-size: 12px;
cursor: pointer;
width: 70px;
text-align: center;
}
.copy-button:hover, .clear-button:hover, .paste-button:hover {
background-color: #993399;
}
.title-container {
display: flex;
align-items: center;
gap: 10px;
}
.input-container {
position: relative;
display: inline-block;
}
.paste-button {
top: 3px;
right: 3px;
}
.clear-button {
bottom: 3px;
right: 3px;
}
.copy-button {
top: 3px;
right: 3px;
}
</style>
</head>
<body>
<h1>Swarmsim Save Editor</h1>
<hr/>
<h3>Input (Save Data):</h3>
<div class="input-container">
<textarea rows=4 cols=80 id="input" oninput="decode(this)"></textarea>
<button class="paste-button" onclick="pasteFromClipboard()">Paste</button>
<button class="clear-button" onclick="clearInput()">Clear</button>
</div>
<hr/>
<h4>Error:</h4>
<textarea rows=1 cols=80 readonly id="error"></textarea>
<hr/>
<h4>Version:</h4>
<textarea rows=1 cols=80 readonly id="version" oninput="autoEncode()"></textarea>
<hr/>
<h4>JSON:</h4>
<textarea rows=10 cols=80 id="json" oninput="autoEncode()"></textarea>
<hr/>
<h3>Encoded Save:</h3>
<div class="encoded-container">
<textarea rows=5 cols=80 readonly id="encoded"></textarea>
<button class="copy-button" onclick="copyToClipboard()">Copy</button>
</div>
<hr/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lz-string/1.4.4/lz-string.min.js"></script>
<script>
const outputNames = ['version', 'json', 'error', 'encoded'];
const outputs = {};
for (let name of outputNames) {
outputs[name] = document.getElementById(name);
}
function decode(el) {
clearOutputs();
try {
const raw = el.value.replace(/\s+/g, '');
const [encodedVersion, encodedBody] = raw.split('|');
const version = atob(encodedVersion);
outputs.version.value = version;
const prefix = btoa("Cheater :(\n\n");
const encoded = encodedBody.substring(prefix.length);
const decompressed = LZString.decompressFromBase64(encoded);
const json = JSON.parse(decompressed);
outputs.json.value = JSON.stringify(json, null, 2);
autoEncode();
} catch (e) {
outputs.error.value = e.message;
throw e;
}
}
function autoEncode() {
try {
const version = outputs.version.value;
const jsonText = outputs.json.value;
if (!version || !jsonText) {
outputs.encoded.value = '';
return;
}
const versionEncoded = btoa(version);
const jsonCompressed = LZString.compressToBase64(jsonText);
const prefix = btoa("Cheater :(\n\n");
const encodedSave = `${versionEncoded}|${prefix}${jsonCompressed}`;
outputs.encoded.value = encodedSave;
} catch (e) {
outputs.error.value = e.message;
}
}
function copyToClipboard() {
const encodedSave = outputs.encoded.value;
if (encodedSave) {
navigator.clipboard.writeText(encodedSave).then(() => {
alert("Encoded Save copied to clipboard!");
}).catch((err) => {
alert("Failed to copy text: " + err);
});
} else {
alert("Encoded Save is empty!");
}
}
function clearOutputs() {
for (let name of outputNames) {
outputs[name].value = '';
}
}
function clearInput() {
document.querySelector('textarea').value = '';
}
function pasteFromClipboard() {
navigator.clipboard.readText().then(text => {
const textarea = document.querySelector('#input');
textarea.value = text;
decode(textarea); // Automatically decode after pasting
}).catch(err => {
alert("Failed to read clipboard contents: " + err);
});
}
</script>
</body>
</html>