mekhanoidy-tools/src/db_extractor/db_extractor.cpp
2017-07-28 20:47:18 +03:00

175 lines
No EOL
5.2 KiB
C++

/*
* AIM db_extractor
* Copyright (C) 2015 lzwdgc
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "db.h"
#include <fstream>
#include <Windows.h>
#include <buffer.h>
#include <primitives/filesystem.h>
void open_db(string path, db &db)
{
db.t.load(buffer(read_file(path + ".tab")));
db.load(buffer(read_file(path + ".ind")));
buffer b(read_file(path + ".dat"));
for (auto &v : db.values)
v.load_fields(db.t, b);
}
string str2utf8(string codepage_str)
{
int size = MultiByteToWideChar(CP_ACP, MB_COMPOSITE, codepage_str.c_str(),
codepage_str.length(), nullptr, 0);
std::wstring utf16_str(size, '\0');
MultiByteToWideChar(CP_ACP, MB_COMPOSITE, codepage_str.c_str(),
codepage_str.length(), &utf16_str[0], size);
int utf8_size = WideCharToMultiByte(CP_UTF8, 0, utf16_str.c_str(),
utf16_str.length(), nullptr, 0,
nullptr, nullptr);
std::string utf8_str(utf8_size, '\0');
WideCharToMultiByte(CP_UTF8, 0, utf16_str.c_str(),
utf16_str.length(), &utf8_str[0], utf8_size,
nullptr, nullptr);
return utf8_str;
}
void create_sql(string path, const db &db)
{
ofstream ofile(path + ".sql");
if (!ofile)
return;
string master_table_name = "DB_TABLE_LIST";
const string id = "ID";
const string row_type = "TEXT_ID";
// db master table
ofile << "drop table if exists " << master_table_name << ";\n";
ofile << "create table \"" << master_table_name << "\"\n";
ofile << "(\n";
ofile << " \"" + str2utf8(id) + "\" INTEGER,\n";
ofile << " \"" + str2utf8(row_type) + "\" TEXT\n";
ofile << ");\n";
ofile << "\n";
// db tables
for (auto &table : db.t.tables)
{
auto &t = table.second;
string name = str2utf8(t.name);
ofile << "drop table if exists " << name << ";\n";
ofile << "create table \"" << name << "\"\n";
ofile << "(\n";
string s;
s += " \"" + str2utf8(id) + "\" INTEGER,\n";
s += " \"" + str2utf8(row_type) + "\" TEXT,\n";
for (auto &f : db.t.fields)
{
if (f.second.table_id != t.id)
continue;
s += " \"" + str2utf8(f.second.name) + "\" " + getSqlType(f.second.type) + ",\n";
}
s.resize(s.size() - 2);
ofile << s << "\n";
ofile << ");\n";
ofile << "\n";
}
// db master table
for (auto &table : db.t.tables)
{
static int idx = 1;
ofile << "insert into \"" << master_table_name << "\" values (";
ofile << "'" << idx++ << "', ";
ofile << "'" << str2utf8(table.second.name) << "'";
ofile << ");\n";
}
// db tables
map<int,int> idx;
for (auto &v : db.values)
{
auto tbl = db.t.tables.find(v.table_id);
if (tbl == db.t.tables.end())
continue;
ofile << "insert into \"" << str2utf8(tbl->second.name) << "\" (";
string s;
s += "'" + str2utf8(id) + "', ";
s += "'" + str2utf8(row_type) + "', ";
for (auto &f : v.fields)
{
auto fld = db.t.fields.find(f.field_id);
s += "'" + str2utf8(fld->second.name) + "', ";
}
s.resize(s.size() - 2);
ofile << s << ") values (";
s.clear();
s += "'" + to_string(idx[v.table_id]++) + "', ";
s += "'" + str2utf8(v.name) + "', ";
for (auto &f : v.fields)
{
s += "'";
auto fld = db.t.fields.find(f.field_id);
switch (fld->second.type)
{
case FieldType::String:
s += str2utf8(f.s.c_str());
break;
case FieldType::Integer:
s += to_string(f.i);
break;
case FieldType::Float:
s += to_string(f.f);
break;
default:
assert(false);
}
s += "', ";
}
s.resize(s.size() - 2);
ofile << s << ");\n";
}
}
int main(int argc, char *argv[])
try
{
if (argc != 2)
{
cout << "Usage:\n" << argv[0] << " path/to/aim_game/data/db" << "\n" << argv[0] << " path/to/aim_game/data/quest" << "\n";
return 1;
}
string path = argv[1];
db db;
open_db(path, db);
create_sql(path, db);
return 0;
}
catch (std::exception &e)
{
printf("error: %s\n", e.what());
return 1;
}
catch (...)
{
printf("error: unknown exception\n");
return 1;
}