#include "PolToolMain.h" #include #include #include "../clib/Program/ProgramMain.h" #include "../clib/clib_endian.h" #include "../clib/fileutil.h" #include "../clib/logfacility.h" #include "../clib/rawtypes.h" #include "../plib/mapcell.h" #include "../plib/mapfunc.h" #include "../plib/mapserver.h" #include "../plib/mapshape.h" #include "../plib/maptile.h" #include "../plib/maptileserver.h" #include "../plib/realmdescriptor.h" #include "baredistro.h" #include "testfiles.h" #include "testenv.h" #include #include namespace Pol { namespace Clib { using namespace std; /////////////////////////////////////////////////////////////////////////////// PolToolMain::PolToolMain() : ProgramMain() {} /////////////////////////////////////////////////////////////////////////////// void PolToolMain::showHelp() { ERROR_PRINT << "Usage:\n" << " \n" << " POLTOOL mapdump [options]\n" << " Options:\n" << " x1 y1 [x2 y2 realm] writes polmap info to polmap.html\n" << " POLTOOL uncompressgump FileName\n" << " unpacks and prints 0xDD gump from given packet log\n" << " file needs to contain a single 0xDD packetlog\n" << " POLTOOL testfiles [options]\n" << " Options:\n" << " outdir=.\n" << " hsa=0\n" << " maxtiles=0x3fff\n" << " width=6144\n" << " height=4096\n"; } int PolToolMain::mapdump() { short wxl = 5485, wxh = 5500, wyl = 0, wyh = 30; const std::vector& binArgs = programArgs(); std::string realmname = "britannia"; if ( binArgs.size() >= 7 ) { realmname = binArgs[6]; } Plib::RealmDescriptor descriptor = Plib::RealmDescriptor::Load( realmname.c_str() ); // TODO: use a string in the signature of Load() Plib::MapServer* mapserver = Plib::MapServer::Create( descriptor ); std::unique_ptr _owner( mapserver ); std::unique_ptr mts( new Plib::MapTileServer( descriptor ) ); if ( binArgs.size() >= 4 ) { wxl = wxh = static_cast( atoi( binArgs[2].c_str() ) ); wyl = wyh = static_cast( atoi( binArgs[3].c_str() ) ); } if ( binArgs.size() >= 6 ) { wxh = static_cast( atoi( binArgs[4].c_str() ) ); wyh = static_cast( atoi( binArgs[5].c_str() ) ); } std::ofstream ofs( "polmap.html" ); ofs << Plib::flagdescs() << std::endl; ofs << "" << std::endl; ofs << ""; for ( int x = wxl; x <= wxh; ++x ) { ofs << ""; } ofs << "" << std::endl; for ( unsigned short y = wyl; y <= wyh; ++y ) { ofs << "" << std::endl; for ( unsigned short x = wxl; x <= wxh; ++x ) { ofs << "" << std::endl; } ofs << "" << std::endl; } ofs << "
 " << x << "
