From 027057ad8ec0f2287e01616825a2cebc9cf4c3a9 Mon Sep 17 00:00:00 2001 From: root <182859762@qq.com> Date: Sun, 7 Apr 2024 14:14:39 +0800 Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90=E6=B8=B8=E6=88=8F=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/cheat-builder/build.js | 1 - tools/cheat-builder/webdb.js | 71 ++++++++++++++++++++++++++++++++++++ 2 files changed, 71 insertions(+), 1 deletion(-) create mode 100644 tools/cheat-builder/webdb.js diff --git a/tools/cheat-builder/build.js b/tools/cheat-builder/build.js index bd42276..0db2505 100644 --- a/tools/cheat-builder/build.js +++ b/tools/cheat-builder/build.js @@ -1,4 +1,3 @@ -const readxml = require("./xml"); const readCht = require("./cht"); const fs = require("fs"); const { readFile, writeFile, access } = require("fs/promises"); diff --git a/tools/cheat-builder/webdb.js b/tools/cheat-builder/webdb.js new file mode 100644 index 0000000..8608764 --- /dev/null +++ b/tools/cheat-builder/webdb.js @@ -0,0 +1,71 @@ +const readxml = require("./xml"); +const {readFile, writeFile} = require("fs/promises"); + +/** @param {string} tr */ +const readItem = tr => { + let ret = {}, start = 0, token = null, state = 0, tmp = null; + do{ + if( tr.charAt(start) === '"') { + let end = tr.indexOf('"', start + 1); + if( end < 0 ) throw new SyntaxError(`no match quito [${tr}]`); + token = tr.slice(start+1, end); + start = end + 2; + } + else { + let end = tr.indexOf(" ", start); + if( end < 0 ) break; + token = tr.slice(start, end); + start = end + 1; + } + + if( state === 0 ){ + tmp = token; + state = 1; + } + else { + ret[ tmp ] = token; + state = 0; + } + }while( true ); + if( state == 0 ) throw new SyntaxError(`invalid at [${tr}], ret is ${JSON.stringify(ret)}`); + ret[ tmp ] = tr.slice( start ); + ret.name = ret.name.slice(0, -4); + return ret; +} + +const readDat = s => { + return s.match( /^\trom\s.*$/mg ).map( r => readItem( r.slice(1+"rom ( ".length, r.length-" )".length) ) ); +} + +const start = async() => { + const data = await readFile("/root/oafb-tool/material/gba.xml"); + const xml = readxml( data.toString() ); + const rom = await readFile("./cover.dat"); + const roms = readDat( rom.toString() ); + const romidx = roms.reduce( (r, v) => { + r[ `${v.crc.toLowerCase().padStart(8,"0")}${v.sha1.toLowerCase()}` ] = v; + return r; + }, {}); + + const db = {}; + for( let rom of xml.children ){ + const rominfo = rom.children; + const description = rominfo.find( t => t.name === "description" )?.children[0]; + const publisher = rominfo.find( t => t.name === "publisher" )?.children[0]; + const year = rominfo.find( t => t.name === "year" )?.children[0]; + const serial = rominfo.find( t => t.name === "info" && t.attributes.name === "serial" )?.attributes.value; + const part = rominfo.find( t => t.name === "part" )?.children.find( t => t.name === "dataarea" && t.attributes.name === "rom" )?.children[0]; + if( part && serial ){ + let ren = romidx[ `${part.attributes.crc.toLowerCase().padStart(8, "0")}${part.attributes.sha1.toLowerCase()}` ]; + if( ren ){ + let out = { file: ren.name, publisher, year, name: rom.attributes.name }; + serial.match(/AGB-[A-Z0-9]{4}/g)?.forEach( ser => db[ser.slice(-4)] = out ); + } + else console.error( "no match rom", rom.attributes.name );// 可以手动修复 + } + else console.error( "invalid rom", rom.attributes.name );// 不做修复 + } + await writeFile("/root/oafb-tool/material/webdb.json", JSON.stringify(db, 0)); +} + +start();