Created
August 26, 2023 09:23
-
-
Save Hipnosis183/6816bdc781ea4a4d2118ac3afeb3bc3c to your computer and use it in GitHub Desktop.
Million Versus Online - Asset Downloader
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Requires NPM package 'node-fetch'. | |
// npm install node-fetch@2 | |
const fetch = require('node-fetch'); | |
const fs = require('fs'); | |
const http = require('http'); | |
const util = require('util'); | |
const pipeline = util.promisify(require('stream').pipeline); | |
// Import file list. | |
let filesGot = 0; | |
let filesTotal = 0; | |
const filesList = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 51, 52, 53, 54, 60, 61, 62, 63, 64, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 152, 153, 157, 159, 162, 163, 175, 176, 179, 180, 181, 182, 183, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199]; | |
// Game server information. | |
const serverHost = 'http://m-versus.com/'; | |
const serverUrl = `${serverHost}version/android/`; | |
http.createServer().listen(3000, '127.0.0.1', async () => { | |
console.log(`[Million Versus Online - Assets Downloader]\n`); | |
await getResources(); | |
//await getWebsite(); | |
console.log(`[DONE] ${filesGot}/${filesTotal} files.`); | |
process.exit(0); // Terminate server process. | |
}); | |
const getResources = async () => { | |
console.log(`[RESOURCES]`); | |
filesTotal += filesList.length; | |
const pathResources = createPath('jp.co.ateam.mva/files'); | |
for (let [i, z] of filesList.entries()) { | |
const zoneVersion = await fetch(`${serverUrl}get_zone_version.php?z=${z}`, { method: 'GET' }); | |
const $zoneVersion = hexNum(strHex((await zoneVersion.buffer()).toString('latin1')).slice(0, 8)); | |
if ($zoneVersion) { | |
const fileName = `zone${z}`; | |
const fileUrl = `${serverUrl}get_data.php?mode=zone&version=${$zoneVersion}&z=${z}`; | |
console.log(`[${i + 1}/${filesList.length}] ${fileName}`); | |
if (await fileDownload(fileName, fileUrl, pathResources)) { filesGot++; }; } | |
} console.log(); | |
} | |
const getWebsite = async () => { | |
console.log(`[WEBSITE]`); | |
filesTotal += 980; | |
const pathWebsite = createPath('m-versus.com/bull/character_make/image_gif'); | |
const charSex = ['01', '02']; | |
const charColor = ['00', '01', '02', '03', '04', '05', '06']; | |
const charHair = ['00', '01', '02', '03', '04', '05', '06']; | |
const charHColor = ['00', '01', '02', '03', '04', '05', '06', '07', '08', '09']; | |
for (let s of charSex) { | |
for (let c of charColor) { | |
for (let h of charHair) { | |
for (let hc of charHColor) { | |
const fileName = `${c}_${s}_${h}_${hc}.gif`; | |
const fileUrl = `${serverHost}bull/character_make/image_gif/${fileName}`; | |
if (await fileDownload(fileName, fileUrl, pathWebsite)) { filesGot++; }; | |
}}}} console.log(); | |
} | |
const createPath = (output) => { | |
// Create output path if it doesn't exist. | |
const outputPath = `./${output}/`; | |
if (!fs.existsSync(outputPath)) { fs.mkdirSync(outputPath, { recursive: true }); } | |
return outputPath; | |
} | |
const fileDownload = async (name, url, output) => { | |
try { // Download data from url. | |
const fileData = await fetch(url, { method: 'GET' }); | |
// Write downloaded data into a new file stream. | |
await pipeline(fileData.body, fs.createWriteStream(output + name)); | |
console.log(`[OK] >>${output.slice(1)}${name}`); return 1; | |
} catch { // Failed to download file. | |
console.log(`[ERROR] ${output.slice(1)}${name} (${url})`); return 0; | |
} | |
} | |
// Return number representation of the given byte string. | |
const hexNum = (s) => { | |
const n = s.match(/../g).reverse().join(''); | |
return parseInt(`0x${n}`, 16); | |
} | |
// Return byte representation of the given string. | |
const strHex = (s) => { | |
return Array.from(s, b => b.charCodeAt(0).toString(16).padStart(2, '0')).join('').toUpperCase(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment