Pol  Revision:cb584c9
PolToolMain.cpp
Go to the documentation of this file.
1 #include "PolToolMain.h"
2 
3 #include <fstream>
4 #include <string>
5 
6 #include <format/format.h>
7 #include "../clib/Program/ProgramMain.h"
8 #include "../clib/clib_endian.h"
9 #include "../clib/fileutil.h"
10 #include "../clib/logfacility.h"
11 #include "../clib/rawtypes.h"
12 #include "../plib/mapcell.h"
13 #include "../plib/mapfunc.h"
14 #include "../plib/mapserver.h"
15 #include "../plib/mapshape.h"
16 #include "../plib/maptile.h"
17 #include "../plib/maptileserver.h"
18 #include "../plib/realmdescriptor.h"
19 #ifdef USE_SYSTEM_ZLIB
20 #include <zlib.h>
21 #else
22 #include "../../lib/zlib/zlib.h"
23 #endif
24 
25 namespace Pol
26 {
27 namespace Clib
28 {
29 using namespace std;
30 
32 
34 PolToolMain::~PolToolMain() = default;
36 
38 {
39  ERROR_PRINT << "Usage:\n"
40  << " \n"
41  << " POLTOOL mapdump [options]\n"
42  << " Options:\n"
43  << " x1 y1 [x2 y2 realm] writes polmap info to polmap.html\n"
44  << " POLTOOL uncompressgump FileName\n"
45  << " unpacks and prints 0xDD gump from given packet log\n"
46  << " file needs to contain a single 0xDD packetlog\n";
47 }
48 
50 {
51  short wxl = 5485, wxh = 5500, wyl = 0, wyh = 30;
52  const std::vector<std::string>& binArgs = programArgs();
53 
54  std::string realmname = "britannia";
55  if ( binArgs.size() >= 6 )
56  {
57  realmname = binArgs[5];
58  }
60  realmname.c_str() ); // TODO: use a string in the signature of Load()
61  Plib::MapServer* mapserver = Plib::MapServer::Create( descriptor );
62  std::unique_ptr<Plib::MapServer> _owner( mapserver );
63 
64  std::unique_ptr<Plib::MapTileServer> mts( new Plib::MapTileServer( descriptor ) );
65  if ( binArgs.size() >= 3 )
66  {
67  wxl = wxh = static_cast<short>( atoi( binArgs[1].c_str() ) );
68  wyl = wyh = static_cast<short>( atoi( binArgs[2].c_str() ) );
69  }
70  if ( binArgs.size() >= 5 )
71  {
72  wxh = static_cast<short>( atoi( binArgs[3].c_str() ) );
73  wyh = static_cast<short>( atoi( binArgs[4].c_str() ) );
74  }
75 
76  std::ofstream ofs( "polmap.html" );
77 
78  ofs << Plib::flagdescs() << std::endl;
79  ofs << "<table border=1 cellpadding=5 cellspacing=0>" << std::endl;
80  ofs << "<tr><td>&nbsp;</td>";
81  for ( int x = wxl; x <= wxh; ++x )
82  {
83  ofs << "<td align=center>" << x << "</td>";
84  }
85  ofs << "</tr>" << std::endl;
86  for ( unsigned short y = wyl; y <= wyh; ++y )
87  {
88  ofs << "<tr><td valign=center>" << y << "</td>" << std::endl;
89  for ( unsigned short x = wxl; x <= wxh; ++x )
90  {
91  ofs << "<td align=left valign=top>";
92 
93  Plib::MAPCELL cell = mapserver->GetMapCell( x, y );
94  Plib::MapShapeList mlist;
95  mapserver->GetMapShapes( mlist, x, y, static_cast<u32>( Plib::FLAG::ALL ) );
96  Plib::MAPTILE_CELL tile = mts->GetMapTile( x, y );
97 
98  ofs << "landtile=" << int( tile.landtile ) << "<br>";
99  ofs << "tilez=" << int( tile.z ) << "<br>";
100  ofs << "z=" << int( cell.z ) << "<br>";
101  ofs << "flags=" << Plib::flagstr( cell.flags );
102 
103  for ( unsigned i = 1; i < mlist.size(); ++i )
104  {
105  ofs << "<br>"
106  << "solid.z=" << int( mlist[i].z ) << "<br>"
107  << "solid.height=" << int( mlist[i].height ) << "<br>"
108  << "solid.flags=" << Plib::flagstr( mlist[i].flags );
109  }
110 
111  ofs << "</td>" << std::endl;
112  }
113  ofs << "</tr>" << std::endl;
114  }
115  ofs << "</table>" << std::endl;
116  return 0;
117 }
118 
120 {
121  const std::vector<std::string>& binArgs = programArgs();
122  if ( binArgs.size() < 3 )
123  {
124  showHelp();
125  return 1;
126  }
127  if ( !Clib::FileExists( binArgs[2] ) )
128  return 1;
129 
130  ifstream dmp( binArgs[2] );
131  std::vector<unsigned char> bytes;
132  dmp.setf( std::ios::hex );
133  int per_line = 0;
134  while ( dmp )
135  {
136  std::string tmp;
137  while ( dmp )
138  {
139  char c;
140  dmp.get( c );
141  if ( c == ' ' )
142  {
143  break;
144  }
145  else if ( per_line == 16 ) // both razor and pol have 16 bytes per line
146  {
147  if ( c == '\n' )
148  per_line = 0;
149  }
150  else if ( isdigit( c ) )
151  tmp += c;
152  else if ( c >= 'A' && c <= 'Z' )
153  tmp += c;
154  }
155  if ( tmp.size() == 2 )
156  {
157  int num = std::stoi( tmp, 0, 16 );
158  bytes.push_back( static_cast<unsigned char>( num ) );
159  ++per_line;
160  }
161  }
162 
163  size_t index = 0;
164  auto toInt = [&]( size_t i ) -> unsigned int {
165  return ( bytes[i] << 24 ) | ( bytes[i + 1] << 16 ) | ( bytes[i + 2] << 8 ) | ( bytes[i + 3] );
166  };
167  auto toShort = [&]( size_t i ) -> unsigned short { return ( bytes[i] << 8 ) | ( bytes[i + 1] ); };
168  if ( bytes[index] != 0xdd )
169  return 1;
170  ++index;
171  auto len = toShort( index );
172  INFO_PRINT << "len " << len;
173  index += 2;
174  auto serial = toInt( index );
175  index += 4;
176  INFO_PRINT << " serial " << serial;
177  auto gumpid = static_cast<unsigned int>( toInt( index ) );
178  index += 4;
179  INFO_PRINT << " gumpID " << gumpid;
180 
181  auto x = toInt( index );
182  index += 4;
183  INFO_PRINT << " x " << x;
184  auto y = toInt( index );
185  index += 4;
186  INFO_PRINT << " y " << y;
187  auto cbuflen = toInt( index ) - 4;
188  index += 4;
189  auto datalen = static_cast<unsigned long>( toInt( index ) );
190  index += 4;
191  std::unique_ptr<unsigned char[]> uncompressed( new unsigned char[datalen] );
192  int res = uncompress( uncompressed.get(), &datalen, &bytes.data()[index], cbuflen );
193  if ( res < 0 )
194  return 1;
195  index += cbuflen;
196  std::string layout( uncompressed.get(), uncompressed.get() + datalen - 1 );
197  fmt::Writer layouttmp;
198  layouttmp << '\n';
199  for ( const auto& c : layout )
200  {
201  layouttmp << c;
202  if ( c == '}' )
203  layouttmp << '\n';
204  }
205  INFO_PRINT << layouttmp.str();
206 
207  auto linecount = toInt( index );
208  index += 4;
209  cbuflen = toInt( index ) - 4;
210  index += 4;
211  datalen = static_cast<unsigned long>( toInt( index ) );
212  index += 4;
213  std::unique_ptr<unsigned char[]> uncompressed2( new unsigned char[datalen] );
214  res = uncompress( uncompressed2.get(), &datalen, &bytes.data()[index], cbuflen );
215  if ( res < 0 )
216  return 1;
217  std::string layout2( uncompressed2.get(), uncompressed2.get() + datalen );
218  INFO_PRINT << '\n';
219  fmt::Writer datatmp;
220  datatmp << '\n';
221  size_t j = 0;
222  for ( size_t i = 0; i < linecount; ++i )
223  {
224  unsigned short wc = ( uncompressed2[j] << 8 ) | ( uncompressed2[j + 1] );
225  if ( wc > 0 )
226  {
227  std::u16string u16s( reinterpret_cast<const char16_t*>( &uncompressed2[j + 2] ), wc );
228  std::string u8_conv;
229  for ( auto c : u16s )
230  {
231  c = ctBEu16( c );
232  if ( c <= 256 )
233  u8_conv += static_cast<char>( c );
234  else
235  {
236  u8_conv += static_cast<char>( c & 0xff );
237  u8_conv += static_cast<char>( ( c >> 8 ) & 0xff );
238  }
239  }
240  datatmp << '"' << u8_conv << "\"\n";
241  }
242  else
243  datatmp << "\"\"\n";
244  j += 2 + wc * 2;
245  }
246  INFO_PRINT << datatmp.str();
247  INFO_PRINT << '\n';
248  return 0;
249 }
250 
252 {
253  const std::vector<std::string>& binArgs = programArgs();
254 
255  /**********************************************
256  * show help
257  **********************************************/
258  if ( binArgs.size() == 1 )
259  {
260  showHelp();
261  return 0; // return "okay"
262  }
263 
264  /**********************************************
265  * execute the map dumping
266  **********************************************/
267  if ( binArgs[1] == "mapdump" )
268  {
269  return mapdump();
270  }
271  else if ( binArgs[1] == "uncompressgump" )
272  {
273  return unpackCompressedGump();
274  }
275  else
276  {
277  ERROR_PRINT << "Unknown command " << binArgs[1] << "\n";
278  return 1; // return "error"
279  }
280 }
281 }
282 } // namespaces
283 
287 
288 int main( int argc, char* argv[] )
289 {
291  PolToolMain->start( argc, argv );
292 }
unsigned short landtile
Definition: maptile.h:21
std::string flagstr(unsigned int flags)
Definition: mapfunc.cpp:24
static RealmDescriptor Load(const std::string &realm_name, const std::string &realm_path="")
const std::vector< std::string > & programArgs() const
#define ctBEu16(x)
Definition: clib_endian.h:46
STL namespace.
static MapServer * Create(const RealmDescriptor &descriptor)
Definition: mapserver.cpp:151
void start(int argc, char *argv[])
Definition: ProgramMain.cpp:42
signed char z
Definition: mapcell.h:50
unsigned char flags
Definition: mapcell.h:51
#define ERROR_PRINT
Definition: logfacility.h:230
bool FileExists(const char *filename)
Definition: fileutil.cpp:118
#define INFO_PRINT
Definition: logfacility.h:223
std::string flagdescs()
Definition: mapfunc.cpp:53
Definition: berror.cpp:12
virtual void showHelp()
Definition: PolToolMain.cpp:37