// IE GM SAS Ripper // Davy Pizdunov 2010 (L) #include #include #include #include #include #include #include #include #include using std::string; using std::cout; namespace gl { string int2str(int x, int width=0, char pad='0'); string tos(int x); int sto(const string &s); void replaceAll(string &s, const string &r, const string &to); void eatEndl(string &s); string getline(std::istream&); void str2file(const std::string &filename, const std::string &s); std::string file2str(const std::string &filename); bool isfile(const string &f); string toLower(string s); string toUpper(string s); void addForwardSlash(string &s); }// gl namespace dir{ typedef std::map > msul; // returns name, time, size( -1L for a subdirectory ) msul readdir(); bool setd(string s); string getd(); bool make(string); bool remove(string); bool rename(string old, string n); bool matchExt(const string& s, const string& ext); inline bool isFolder(const string &dir) { string cwd =getd(); if( !setd(dir) ) return false; setd(cwd); return true; } class in{ string cwd; public: in(string s) { cwd=getd(); if( !setd(s) ) { throw string("dir::in: cannot get into [")+s+"]"; } } ~in(){ setd(cwd); } }; } //dir // Classes struct Tile { string apath, rpath, name, ext; string lyr; int x,y,z; Tile(string ap, string rp, string nm, bool my); bool operator<(const Tile& t) const; }; class Cache { string mCurrentDir; string mCurrentPath; std::set mTiles; public: Cache(string path); int size() const { return mTiles.size(); } void add(Tile t){ mTiles.insert(t); } const std::set & getTiles() const { return mTiles; } }; class Ie { string mDir; string mPath; string mGmPath; string mSasPath; std::set mTiles; public: Ie(string path, string gmpath, string spath); void skip(const Cache &c); void save(Cache &c); string aPath() const { return mPath; } int size() const { return mTiles.size(); } void add(Tile t){ mTiles.insert(t); } }; struct DirVisitor { string rpath; virtual void file(string name, string rpath) = 0; void go(); }; struct CacheVisitor: DirVisitor { Cache * pc; CacheVisitor(Cache *p, string rp): pc(p) { rpath=rp; } void file(string name, string rpath); }; struct IeVisitor: DirVisitor { Ie * pi; IeVisitor(Ie *p, string rp): pi(p) { rpath=rp; } void file(string name, string rpath); }; void CacheVisitor::file(string name, string rpath) { Tile t("",rpath,name,true); if( t.lyr=="" ) return; pc->add(t); if( !(pc->size()%100) ) cout<size()<<'\r'; } void IeVisitor::file(string name, string rpath) { Tile t(pi->aPath(),rpath,name,false); if( t.lyr=="" ) return; pi->add(t); if( !(pi->size()%100) ) cout<size()<<'\r'; } string getIePath(); int main(int ac, const char *av[]) try{ string iepath = getIePath(); int n = 1; int tm = 300; if( ac>= 2 ) n = atoi(av[1]); if( ac>2 ) tm = atoi(av[2]); while(1) { cout<<"Scanning data\n"< t.lyr ) return true; if( z < t.z ) return false; if( z > t.z ) return true; if( x < t.x ) return false; if( x > t.x ) return true; return y>lyr>>z>>x>>y; if( z>=0 ) { //cout<<" $("<second.second == -1L ) { string rp = rpath; rpath += i->first+"/"; dir::in ind(i->first); go(); rpath = rp; } else file( i->first, rpath ); } } Cache::Cache(string p) { mCurrentDir = dir::getd(); mCurrentPath = mCurrentDir; gl::replaceAll(mCurrentPath,"\\","/"); gl::addForwardSlash(mCurrentPath); dir::make(p); string pr = p+"/iegmrip"; dir::make(pr); CacheVisitor cv(this,p); dir::in ind(p); cv.go(); } Ie::Ie(string p, string gmp, string sas) { mDir = p; mPath = mDir; mGmPath = gmp; mSasPath = sas; dir::make(sas); gl::replaceAll(mPath,"\\","/"); gl::addForwardSlash(mPath); IeVisitor iv(this,""); dir::in ind(mDir); iv.go(); } void Ie::skip(const Cache &c) { const std::set & ct = c.getTiles(); for( std::set::const_iterator i=ct.begin(); i!=ct.end(); ++i ) { std::set::iterator j = mTiles.find(*i); if( j != mTiles.end() ) { mTiles.erase(j); } } } void Ie::save(Cache &c) { for( std::set::const_iterator i=mTiles.begin(); i!=mTiles.end(); ++i ) { Tile t = *i; // load string file; { dir::in ind(mDir); string file2read(t.rpath+t.name); file = gl::file2str(file2read); } { dir::in ind(mGmPath); string f2s; { string xc = gl::int2str(t.x,7); string yc = gl::int2str(t.y,7); string zc = gl::int2str(t.z,2); string name = t.lyr+'_'+zc+'_'+xc+'_'+yc+t.ext; dir::make(zc); dir::make(zc+'/'+t.lyr); dir::make(zc+'/'+t.lyr+'/'+xc); f2s = zc+'/'+t.lyr+'/'+xc+'/'+name; } gl::str2file( f2s, file ); } { dir::in ind(mSasPath); string f2s; { string xc = gl::int2str(t.x); string yc = gl::int2str(t.y); string xd = gl::int2str(t.x/1024); string yd = gl::int2str(t.y/1024); string zc = gl::int2str(t.z+1); string slr; if( t.lyr=="sat" ) slr="SAT"; if( t.lyr=="map" ) slr="MAP"; if( t.lyr=="lyr" ) slr="BOTH"; string name = 'y'+yc+t.ext; dir::make(slr); dir::make(slr+"/z"+zc); dir::make(slr+"/z"+zc+'/'+xd); dir::make(slr+"/z"+zc+'/'+xd+"/x"+xc); dir::make(slr+"/z"+zc+'/'+xd+"/x"+xc+'/'+yd); f2s = slr+"/z"+zc+'/'+xd+"/x"+xc+'/'+yd+'/'+name; } gl::str2file( f2s, file ); } { static int si=0; if( !(++si%10) ) cout<(pr) ) { if( s.size() && s[0]=='-' ) { s[0] = pad; s = '-' + s; } else s = pad+s; } return s; } // Windows specifics #include #include dir::msul dir::readdir() { std::map > r; _finddata_t f; long handle; if ( (handle = _findfirst("*",&f) ) != -1L ) do { // f.name f.size, (f.attrib & _A_SUBDIR) std::pair atr; atr.first = f.time_write; if( !(f.attrib & _A_SUBDIR) ) atr.second = f.size; else atr.second = -1L; string name(f.name); if( name != "." && name != ".." ) r[name] = atr; }while( _findnext(handle,&f) != -1 ); _findclose(handle); return r; } bool dir::setd(string s){ return !_chdir(s.c_str()); } string dir::getd(){ int size = 100; char * p = new char[size]; char * r = _getcwd(p,size); while( !r ){ delete[] p; if( size > 1000000L ) return ""; size*=2; p = new char[size]; r = _getcwd(p,size); } string rr(r); delete[] p; return rr; } bool dir::make(string s){ return !_mkdir(s.c_str()); } bool dir::remove(string s){ return !_rmdir(s.c_str()); } bool dir::rename(string old, string n) { //if( MoveFileEx(old.c_str(), n.c_str(), MOVEFILE_REPLACE_EXISTING )!=0 ) if( ::rename(old.c_str(), n.c_str()) == 0 ) return true; else return false; } bool dir::matchExt(const string& s, const string& e) { string::size_type i = s.rfind("."); if( i==string::npos ) return false; string r = s.substr(i+1); return gl::toLower(r)==gl::toLower(e); }