diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..8c64a62 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "dep/dbmgr"] + path = dep/dbmgr + url = https://github.com/aimrebirth/DatabaseManager.git diff --git a/CMakeLists.txt b/CMakeLists.txt index bc5e2d0..66aec6c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,4 +15,7 @@ if (MSVC) #set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT") endif(MSVC) +include_directories(dep/dbmgr/include) +add_subdirectory(dep/dbmgr) + add_subdirectory(src) \ No newline at end of file diff --git a/dep/dbmgr b/dep/dbmgr new file mode 160000 index 0000000..8a5126c --- /dev/null +++ b/dep/dbmgr @@ -0,0 +1 @@ +Subproject commit 8a5126cd1a2769780bd4e05c18d553f2bcb60f56 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d27e809..9d6edf4 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -6,6 +6,7 @@ add_executable(db_extractor ${db_extractor_src}) file(GLOB obj_extractor_src "obj_extractor/*") add_executable(obj_extractor ${obj_extractor_src}) +target_link_libraries(obj_extractor DatabaseManager) file(GLOB script2txt_src "script2txt/*") add_executable(script2txt ${script2txt_src}) diff --git a/src/obj_extractor/obj_extractor.cpp b/src/obj_extractor/obj_extractor.cpp index e0e24d9..4870b2a 100644 --- a/src/obj_extractor/obj_extractor.cpp +++ b/src/obj_extractor/obj_extractor.cpp @@ -16,44 +16,193 @@ * along with this program. If not, see . */ +#include +#include #include +#include +#include #include #include #include "objects.h" #include "other.h" -void read_mmo(string fn) +#include + +using namespace std; + +struct storage { + Objects objects; + MechGroups mgs; + MapGoods mg; + MapMusic mm; + MapSounds ms; +}; + +storage read_mmo(string fn) +{ + storage s; FILE *f = fopen(fn.c_str(), "rb"); if (!f) - return; - Objects objects; - objects.load(f); - MechGroups mgs; - mgs.load(f); + return s; + s.objects.load(f); + s.mgs.load(f); if (feof(f)) { // custom maps? fclose(f); - return; + return s; } - MapGoods mg; - mg.load(f); - MapMusic mm; - mm.load(f); - MapSounds ms; - ms.load(f); + s.mg.load(f); + s.mm.load(f); + s.ms.load(f); fclose(f); + return s; +} + +void write_mmo(string db, const storage &s) +{ + using namespace polygon4; + using namespace polygon4::detail; + + auto storage = initStorage(db); + storage->load(); + + int map_id = 1; + + for (auto &seg : s.objects.segments) + { + if (seg->segment_type == SegmentType::SHELL) + { + SegmentObjects *segment = (SegmentObjects *)seg; + set objs; + std::map bld_ids; + std::map coord_ids; + for (auto &object : segment->objects) + objs.insert(object.name1); + for (auto &o : objs) + { + auto iter = find_if(storage->buildings.begin(), storage->buildings.end(), [&](const decltype(Storage::buildings)::value_type &p) + { + return p.second->text_id == o; + }); + if (iter == storage->buildings.end()) + { + auto bld = storage->addBuilding(); + bld->text_id = o; + bld_ids[o] = bld->id; + } + else + bld_ids[o] = iter->second->id; + } + for (auto &object : segment->objects) + { + MapBuilding mb; + mb.text_id = object.name2; + mb.building = storage->buildings[bld_ids[object.name1]]; + auto iter = find_if(storage->coordinates.begin(), storage->coordinates.end(), [&](const decltype(Storage::coordinates)::value_type &p) + { + Coordinate c; + c.x = object.position.x; + c.y = object.position.y; + c.z = object.position.z; + return *p.second.get() == c; + }); + if (iter == storage->coordinates.end()) + { + auto c = storage->addCoordinate(); + c->x = object.position.x; + c->y = object.position.y; + c->z = object.position.z; + mb.coordinate = c; + } + else + mb.coordinate = iter->second; + auto i = find_if(storage->mapBuildings.begin(), storage->mapBuildings.end(), [&](const decltype(Storage::mapBuildings)::value_type &p) + { + return *p.second.get() == mb; + }); + if (i == storage->mapBuildings.end()) + { + auto mb2 = storage->addMapBuilding(storage->maps[map_id].get()); + mb.id = mb2->id; + *mb2.get() = mb; + } + } + } + if (seg->segment_type == SegmentType::SURFACE || + seg->segment_type == SegmentType::STONE || + seg->segment_type == SegmentType::EXPLOSION) + { + SegmentObjects *segment = (SegmentObjects *)seg; + set objs; + std::map bld_ids; + std::map coord_ids; + for (auto &object : segment->objects) + objs.insert(object.name1); + for (auto &o : objs) + { + auto iter = find_if(storage->objects.begin(), storage->objects.end(), [&](const decltype(Storage::objects)::value_type &p) + { + return p.second->text_id == o; + }); + if (iter == storage->objects.end()) + { + auto bld = storage->addObject(); + bld->text_id = o; + bld_ids[o] = bld->id; + } + else + bld_ids[o] = iter->second->id; + } + for (auto &object : segment->objects) + { + detail::MapObject mb; + //mb.text_id = object.name2; + mb.object = storage->objects[bld_ids[object.name1]]; + auto iter = find_if(storage->coordinates.begin(), storage->coordinates.end(), [&](const decltype(Storage::coordinates)::value_type &p) + { + Coordinate c; + c.x = object.position.x; + c.y = object.position.y; + c.z = object.position.z; + return *p.second.get() == c; + }); + if (iter == storage->coordinates.end()) + { + auto c = storage->addCoordinate(); + c->x = object.position.x; + c->y = object.position.y; + c->z = object.position.z; + mb.coordinate = c; + } + else + mb.coordinate = iter->second; + auto i = find_if(storage->mapObjects.begin(), storage->mapObjects.end(), [&](const decltype(Storage::mapObjects)::value_type &p) + { + return *p.second.get() == mb; + }); + if (i == storage->mapObjects.end()) + { + auto mb2 = storage->addMapObject(storage->maps[map_id].get()); + mb.id = mb2->id; + *mb2.get() = mb; + } + } + } + } + storage->save(); } int main(int argc, char *argv[]) { - if (argc != 2) + if (argc != 3) { - cout << "Usage:\n" << argv[0] << " file.mmo" << "\n"; + cout << "Usage:\n" << argv[0] << " db.sqlite file.mmo" << "\n"; return 1; } - read_mmo(argv[1]); + storage s = read_mmo(argv[2]); + write_mmo(argv[1], s); return 0; } \ No newline at end of file diff --git a/src/obj_extractor/objects.h b/src/obj_extractor/objects.h index a0e377e..d9c88b9 100644 --- a/src/obj_extractor/objects.h +++ b/src/obj_extractor/objects.h @@ -33,8 +33,8 @@ enum class SegmentType : uint32_t { TEXTURE = 0x1, MODEL, - SURFACE, - STONE, + SURFACE, // stones + STONE, // trees TREE, GLIDER, @@ -43,9 +43,9 @@ enum class SegmentType : uint32_t WEAPON, CONFIG, - SHELL, // (AMMO,BULLET) + SHELL, // buildings IMAGE, - EXPLOSION, + EXPLOSION, // road lights EQUIPMENT, ORGANIZATION,