gd-level-to-json-cli
Version:
Convert a Geometry Dash level's data to a readable JSON format.
115 lines (98 loc) • 3.95 kB
JavaScript
const fs = require("fs");
const path = require("path");
const arg = require("arg");
const { default: fetch } = require("node-fetch");
const { RateLimiter } = require("limiter");
const convert = require("gd-level-to-json");
const limiter = new RateLimiter({
tokensPerInterval: 100,
interval: 300000
});
function parseResponse(responseBody) {
if (!responseBody || responseBody == "-1") return {};
if (responseBody.startsWith("\nWarning:")) responseBody = responseBody.split("\n").slice(2).join("\n").trim();
if (responseBody.startsWith("<br />")) responseBody = responseBody.split("<br />").slice(2).join("<br />").trim();
let response = responseBody.split("#")[0].split(":");
let res = {};
for (let i = 0; i < response.length; i += 2)
res[response[i]] = response[i + 1];
return res;
}
async function getLevelFromID(id, server) {
let data;
let remainingRequests = await limiter.removeTokens(1);
if (remainingRequests < 0)
return "-2";
else {
try {
data = await fetch(server + "/downloadGJLevel22.php", {
method: "POST",
body: new URLSearchParams({ secret: "Wmfd2893gb7", gameVersion: "21", binaryVersion: "35", levelID: id })
}).then(r => r.text());
if (data == "-1")
return "-1";
data = parseResponse(data)[4] ? parseResponse(data)[4] : "-1";
} catch {
return "-1";
}
}
return data;
}
async function cli(argv) {
try {
let args = arg({
"--output": String,
"--file": String,
"--id": String,
"--server": String,
"-o": "--output",
"-f": "--file",
"-i": "--id",
"-s": "--server",
}, { argv });
let options = {
output: args["--output"],
file: args["--file"],
id: args["--id"],
server: args["--server"],
}
if (!argv[0]) {
return console.log([
" _ _ _ _ ____ ___ _ _ ",
" | | _____ _____| | | |_ ___ | / ___| / _ \\| \\ | |",
" | | / _ \\ \\ / / _ \\ | | __/ _ \\ _ | \\___ \\| | | | \\| |",
" | |__| __/\\ V / __/ | | || (_) | | |_| |___) | |_| | |\\ |",
" |_____\\___| \\_/ \\___|_| \\__\\___/ \\___/|____/ \\___/|_| \\_|",
"",
"Convert a Geometry Dash level's data to a readable JSON format.",
"",
"Format: leveltojson (options)",
"",
"Options:",
"--------------------------------------------------------------------------------",
"Output",
"--output (-o): The optional path to an output level JSON file.",
"--------------------------------------------------------------------------------",
"Local",
"--file (-f): The path to a level text file.",
"--------------------------------------------------------------------------------",
"Online",
"--id (-i): The ID of the level you are getting the data of.",
"--server (-s): The optional endpoint to a Geometry Dash server. (With http://)",
"--------------------------------------------------------------------------------"
].join("\n"));
}
if (options.file && (options.id || options.server))
return console.log("You cannot have local and online options at the same time.");
let data = options.id ? convert(await getLevelFromID(options.id, options.server ? options.server : "http://www.boomlings.com/database")) : convert(fs.readFileSync(path.resolve(options.file)).toString());
if (data == "-1")
return console.log("An error occured while retrieving level data.");
if (data == "-2")
return console.log("You are being rate limited.");
fs.writeFileSync(options.output ? path.resolve(options.output) : path.resolve(process.cwd(), "level.json"), JSON.stringify(data, null, "\t"));
console.log("Data written to " + (options.output ? path.resolve(options.output) : path.resolve(process.cwd(), "level.json")) + ".");
} catch {
console.log("An error occured! Please try again.");
}
}
module.exports = cli;