" << y << ""; Plib::MAPCELL cell = mapserver->GetMapCell( x, y ); Plib::MapShapeList mlist; mapserver->GetMapShapes( mlist, x, y, static_cast( Plib::FLAG::ALL ) ); Plib::MAPTILE_CELL tile = mts->GetMapTile( x, y ); ofs << "landtile=" << int( tile.landtile ) << "
"; ofs << "tilez=" << int( tile.z ) << "
"; ofs << "z=" << int( cell.z ) << "
"; ofs << "flags=" << Plib::flagstr( cell.flags ); for ( unsigned i = 1; i < mlist.size(); ++i ) { ofs << "
" << "solid.z=" << int( mlist[i].z ) << "
" << "solid.height=" << int( mlist[i].height ) << "
" << "solid.flags=" << Plib::flagstr( mlist[i].flags ); } ofs << "
" << std::endl; return 0; } int PolToolMain::unpackCompressedGump() { const std::vector& binArgs = programArgs(); if ( binArgs.size() < 3 ) { showHelp(); return 1; } if ( !Clib::FileExists( binArgs[2] ) ) return 1; ifstream dmp( binArgs[2] ); std::vector bytes; dmp.setf( std::ios::hex ); int per_line = 0; while ( dmp ) { std::string tmp; while ( dmp ) { char c; dmp.get( c ); if ( c == ' ' ) { break; } else if ( per_line == 16 ) // both razor and pol have 16 bytes per line { if ( c == '\n' ) per_line = 0; } else if ( isdigit( c ) ) tmp += c; else if ( c >= 'A' && c <= 'Z' ) tmp += c; } if ( tmp.size() == 2 ) { int num = std::stoi( tmp, nullptr, 16 ); bytes.push_back( static_cast( num ) ); ++per_line; } } size_t index = 0; auto toInt = [&]( size_t i ) -> unsigned int { return ( bytes[i] << 24 ) | ( bytes[i + 1] << 16 ) | ( bytes[i + 2] << 8 ) | ( bytes[i + 3] ); }; auto toShort = [&]( size_t i ) -> unsigned short { return ( bytes[i] << 8 ) | ( bytes[i + 1] ); }; if ( bytes[index] != 0xdd ) return 1; ++index; auto len = toShort( index ); INFO_PRINT << "len " << len; index += 2; auto serial = toInt( index ); index += 4; INFO_PRINT << " serial " << serial; auto gumpid = static_cast( toInt( index ) ); index += 4; INFO_PRINT << " gumpID " << gumpid; auto x = toInt( index ); index += 4; INFO_PRINT << " x " << x; auto y = toInt( index ); index += 4; INFO_PRINT << " y " << y; auto cbuflen = toInt( index ) - 4; index += 4; auto datalen = static_cast( toInt( index ) ); index += 4; std::unique_ptr uncompressed( new unsigned char[datalen] ); int res = uncompress( uncompressed.get(), &datalen, &bytes.data()[index], cbuflen ); if ( res < 0 ) return 1; index += cbuflen; std::string layout( uncompressed.get(), uncompressed.get() + datalen - 1 ); fmt::Writer layouttmp; layouttmp << '\n'; for ( const auto& c : layout ) { layouttmp << c; if ( c == '}' ) layouttmp << '\n'; } INFO_PRINT << layouttmp.str(); auto linecount = toInt( index ); index += 4; cbuflen = toInt( index ) - 4; index += 4; datalen = static_cast( toInt( index ) ); index += 4; std::unique_ptr uncompressed2( new unsigned char[datalen] ); res = uncompress( uncompressed2.get(), &datalen, &bytes.data()[index], cbuflen ); if ( res < 0 ) return 1; std::string layout2( uncompressed2.get(), uncompressed2.get() + datalen ); INFO_PRINT << '\n'; fmt::Writer datatmp; datatmp << '\n'; size_t j = 0; for ( size_t i = 0; i < linecount; ++i ) { unsigned short wc = ( uncompressed2[j] << 8 ) | ( uncompressed2[j + 1] ); if ( wc > 0 ) { std::u16string u16s( reinterpret_cast( &uncompressed2[j + 2] ), wc ); std::string u8_conv; for ( auto c : u16s ) { c = ctBEu16( c ); if ( c <= 256 ) u8_conv += static_cast( c ); else { u8_conv += static_cast( c & 0xff ); u8_conv += static_cast( ( c >> 8 ) & 0xff ); } } datatmp << '"' << u8_conv << "\"\n"; } else datatmp << "\"\"\n"; j += 2 + wc * 2; } INFO_PRINT << datatmp.str(); INFO_PRINT << '\n'; return 0; } int PolToolMain::main() { const std::vector& binArgs = programArgs(); /********************************************** * show help **********************************************/ if ( binArgs.size() == 1 ) { showHelp(); return 0; // return "okay" } /********************************************** * execute the map dumping **********************************************/ if ( binArgs[1] == "mapdump" ) { return mapdump(); } else if ( binArgs[1] == "uncompressgump" ) { return unpackCompressedGump(); } else if ( binArgs[1] == "testfiles" ) { std::string outdir = programArgsFindEquals( "outdir=", "." ); bool hsa = programArgsFindEquals( "hsa=", 0, false ) != 0 ? true : false; int maxtiles = programArgsFindEquals( "maxtiles=", 0x3fff, true ); int width = programArgsFindEquals( "width=", 6144, false ); int height = programArgsFindEquals( "height=", 4096, false ); PolTool::FileGenerator g( outdir, hsa, maxtiles, width, height ); g.generateTiledata(); g.generateMap(); g.generateStatics(); g.generateMultis(); return 0; } else if ( binArgs[1] == "baredistro" ) { std::string outdir = programArgsFindEquals( "outdir=", "." ); bool hsa = programArgsFindEquals( "hsa=", 0, false ) != 0 ? true : false; int maxtiles = programArgsFindEquals( "maxtiles=", 0x3fff, true ); int width = programArgsFindEquals( "width=", 6144, false ); int height = programArgsFindEquals( "height=", 4096, false ); PolTool::BareDistro distro( outdir, hsa, maxtiles, width, height ); distro.generate(); return 0; } else if ( binArgs[1] == "testenv" ) { std::string outdir = programArgsFindEquals( "outdir=", "." ); bool hsa = programArgsFindEquals( "hsa=", 0, false ) != 0 ? true : false; int maxtiles = programArgsFindEquals( "maxtiles=", 0x3fff, true ); int width = programArgsFindEquals( "width=", 6144, false ); int height = programArgsFindEquals( "height=", 4096, false ); PolTool::TestEnv testenv( outdir, hsa, maxtiles, width, height ); testenv.generate(); return 0; } else { ERROR_PRINT << "Unknown command " << binArgs[1] << "\n"; return 1; // return "error" } } } // namespace Clib } // namespace Pol /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// int main( int argc, char* argv[] ) { Pol::Clib::PolToolMain* PolToolMain = new Pol::Clib::PolToolMain(); PolToolMain->start( argc, argv ); }