Advertisement
lucasgautheron

Untitled

Aug 25th, 2011
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 54.80 KB | None | 0 0
  1. Index: src/client.cpp
  2. ===================================================================
  3. --- src/client.cpp  (revision 6612)
  4. +++ src/client.cpp  (working copy)
  5. @@ -813,3 +813,220 @@
  6.  COMMAND(listdemos, ARG_NONE);
  7.  COMMANDN(setmr, setminutesremaining, ARG_1INT);
  8.  COMMANDN(rewind, rewinddemo, ARG_1INT);
  9. +
  10. +// packages auto - downloader
  11. +
  12. +// arrays
  13. +vector<pckserver *> pckservers;
  14. +vector<package *> packages;
  15. +//vector<package *> pendingpackages;
  16. +
  17. +// thread
  18. +SDL_Thread *pckthread;
  19. +int process_packages(void *ptr);
  20. +
  21. +// cubescript
  22. +
  23. +void addpckserver(char *addr)
  24. +{
  25. +
  26. +}
  27. +
  28. +void addpackage(char *type, char *name)
  29. +{
  30. +    int t = atoi(type);
  31. +    if(t < 0 || t >= PCK_NUM) return;
  32. +    if(!name || name[0] == '\0') return;
  33. +    package *pck = new package();
  34. +    pck->name = newstring(name);
  35. +    pck->type = t;
  36. +    pck->source = pckservers[0]; // FIXME
  37. +    packages.add(pck);
  38. +}
  39. +
  40. +void requirepackage(int type, char *name)
  41. +{
  42. +    loopv(packages) if(packages[i]->type == type
  43. +        && !strcmp(packages[i]->name, name))
  44. +    {
  45. +        packages[i]->pending = true;
  46. +    }
  47. +}
  48. +
  49. +// reset current packages list
  50. +void resetpackages()
  51. +{
  52. +    loopv(packages)
  53. +    {
  54. +        DELETEP(packages[i]);
  55. +        packages.remove(i);
  56. +    }
  57. +    packages.shrink(0); // pointless?
  58. +}
  59. +
  60. +// update list of packages
  61. +void retrievepackages()
  62. +{
  63. +    resetpackages();
  64. +
  65. +    // TMP:
  66. +    if(!pckservers.length())
  67. +    {
  68. +        pckserver *srcserver = new pckserver();
  69. +        srcserver->addr = "http://de582.ispfr.net/cube";
  70. +        srcserver->pending = true;
  71. +        pckservers.add(srcserver);
  72. +    }
  73. +    // :TMP
  74. +    loopv(pckservers) pckservers[i]->pending = true;
  75. +    pckthread = SDL_CreateThread(process_packages, (void *)NULL);
  76. +}
  77. +
  78. +void downloadpackages()
  79. +{
  80. +    pckthread = SDL_CreateThread(process_packages, (void *)NULL);
  81. +}
  82. +
  83. +void test(int id)
  84. +{
  85. +    if(!packages.inrange(id)) { conoutf("package not found"); return; }
  86. +    packages[id]->pending = true;
  87. +    pckthread = SDL_CreateThread(process_packages, (void *)NULL);
  88. +}
  89. +
  90. +COMMAND(test, ARG_1INT);
  91. +COMMAND(addpckserver, ARG_1STR);
  92. +COMMAND(addpackage, ARG_2STR);
  93. +COMMAND(retrievepackages, ARG_NONE);
  94. +COMMAND(resetpackages, ARG_NONE);
  95. +
  96. +// cURL / Network
  97. +
  98. +static size_t write_callback(void *ptr, size_t size, size_t nmemb, FILE *stream)
  99. +{
  100. +    return fwrite(ptr, size, nmemb, stream);
  101. +}
  102. +
  103. +// update packages list from a source
  104. +void retrievepackages(pckserver *srcserver, FILE *outfile)
  105. +{
  106. +    srcserver->pending = false;
  107. +    string req;
  108. +    sprintf(req, "%s/get.php", srcserver->addr);
  109. +    conoutf("retrieving list of packages from %s...", srcserver->addr);
  110. +
  111. +    fprintf(outfile, "// setserver \"%s\";\n", srcserver->addr);
  112. +    
  113. +    CURL *curl = curl_easy_init();
  114. +    curl_easy_setopt(curl, CURLOPT_URL, req);
  115. +    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
  116. +    curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
  117. +    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "do=list");
  118. +    curl_easy_perform(curl);
  119. +    curl_easy_cleanup(curl);
  120. +}
  121. +
  122. +// download a package
  123. +bool dlpackage(package *pck)
  124. +{
  125. +    if(!pck || !pck->source) return false;
  126. +    FILE *outfile = fopen(path("config/tmp", true), "wb");
  127. +    string req;
  128. +    sprintf(req, "%s/get.php", pck->source->addr);
  129. +    string post;
  130. +    sprintf(post, "do=dl&name=%s&type=%d", pck->name, pck->type);
  131. +    conoutf("downloading %s...", pck->name);
  132. +
  133. +    CURL *curl = curl_easy_init();
  134. +    curl_easy_setopt(curl, CURLOPT_URL, req);
  135. +    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_callback);
  136. +    curl_easy_setopt(curl, CURLOPT_WRITEDATA, outfile);
  137. +    curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
  138. +    curl_easy_perform(curl);
  139. +    curl_easy_cleanup(curl);
  140. +    fclose(outfile);
  141. +    return true;
  142. +}
  143. +
  144. +/*void retrievepackages()
  145. +{
  146. +    resetpackages();
  147. +    if(!pckservers.length())
  148. +    {
  149. +        pckserver *srcserver = new pckserver();
  150. +        srcserver->addr = "http://de582.ispfr.net/cube";
  151. +        pckservers.add(srcserver);
  152. +    }
  153. +    FILE *fp = fopen(path("config/packages.cfg", true), "w");
  154. +    loopv(pckservers)
  155. +    {
  156. +        retrievepackages(pckservers[i], fp);
  157. +    }
  158. +    fclose(fp);
  159. +    execfile("config/packages.cfg");
  160. +}*/
  161. +
  162. +// threading
  163. +
  164. +// threaded loop to process requests
  165. +int process_packages(void *ptr)
  166. +{
  167. +    FILE *fp = NULL;
  168. +    loopv(pckservers)
  169. +    {
  170. +        if(pckservers[i]->pending)
  171. +        {
  172. +            if(!fp) fp = fopen(path("config/packages.cfg", true), "w");
  173. +            retrievepackages(pckservers[i], fp);
  174. +        }
  175. +    }
  176. +    if(fp)
  177. +    {
  178. +        execfile("config/packages.cfg");
  179. +        conoutf("%d packages loaded !", packages.length());
  180. +        fclose(fp);
  181. +    }
  182. +
  183. +    bool dled = false;
  184. +    loopv(packages)
  185. +    {
  186. +        if(packages[i]->pending)
  187. +        {
  188. +            dled = true;
  189. +            packages[i]->pending = false; // even if an error occurs, do not dl again.
  190. +            if(!dlpackage(packages[i]))
  191. +            {
  192. +                conoutf("\f3failed!");
  193. +                continue;
  194. +            }
  195. +
  196. +            switch(packages[i]->type)
  197. +            {
  198. +                case PCK_TEXTURE:
  199. +                {
  200. +                    string tmp;
  201. +                    sprintf(tmp, "packages/textures/%s", packages[i]->name);
  202. +                    preparedir(tmp);
  203. +                    // with textures, the image itself is sent. Just need to copy it from the temporary file
  204. +                    if(!copyfile(path("config/tmp", true), tmp)) conoutf("\f3failed to install %s", packages[i]->name);
  205. +                }
  206. +                break;
  207. +
  208. +                case PCK_MAP:
  209. +                {
  210. +                    const char *p = path("config/tmp", true);
  211. +                    addzip(p);
  212. +                }
  213. +                break;
  214. +
  215. +                default:
  216. +                {
  217. +                    conoutf("could not install package %s", packages[i]->name);
  218. +                }
  219. +                break;
  220. +            }
  221. +        }
  222. +    }
  223. +    if(dled) conoutf("packages installed.");
  224. +    return 0;
  225. +}
  226. \ No newline at end of file
  227. Index: src/entity.h
  228. ===================================================================
  229. --- src/entity.h    (revision 6612)
  230. +++ src/entity.h    (working copy)
  231. @@ -622,3 +622,23 @@
  232.  
  233.      return killmessages[gib?1:0][gun];
  234.  }
  235. +
  236. +struct pckserver
  237. +{
  238. +    char *addr;
  239. +    bool pending;
  240. +
  241. +    pckserver() : addr(NULL), pending(false) {}
  242. +};
  243. +
  244. +enum { PCK_TEXTURE, PCK_SKYBOX, PCK_MAPMODEL, PCK_AUDIO, PCK_MAP, PCK_NUM };
  245. +
  246. +struct package
  247. +{
  248. +    char *name;
  249. +    int type;
  250. +    bool pending;
  251. +    pckserver *source;
  252. +
  253. +    package() : name(NULL), type(-1), pending(false) {}
  254. +};
  255. \ No newline at end of file
  256. Index: src/platform.h
  257. ===================================================================
  258. --- src/platform.h  (revision 6612)
  259. +++ src/platform.h  (working copy)
  260. @@ -71,3 +71,8 @@
  261.  
  262.      #include <setjmp.h>
  263.  #endif
  264. +
  265. +#ifndef CURL_STATICLIB
  266. +#define CURL_STATICLIB
  267. +#endif
  268. +#include "curl/curl.h"
  269. \ No newline at end of file
  270. Index: src/protos.h
  271. ===================================================================
  272. --- src/protos.h    (revision 6612)
  273. +++ src/protos.h    (working copy)
  274. @@ -305,6 +305,9 @@
  275.  extern float skyfloor;
  276.  extern void draw_envbox(int fogdist);
  277.  
  278. +extern void requirepackage(int type, char *name);
  279. +extern void downloadpackages();
  280. +
  281.  extern int maxtmus;
  282.  extern void inittmus();
  283.  extern void resettmu(int n);
  284. Index: src/stream.cpp
  285. ===================================================================
  286. --- src/stream.cpp  (revision 6612)
  287. +++ src/stream.cpp  (working copy)
  288. @@ -1,785 +1,817 @@
  289. -#include "cube.h"
  290. -
  291. -///////////////////////// file system ///////////////////////
  292. -
  293. -#ifndef WIN32
  294. -#include <unistd.h>
  295. -#include <sys/stat.h>
  296. -#include <sys/types.h>
  297. -#include <dirent.h>
  298. -#endif
  299. -
  300. -string homedir = "";
  301. -vector<char *> packagedirs;
  302. -
  303. -char *makerelpath(const char *dir, const char *file, const char *prefix, const char *cmd)
  304. -{
  305. -    static string tmp;
  306. -    if(prefix) copystring(tmp, prefix);
  307. -    else tmp[0] = '\0';
  308. -    if(file[0]=='<')
  309. -    {
  310. -        const char *end = strrchr(file, '>');
  311. -        if(end)
  312. -        {
  313. -            size_t len = strlen(tmp);
  314. -            copystring(&tmp[len], file, min(sizeof(tmp)-len, size_t(end+2-file)));
  315. -            file = end+1;
  316. -        }
  317. -    }
  318. -    if(cmd) concatstring(tmp, cmd);
  319. -    defformatstring(pname)("%s/%s", dir, file);
  320. -    concatstring(tmp, pname);
  321. -    return tmp;
  322. -}
  323. -
  324. -
  325. -char *path(char *s)
  326. -{
  327. -    for(char *curpart = s;;)
  328. -    {
  329. -        char *endpart = strchr(curpart, '&');
  330. -        if(endpart) *endpart = '\0';
  331. -        if(curpart[0]=='<')
  332. -        {
  333. -            char *file = strrchr(curpart, '>');
  334. -            if(!file) return s;
  335. -            curpart = file+1;
  336. -        }
  337. -        for(char *t = curpart; (t = strpbrk(t, "/\\")); *t++ = PATHDIV);
  338. -        for(char *prevdir = NULL, *curdir = s;;)
  339. -        {
  340. -            prevdir = curdir[0]==PATHDIV ? curdir+1 : curdir;
  341. -            curdir = strchr(prevdir, PATHDIV);
  342. -            if(!curdir) break;
  343. -            if(prevdir+1==curdir && prevdir[0]=='.')
  344. -            {
  345. -                memmove(prevdir, curdir+1, strlen(curdir+1)+1);
  346. -                curdir = prevdir;
  347. -            }
  348. -            else if(curdir[1]=='.' && curdir[2]=='.' && curdir[3]==PATHDIV)
  349. -            {
  350. -                if(prevdir+2==curdir && prevdir[0]=='.' && prevdir[1]=='.') continue;
  351. -                memmove(prevdir, curdir+4, strlen(curdir+4)+1);
  352. -                curdir = prevdir;
  353. -            }
  354. -        }
  355. -        if(endpart)
  356. -        {
  357. -            *endpart = '&';
  358. -            curpart = endpart+1;
  359. -        }
  360. -        else break;
  361. -    }
  362. -    return s;
  363. -}
  364. -
  365. -char *path(const char *s, bool copy)
  366. -{
  367. -    static string tmp;
  368. -    copystring(tmp, s);
  369. -    path(tmp);
  370. -    return tmp;
  371. -}
  372. -
  373. -const char *parentdir(const char *directory)
  374. -{
  375. -    const char *p = directory + strlen(directory);
  376. -    while(p > directory && *p != '/' && *p != '\\') p--;
  377. -    static string parent;
  378. -    size_t len = p-directory+1;
  379. -    copystring(parent, directory, len);
  380. -    return parent;
  381. -}
  382. -
  383. -const char *behindpath(const char *s)
  384. -{
  385. -    const char *t = s;
  386. -    for( ; (s = strpbrk(s, "/\\")); t = ++s);
  387. -    return t;
  388. -}
  389. -
  390. -bool fileexists(const char *path, const char *mode)
  391. -{
  392. -    bool exists = true;
  393. -    if(mode[0]=='w' || mode[0]=='a') path = parentdir(path);
  394. -#ifdef WIN32
  395. -    if(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES) exists = false;
  396. -#else
  397. -    if(access(path, R_OK | (mode[0]=='w' || mode[0]=='a' ? W_OK : 0)) == -1) exists = false;
  398. -#endif
  399. -    return exists;
  400. -}
  401. -
  402. -bool createdir(const char *path)
  403. -{
  404. -    size_t len = strlen(path);
  405. -    if(path[len-1]==PATHDIV)
  406. -    {
  407. -        static string strip;
  408. -        path = copystring(strip, path, len);
  409. -    }
  410. -#ifdef WIN32
  411. -    return CreateDirectory(path, NULL)!=0;
  412. -#else
  413. -    return mkdir(path, 0777)==0;
  414. -#endif
  415. -}
  416. -
  417. -size_t fixpackagedir(char *dir)
  418. -{
  419. -    path(dir);
  420. -    size_t len = strlen(dir);
  421. -    if(len > 0 && dir[len-1] != PATHDIV)
  422. -    {
  423. -        dir[len] = PATHDIV;
  424. -        dir[len+1] = '\0';
  425. -    }
  426. -    return len;
  427. -}
  428. -
  429. -#ifdef WIN32
  430. -char *getregszvalue(HKEY root, const char *keystr, const char *query)
  431. -{
  432. -    HKEY key;
  433. -    if(RegOpenKeyEx(HKEY_CURRENT_USER, keystr, 0, KEY_READ, &key)==ERROR_SUCCESS)
  434. -    {
  435. -        DWORD type = 0, len = 0;
  436. -        if(RegQueryValueEx(key, query, 0, &type, 0, &len)==ERROR_SUCCESS && type==REG_SZ)
  437. -        {
  438. -            char *val = new char[len];
  439. -            long result = RegQueryValueEx(key, query, 0, &type, (uchar *)val, &len);
  440. -            if(result==ERROR_SUCCESS)
  441. -            {
  442. -                RegCloseKey(key);
  443. -                val[len-1] = '\0';
  444. -                return val;
  445. -            }
  446. -            delete[] val;
  447. -        }
  448. -        RegCloseKey(key);
  449. -    }
  450. -    return NULL;
  451. -}
  452. -#endif
  453. -
  454. -void sethomedir(const char *dir)
  455. -{
  456. -    string tmpdir;
  457. -    copystring(tmpdir, dir);
  458. -
  459. -#ifdef WIN32
  460. -    const char substitute[] = "?MYDOCUMENTS?";
  461. -    if(!strncmp(dir, substitute, strlen(substitute)))
  462. -    {
  463. -        const char *regpath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
  464. -        char *mydocuments = getregszvalue(HKEY_CURRENT_USER, regpath, "Personal");
  465. -        if(mydocuments)
  466. -        {
  467. -            formatstring(tmpdir)("%s%s", mydocuments, dir+strlen(substitute));
  468. -            delete[] mydocuments;
  469. -        }
  470. -        else
  471. -        {
  472. -            printf("failed to retrieve 'Personal' path from '%s'\n", regpath);
  473. -        }
  474. -    }
  475. -#endif
  476. -
  477. -#ifndef STANDALONE
  478. -    clientlogf("Using home directory: %s", tmpdir);
  479. -#endif
  480. -
  481. -    if(fixpackagedir(tmpdir) > 0)
  482. -    {
  483. -        copystring(homedir, tmpdir);
  484. -        createdir(homedir);
  485. -    }
  486. -}
  487. -
  488. -void addpackagedir(const char *dir)
  489. -{
  490. -#ifndef STANDALONE
  491. -    clientlogf("Adding package directory: %s", dir);
  492. -#endif
  493. -
  494. -    string pdir;
  495. -    copystring(pdir, dir);
  496. -    if(fixpackagedir(pdir) > 0) packagedirs.add(newstring(pdir));
  497. -}
  498. -
  499. -const char *findfile(const char *filename, const char *mode)
  500. -{
  501. -    static string s;
  502. -    if(homedir[0])
  503. -    {
  504. -        formatstring(s)("%s%s", homedir, filename);
  505. -        if(fileexists(s, mode)) return s;
  506. -        if(mode[0]=='w' || mode[0]=='a')
  507. -        {
  508. -            string dirs;
  509. -            copystring(dirs, s);
  510. -            char *dir = strchr(dirs[0]==PATHDIV ? dirs+1 : dirs, PATHDIV);
  511. -            while(dir)
  512. -            {
  513. -                *dir = '\0';
  514. -                if(!fileexists(dirs, "r") && !createdir(dirs)) return s;
  515. -                *dir = PATHDIV;
  516. -                dir = strchr(dir+1, PATHDIV);
  517. -            }
  518. -            return s;
  519. -        }
  520. -    }
  521. -    if(mode[0]=='w' || mode[0]=='a') return filename;
  522. -    loopv(packagedirs)
  523. -    {
  524. -        formatstring(s)("%s%s", packagedirs[i], filename);
  525. -        if(fileexists(s, mode)) return s;
  526. -    }
  527. -    return filename;
  528. -}
  529. -
  530. -bool listdir(const char *dir, const char *ext, vector<char *> &files)
  531. -{
  532. -    int extsize = ext ? (int)strlen(ext)+1 : 0;
  533. -    #if defined(WIN32)
  534. -    defformatstring(pathname)("%s\\*.%s", dir, ext ? ext : "*");
  535. -    WIN32_FIND_DATA FindFileData;
  536. -    HANDLE Find = FindFirstFile(path(pathname), &FindFileData);
  537. -    if(Find != INVALID_HANDLE_VALUE)
  538. -    {
  539. -        do {
  540. -            files.add(newstring(FindFileData.cFileName, (int)strlen(FindFileData.cFileName) - extsize));
  541. -        } while(FindNextFile(Find, &FindFileData));
  542. -        FindClose(Find);
  543. -        return true;
  544. -    }
  545. -    #else
  546. -    string pathname;
  547. -    copystring(pathname, dir);
  548. -    DIR *d = opendir(path(pathname));
  549. -    if(d)
  550. -    {
  551. -        struct dirent *de;
  552. -        while((de = readdir(d)) != NULL)
  553. -        {
  554. -            if(!ext) files.add(newstring(de->d_name));
  555. -            else
  556. -            {
  557. -                int namelength = (int)strlen(de->d_name) - extsize;
  558. -                if(namelength > 0 && de->d_name[namelength] == '.' && strncmp(de->d_name+namelength+1, ext, extsize-1)==0)
  559. -                    files.add(newstring(de->d_name, namelength));
  560. -            }
  561. -        }
  562. -        closedir(d);
  563. -        return true;
  564. -    }
  565. -    #endif
  566. -    else return false;
  567. -}
  568. -
  569. -int listfiles(const char *dir, const char *ext, vector<char *> &files)
  570. -{
  571. -    int dirs = 0;
  572. -    if(listdir(dir, ext, files)) dirs++;
  573. -    string s;
  574. -    if(homedir[0])
  575. -    {
  576. -        formatstring(s)("%s%s", homedir, dir);
  577. -        if(listdir(s, ext, files)) dirs++;
  578. -    }
  579. -    loopv(packagedirs)
  580. -    {
  581. -        formatstring(s)("%s%s", packagedirs[i], dir);
  582. -        if(listdir(s, ext, files)) dirs++;
  583. -    }
  584. -#ifndef STANDALONE
  585. -    dirs += listzipfiles(dir, ext, files);
  586. -#endif
  587. -    return dirs;
  588. -}
  589. -
  590. -bool delfile(const char *path)
  591. -{
  592. -    return !remove(path);
  593. -}
  594. -
  595. -#ifndef STANDALONE
  596. -static int rwopsseek(SDL_RWops *rw, int offset, int whence)
  597. -{
  598. -    stream *f = (stream *)rw->hidden.unknown.data1;
  599. -    if((!offset && whence==SEEK_CUR) || f->seek(offset, whence)) return f->tell();
  600. -    return -1;
  601. -}
  602. -
  603. -static int rwopsread(SDL_RWops *rw, void *buf, int size, int nmemb)
  604. -{
  605. -    stream *f = (stream *)rw->hidden.unknown.data1;
  606. -    return f->read(buf, size*nmemb)/size;
  607. -}
  608. -
  609. -static int rwopswrite(SDL_RWops *rw, const void *buf, int size, int nmemb)
  610. -{
  611. -    stream *f = (stream *)rw->hidden.unknown.data1;
  612. -    return f->write(buf, size*nmemb)/size;
  613. -}
  614. -
  615. -static int rwopsclose(SDL_RWops *rw)
  616. -{
  617. -    return 0;
  618. -}
  619. -
  620. -SDL_RWops *stream::rwops()
  621. -{
  622. -    SDL_RWops *rw = SDL_AllocRW();
  623. -    if(!rw) return NULL;
  624. -    rw->hidden.unknown.data1 = this;
  625. -    rw->seek = rwopsseek;
  626. -    rw->read = rwopsread;
  627. -    rw->write = rwopswrite;
  628. -    rw->close = rwopsclose;
  629. -    return rw;
  630. -}
  631. -#endif
  632. -
  633. -long stream::size()
  634. -{
  635. -    long pos = tell(), endpos;
  636. -    if(pos < 0 || !seek(0, SEEK_END)) return -1;
  637. -    endpos = tell();
  638. -    return pos == endpos || seek(pos, SEEK_SET) ? endpos : -1;
  639. -}
  640. -
  641. -bool stream::getline(char *str, int len)
  642. -{
  643. -    loopi(len-1)
  644. -    {
  645. -        if(read(&str[i], 1) != 1) { str[i] = '\0'; return i > 0; }
  646. -        else if(str[i] == '\n') { str[i+1] = '\0'; return true; }
  647. -    }
  648. -    if(len > 0) str[len-1] = '\0';
  649. -    return true;
  650. -}
  651. -
  652. -#ifdef __linux__
  653. -#include <sys/statvfs.h>
  654. -#define MINFSSIZE 50000000ull           // 50MB
  655. -#endif
  656. -
  657. -struct filestream : stream
  658. -{
  659. -    FILE *file;
  660. -
  661. -    filestream() : file(NULL) {}
  662. -    ~filestream() { close(); }
  663. -
  664. -    bool open(const char *name, const char *mode)
  665. -    {
  666. -        if(file) return false;
  667. -        file = fopen(name, mode);
  668. -#ifdef __linux__
  669. -        struct statvfs buf;
  670. -        if(file && strchr(mode,'w'))
  671. -        {
  672. -            int fail = fstatvfs(fileno(file), &buf);
  673. -            if (fail || (unsigned long long)buf.f_frsize * (unsigned long long)buf.f_bavail < MINFSSIZE)
  674. -            {
  675. -                close();
  676. -                return false;
  677. -            }
  678. -        }
  679. -#endif
  680. -        return file!=NULL;
  681. -    }
  682. -
  683. -    bool opentemp(const char *name, const char *mode)
  684. -    {
  685. -        if(file) return false;
  686. -#ifdef WIN32
  687. -        file = fopen(name, mode);
  688. -#else
  689. -        file = tmpfile();
  690. -#endif
  691. -        return file!=NULL;
  692. -    }
  693. -
  694. -    void close()
  695. -    {
  696. -        if(file) { fclose(file); file = NULL; }
  697. -    }
  698. -
  699. -    bool end() { return feof(file)!=0; }
  700. -    long tell() { return ftell(file); }
  701. -    bool seek(long offset, int whence) { return fseek(file, offset, whence) >= 0; }
  702. -    int read(void *buf, int len) { return (int)fread(buf, 1, len, file); }
  703. -    int write(const void *buf, int len) { return (int)fwrite(buf, 1, len, file); }
  704. -    int getchar() { return fgetc(file); }
  705. -    bool putchar(int c) { return fputc(c, file)!=EOF; }
  706. -    bool getline(char *str, int len) { return fgets(str, len, file)!=NULL; }
  707. -    bool putstring(const char *str) { return fputs(str, file)!=EOF; }
  708. -
  709. -    int printf(const char *fmt, ...)
  710. -    {
  711. -        va_list v;
  712. -        va_start(v, fmt);
  713. -        int result = vfprintf(file, fmt, v);
  714. -        va_end(v);
  715. -        return result;
  716. -    }
  717. -};
  718. -
  719. -#ifndef STANDALONE
  720. -VAR(dbggz, 0, 0, 1);
  721. -#endif
  722. -
  723. -struct gzstream : stream
  724. -{
  725. -    enum
  726. -    {
  727. -        MAGIC1   = 0x1F,
  728. -        MAGIC2   = 0x8B,
  729. -        BUFSIZE  = 16384,
  730. -        OS_UNIX  = 0x03
  731. -    };
  732. -
  733. -    enum
  734. -    {
  735. -        F_ASCII    = 0x01,
  736. -        F_CRC      = 0x02,
  737. -        F_EXTRA    = 0x04,
  738. -        F_NAME     = 0x08,
  739. -        F_COMMENT  = 0x10,
  740. -        F_RESERVED = 0xE0
  741. -    };
  742. -
  743. -    stream *file;
  744. -    z_stream zfile;
  745. -    uchar *buf;
  746. -    bool reading, writing, autoclose;
  747. -    uint crc;
  748. -    int headersize;
  749. -
  750. -    gzstream() : file(NULL), buf(NULL), reading(false), writing(false), autoclose(false), crc(0), headersize(0)
  751. -    {
  752. -        zfile.zalloc = NULL;
  753. -        zfile.zfree = NULL;
  754. -        zfile.opaque = NULL;
  755. -        zfile.next_in = zfile.next_out = NULL;
  756. -        zfile.avail_in = zfile.avail_out = 0;
  757. -    }
  758. -
  759. -    ~gzstream()
  760. -    {
  761. -        close();
  762. -    }
  763. -
  764. -    void writeheader()
  765. -    {
  766. -        uchar header[] = { MAGIC1, MAGIC2, Z_DEFLATED, 0, 0, 0, 0, 0, 0, OS_UNIX };
  767. -        file->write(header, sizeof(header));
  768. -    }
  769. -
  770. -    void readbuf(int size = BUFSIZE)
  771. -    {
  772. -        if(!zfile.avail_in) zfile.next_in = (Bytef *)buf;
  773. -        size = min(size, int(&buf[BUFSIZE] - &zfile.next_in[zfile.avail_in]));
  774. -        int n = file->read(zfile.next_in + zfile.avail_in, size);
  775. -        if(n > 0) zfile.avail_in += n;
  776. -    }
  777. -
  778. -    int readbyte(int size = BUFSIZE)
  779. -    {
  780. -        if(!zfile.avail_in) readbuf(size);
  781. -        if(!zfile.avail_in) return 0;
  782. -        zfile.avail_in--;
  783. -        return *(uchar *)zfile.next_in++;
  784. -    }
  785. -
  786. -    void skipbytes(int n)
  787. -    {
  788. -        while(n > 0 && zfile.avail_in > 0)
  789. -        {
  790. -            int skipped = min(n, (int)zfile.avail_in);
  791. -            zfile.avail_in -= skipped;
  792. -            zfile.next_in += skipped;
  793. -            n -= skipped;
  794. -        }
  795. -        if(n <= 0) return;
  796. -        file->seek(n, SEEK_CUR);
  797. -    }
  798. -
  799. -    bool checkheader()
  800. -    {
  801. -        readbuf(10);
  802. -        if(readbyte() != MAGIC1 || readbyte() != MAGIC2 || readbyte() != Z_DEFLATED) return false;
  803. -        int flags = readbyte();
  804. -        if(flags & F_RESERVED) return false;
  805. -        skipbytes(6);
  806. -        if(flags & F_EXTRA)
  807. -        {
  808. -            int len = readbyte(512);
  809. -            len |= readbyte(512)<<8;
  810. -            skipbytes(len);
  811. -        }
  812. -        if(flags & F_NAME) while(readbyte(512));
  813. -        if(flags & F_COMMENT) while(readbyte(512));
  814. -        if(flags & F_CRC) skipbytes(2);
  815. -        headersize = file->tell() - zfile.avail_in;
  816. -        return zfile.avail_in > 0 || !file->end();
  817. -    }
  818. -
  819. -    bool open(stream *f, const char *mode, bool needclose, int level)
  820. -    {
  821. -        if(file) return false;
  822. -        for(; *mode; mode++)
  823. -        {
  824. -            if(*mode=='r') { reading = true; break; }
  825. -            else if(*mode=='w') { writing = true; break; }
  826. -        }
  827. -        if(reading)
  828. -        {
  829. -            if(inflateInit2(&zfile, -MAX_WBITS) != Z_OK) reading = false;
  830. -        }
  831. -        else if(writing && deflateInit2(&zfile, level, Z_DEFLATED, -MAX_WBITS, min(MAX_MEM_LEVEL, 8), Z_DEFAULT_STRATEGY) != Z_OK) writing = false;
  832. -        if(!reading && !writing) return false;
  833. -
  834. -        autoclose = needclose;
  835. -        file = f;
  836. -        crc = crc32(0, NULL, 0);
  837. -        buf = new uchar[BUFSIZE];
  838. -
  839. -        if(reading)
  840. -        {
  841. -            if(!checkheader()) { stopreading(); return false; }
  842. -        }
  843. -        else if(writing) writeheader();
  844. -        return true;
  845. -    }
  846. -
  847. -    uint getcrc() { return crc; }
  848. -
  849. -    void finishreading()
  850. -    {
  851. -        if(!reading) return;
  852. -#ifndef STANDALONE
  853. -        if(dbggz)
  854. -        {
  855. -            uint checkcrc = 0, checksize = 0;
  856. -            loopi(4) checkcrc |= uint(readbyte()) << (i*8);
  857. -            loopi(4) checksize |= uint(readbyte()) << (i*8);
  858. -            if(checkcrc != crc)
  859. -                conoutf("gzip crc check failed: read %X, calculated %X", checkcrc, crc);
  860. -            if(checksize != zfile.total_out)
  861. -                conoutf("gzip size check failed: read %d, calculated %d", checksize, zfile.total_out);
  862. -        }
  863. -#endif
  864. -    }
  865. -
  866. -    void stopreading()
  867. -    {
  868. -        if(!reading) return;
  869. -        inflateEnd(&zfile);
  870. -        reading = false;
  871. -    }
  872. -
  873. -    void finishwriting()
  874. -    {
  875. -        if(!writing) return;
  876. -        for(;;)
  877. -        {
  878. -            int err = zfile.avail_out > 0 ? deflate(&zfile, Z_FINISH) : Z_OK;
  879. -            if(err != Z_OK && err != Z_STREAM_END) break;
  880. -            flush();
  881. -            if(err == Z_STREAM_END) break;
  882. -        }
  883. -        uchar trailer[8] =
  884. -        {
  885. -            crc&0xFF, (crc>>8)&0xFF, (crc>>16)&0xFF, (crc>>24)&0xFF,
  886. -            zfile.total_in&0xFF, (zfile.total_in>>8)&0xFF, (zfile.total_in>>16)&0xFF, (zfile.total_in>>24)&0xFF
  887. -        };
  888. -        file->write(trailer, sizeof(trailer));
  889. -    }
  890. -
  891. -    void stopwriting()
  892. -    {
  893. -        if(!writing) return;
  894. -        deflateEnd(&zfile);
  895. -        writing = false;
  896. -    }
  897. -
  898. -    void close()
  899. -    {
  900. -        if(reading) finishreading();
  901. -        stopreading();
  902. -        if(writing) finishwriting();
  903. -        stopwriting();
  904. -        DELETEA(buf);
  905. -        if(autoclose) DELETEP(file);
  906. -    }
  907. -
  908. -    bool end() { return !reading && !writing; }
  909. -    long tell() { return reading ? zfile.total_out : (writing ? zfile.total_in : -1); }
  910. -
  911. -    bool seek(long offset, int whence)
  912. -    {
  913. -        if(writing || !reading) return false;
  914. -
  915. -        if(whence == SEEK_END)
  916. -        {
  917. -            uchar skip[512];
  918. -            while(read(skip, sizeof(skip)) == sizeof(skip));
  919. -            return !offset;
  920. -        }
  921. -        else if(whence == SEEK_CUR) offset += zfile.total_out;
  922. -
  923. -        if(offset >= (int)zfile.total_out) offset -= zfile.total_out;
  924. -        else if(offset < 0 || !file->seek(headersize, SEEK_SET)) return false;
  925. -        else
  926. -        {
  927. -            if(zfile.next_in && zfile.total_in <= uint(zfile.next_in - buf))
  928. -            {
  929. -                zfile.avail_in += zfile.total_in;
  930. -                zfile.next_in -= zfile.total_in;
  931. -            }
  932. -            else
  933. -            {
  934. -                zfile.avail_in = 0;
  935. -                zfile.next_in = NULL;
  936. -            }
  937. -            inflateReset(&zfile);
  938. -            crc = crc32(0, NULL, 0);
  939. -        }
  940. -
  941. -        uchar skip[512];
  942. -        while(offset > 0)
  943. -        {
  944. -            int skipped = min(offset, (long)sizeof(skip));
  945. -            if(read(skip, skipped) != skipped) { stopreading(); return false; }
  946. -            offset -= skipped;
  947. -        }
  948. -
  949. -        return true;
  950. -    }
  951. -
  952. -    int read(void *buf, int len)
  953. -    {
  954. -        if(!reading || !buf || !len) return 0;
  955. -        zfile.next_out = (Bytef *)buf;
  956. -        zfile.avail_out = len;
  957. -        while(zfile.avail_out > 0)
  958. -        {
  959. -            if(!zfile.avail_in)
  960. -            {
  961. -                readbuf(BUFSIZE);
  962. -                if(!zfile.avail_in) { stopreading(); break; }
  963. -            }
  964. -            int err = inflate(&zfile, Z_NO_FLUSH);
  965. -            if(err == Z_STREAM_END) { crc = crc32(crc, (Bytef *)buf, len - zfile.avail_out); finishreading(); stopreading(); return len - zfile.avail_out; }
  966. -            else if(err != Z_OK) { stopreading(); break; }
  967. -        }
  968. -        crc = crc32(crc, (Bytef *)buf, len - zfile.avail_out);
  969. -        return len - zfile.avail_out;
  970. -    }
  971. -
  972. -    bool flush()
  973. -    {
  974. -        if(zfile.next_out && zfile.avail_out < BUFSIZE)
  975. -        {
  976. -            if(file->write(buf, BUFSIZE - zfile.avail_out) != int(BUFSIZE - zfile.avail_out))
  977. -                return false;
  978. -        }
  979. -        zfile.next_out = buf;
  980. -        zfile.avail_out = BUFSIZE;
  981. -        return true;
  982. -    }
  983. -
  984. -    int write(const void *buf, int len)
  985. -    {
  986. -        if(!writing || !buf || !len) return 0;
  987. -        zfile.next_in = (Bytef *)buf;
  988. -        zfile.avail_in = len;
  989. -        while(zfile.avail_in > 0)
  990. -        {
  991. -            if(!zfile.avail_out && !flush()) { stopwriting(); break; }
  992. -            int err = deflate(&zfile, Z_NO_FLUSH);
  993. -            if(err != Z_OK) { stopwriting(); break; }
  994. -        }
  995. -        crc = crc32(crc, (Bytef *)buf, len - zfile.avail_in);
  996. -        return len - zfile.avail_in;
  997. -    }
  998. -};
  999. -
  1000. -
  1001. -stream *openrawfile(const char *filename, const char *mode)
  1002. -{
  1003. -    const char *found = findfile(filename, mode);
  1004. -#ifndef STANDALONE
  1005. -    if(mode && (mode[0]=='w' || mode[0]=='a')) conoutf("writing to file: %s", found);
  1006. -#endif
  1007. -    if(!found) return NULL;
  1008. -    filestream *file = new filestream;
  1009. -    if(!file->open(found, mode))
  1010. -    {
  1011. -#ifndef STANDALONE
  1012. -//         conoutf("file failure! %s",filename);
  1013. -#endif
  1014. -        delete file; return NULL;
  1015. -    }
  1016. -    return file;
  1017. -}
  1018. -
  1019. -stream *openfile(const char *filename, const char *mode)
  1020. -{
  1021. -#ifndef STANDALONE
  1022. -    stream *s = openzipfile(filename, mode);
  1023. -    if(s) return s;
  1024. -#endif
  1025. -    return openrawfile(filename, mode);
  1026. -}
  1027. -
  1028. -int getfilesize(const char *filename)
  1029. -{
  1030. -    stream *f = openfile(filename, "rb");
  1031. -    if(!f) return -1;
  1032. -    int len = f->size();
  1033. -    delete f;
  1034. -    return len;
  1035. -}
  1036. -
  1037. -stream *opentempfile(const char *name, const char *mode)
  1038. -{
  1039. -    const char *found = findfile(name, mode);
  1040. -    filestream *file = new filestream;
  1041. -    if(!file->opentemp(found ? found : name, mode)) { delete file; return NULL; }
  1042. -    return file;
  1043. -}
  1044. -
  1045. -stream *opengzfile(const char *filename, const char *mode, stream *file, int level)
  1046. -{
  1047. -    stream *source = file ? file : openfile(filename, mode);
  1048. -    if(!source) return NULL;
  1049. -    gzstream *gz = new gzstream;
  1050. -    if(!gz->open(source, mode, !file, level)) { if(!file) delete source; return NULL; }
  1051. -    return gz;
  1052. -}
  1053. -
  1054. -char *loadfile(const char *fn, int *size, const char *mode)
  1055. -{
  1056. -    stream *f = openfile(fn, mode ? mode : "rb");
  1057. -    if(!f) return NULL;
  1058. -    int len = f->size();
  1059. -    if(len<=0) { delete f; return NULL; }
  1060. -    char *buf = new char[len+1];
  1061. -    if(!buf) { delete f; return NULL; }
  1062. -    buf[len] = 0;
  1063. -    int rlen = f->read(buf, len);
  1064. -    delete f;
  1065. -    if(len!=rlen && (!mode || strchr(mode, 'b')))
  1066. -    {
  1067. -        delete[] buf;
  1068. -        return NULL;
  1069. -    }
  1070. -    if(size!=NULL) *size = len;
  1071. -    return buf;
  1072. -}
  1073. -
  1074. +#include "cube.h"
  1075. +
  1076. +///////////////////////// file system ///////////////////////
  1077. +
  1078. +#ifndef WIN32
  1079. +#include <unistd.h>
  1080. +#include <sys/stat.h>
  1081. +#include <sys/types.h>
  1082. +#include <dirent.h>
  1083. +#endif
  1084. +
  1085. +string homedir = "";
  1086. +vector<char *> packagedirs;
  1087. +
  1088. +char *makerelpath(const char *dir, const char *file, const char *prefix, const char *cmd)
  1089. +{
  1090. +    static string tmp;
  1091. +    if(prefix) copystring(tmp, prefix);
  1092. +    else tmp[0] = '\0';
  1093. +    if(file[0]=='<')
  1094. +    {
  1095. +        const char *end = strrchr(file, '>');
  1096. +        if(end)
  1097. +        {
  1098. +            size_t len = strlen(tmp);
  1099. +            copystring(&tmp[len], file, min(sizeof(tmp)-len, size_t(end+2-file)));
  1100. +            file = end+1;
  1101. +        }
  1102. +    }
  1103. +    if(cmd) concatstring(tmp, cmd);
  1104. +    defformatstring(pname)("%s/%s", dir, file);
  1105. +    concatstring(tmp, pname);
  1106. +    return tmp;
  1107. +}
  1108. +
  1109. +
  1110. +char *path(char *s)
  1111. +{
  1112. +    for(char *curpart = s;;)
  1113. +    {
  1114. +        char *endpart = strchr(curpart, '&');
  1115. +        if(endpart) *endpart = '\0';
  1116. +        if(curpart[0]=='<')
  1117. +        {
  1118. +            char *file = strrchr(curpart, '>');
  1119. +            if(!file) return s;
  1120. +            curpart = file+1;
  1121. +        }
  1122. +        for(char *t = curpart; (t = strpbrk(t, "/\\")); *t++ = PATHDIV);
  1123. +        for(char *prevdir = NULL, *curdir = s;;)
  1124. +        {
  1125. +            prevdir = curdir[0]==PATHDIV ? curdir+1 : curdir;
  1126. +            curdir = strchr(prevdir, PATHDIV);
  1127. +            if(!curdir) break;
  1128. +            if(prevdir+1==curdir && prevdir[0]=='.')
  1129. +            {
  1130. +                memmove(prevdir, curdir+1, strlen(curdir+1)+1);
  1131. +                curdir = prevdir;
  1132. +            }
  1133. +            else if(curdir[1]=='.' && curdir[2]=='.' && curdir[3]==PATHDIV)
  1134. +            {
  1135. +                if(prevdir+2==curdir && prevdir[0]=='.' && prevdir[1]=='.') continue;
  1136. +                memmove(prevdir, curdir+4, strlen(curdir+4)+1);
  1137. +                curdir = prevdir;
  1138. +            }
  1139. +        }
  1140. +        if(endpart)
  1141. +        {
  1142. +            *endpart = '&';
  1143. +            curpart = endpart+1;
  1144. +        }
  1145. +        else break;
  1146. +    }
  1147. +    return s;
  1148. +}
  1149. +
  1150. +char *path(const char *s, bool copy)
  1151. +{
  1152. +    static string tmp;
  1153. +    copystring(tmp, s);
  1154. +    path(tmp);
  1155. +    return tmp;
  1156. +}
  1157. +
  1158. +const char *parentdir(const char *directory)
  1159. +{
  1160. +    const char *p = directory + strlen(directory);
  1161. +    while(p > directory && *p != '/' && *p != '\\') p--;
  1162. +    static string parent;
  1163. +    size_t len = p-directory+1;
  1164. +    copystring(parent, directory, len);
  1165. +    return parent;
  1166. +}
  1167. +
  1168. +const char *behindpath(const char *s)
  1169. +{
  1170. +    const char *t = s;
  1171. +    for( ; (s = strpbrk(s, "/\\")); t = ++s);
  1172. +    return t;
  1173. +}
  1174. +
  1175. +bool fileexists(const char *path, const char *mode)
  1176. +{
  1177. +    bool exists = true;
  1178. +    if(mode[0]=='w' || mode[0]=='a') path = parentdir(path);
  1179. +#ifdef WIN32
  1180. +    if(GetFileAttributes(path) == INVALID_FILE_ATTRIBUTES) exists = false;
  1181. +#else
  1182. +    if(access(path, R_OK | (mode[0]=='w' || mode[0]=='a' ? W_OK : 0)) == -1) exists = false;
  1183. +#endif
  1184. +    return exists;
  1185. +}
  1186. +
  1187. +bool createdir(const char *path)
  1188. +{
  1189. +    size_t len = strlen(path);
  1190. +    if(path[len-1]==PATHDIV)
  1191. +    {
  1192. +        static string strip;
  1193. +        path = copystring(strip, path, len);
  1194. +    }
  1195. +#ifdef WIN32
  1196. +    return CreateDirectory(path, NULL)!=0;
  1197. +#else
  1198. +    return mkdir(path, 0777)==0;
  1199. +#endif
  1200. +}
  1201. +
  1202. +size_t fixpackagedir(char *dir)
  1203. +{
  1204. +    path(dir);
  1205. +    size_t len = strlen(dir);
  1206. +    if(len > 0 && dir[len-1] != PATHDIV)
  1207. +    {
  1208. +        dir[len] = PATHDIV;
  1209. +        dir[len+1] = '\0';
  1210. +    }
  1211. +    return len;
  1212. +}
  1213. +
  1214. +#ifdef WIN32
  1215. +char *getregszvalue(HKEY root, const char *keystr, const char *query)
  1216. +{
  1217. +    HKEY key;
  1218. +    if(RegOpenKeyEx(HKEY_CURRENT_USER, keystr, 0, KEY_READ, &key)==ERROR_SUCCESS)
  1219. +    {
  1220. +        DWORD type = 0, len = 0;
  1221. +        if(RegQueryValueEx(key, query, 0, &type, 0, &len)==ERROR_SUCCESS && type==REG_SZ)
  1222. +        {
  1223. +            char *val = new char[len];
  1224. +            long result = RegQueryValueEx(key, query, 0, &type, (uchar *)val, &len);
  1225. +            if(result==ERROR_SUCCESS)
  1226. +            {
  1227. +                RegCloseKey(key);
  1228. +                val[len-1] = '\0';
  1229. +                return val;
  1230. +            }
  1231. +            delete[] val;
  1232. +        }
  1233. +        RegCloseKey(key);
  1234. +    }
  1235. +    return NULL;
  1236. +}
  1237. +#endif
  1238. +
  1239. +void sethomedir(const char *dir)
  1240. +{
  1241. +    string tmpdir;
  1242. +    copystring(tmpdir, dir);
  1243. +
  1244. +#ifdef WIN32
  1245. +    const char substitute[] = "?MYDOCUMENTS?";
  1246. +    if(!strncmp(dir, substitute, strlen(substitute)))
  1247. +    {
  1248. +        const char *regpath = "Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders";
  1249. +        char *mydocuments = getregszvalue(HKEY_CURRENT_USER, regpath, "Personal");
  1250. +        if(mydocuments)
  1251. +        {
  1252. +            formatstring(tmpdir)("%s%s", mydocuments, dir+strlen(substitute));
  1253. +            delete[] mydocuments;
  1254. +        }
  1255. +        else
  1256. +        {
  1257. +            printf("failed to retrieve 'Personal' path from '%s'\n", regpath);
  1258. +        }
  1259. +    }
  1260. +#endif
  1261. +
  1262. +#ifndef STANDALONE
  1263. +    clientlogf("Using home directory: %s", tmpdir);
  1264. +#endif
  1265. +
  1266. +    if(fixpackagedir(tmpdir) > 0)
  1267. +    {
  1268. +        copystring(homedir, tmpdir);
  1269. +        createdir(homedir);
  1270. +    }
  1271. +}
  1272. +
  1273. +void addpackagedir(const char *dir)
  1274. +{
  1275. +#ifndef STANDALONE
  1276. +    clientlogf("Adding package directory: %s", dir);
  1277. +#endif
  1278. +
  1279. +    string pdir;
  1280. +    copystring(pdir, dir);
  1281. +    if(fixpackagedir(pdir) > 0) packagedirs.add(newstring(pdir));
  1282. +}
  1283. +
  1284. +const char *findfile(const char *filename, const char *mode)
  1285. +{
  1286. +    static string s;
  1287. +    if(homedir[0])
  1288. +    {
  1289. +        formatstring(s)("%s%s", homedir, filename);
  1290. +        if(fileexists(s, mode)) return s;
  1291. +        if(mode[0]=='w' || mode[0]=='a')
  1292. +        {
  1293. +            string dirs;
  1294. +            copystring(dirs, s);
  1295. +            char *dir = strchr(dirs[0]==PATHDIV ? dirs+1 : dirs, PATHDIV);
  1296. +            while(dir)
  1297. +            {
  1298. +                *dir = '\0';
  1299. +                if(!fileexists(dirs, "r") && !createdir(dirs)) return s;
  1300. +                *dir = PATHDIV;
  1301. +                dir = strchr(dir+1, PATHDIV);
  1302. +            }
  1303. +            return s;
  1304. +        }
  1305. +    }
  1306. +    if(mode[0]=='w' || mode[0]=='a') return filename;
  1307. +    loopv(packagedirs)
  1308. +    {
  1309. +        formatstring(s)("%s%s", packagedirs[i], filename);
  1310. +        if(fileexists(s, mode)) return s;
  1311. +    }
  1312. +    return filename;
  1313. +}
  1314. +
  1315. +bool listdir(const char *dir, const char *ext, vector<char *> &files)
  1316. +{
  1317. +    int extsize = ext ? (int)strlen(ext)+1 : 0;
  1318. +    #if defined(WIN32)
  1319. +    defformatstring(pathname)("%s\\*.%s", dir, ext ? ext : "*");
  1320. +    WIN32_FIND_DATA FindFileData;
  1321. +    HANDLE Find = FindFirstFile(path(pathname), &FindFileData);
  1322. +    if(Find != INVALID_HANDLE_VALUE)
  1323. +    {
  1324. +        do {
  1325. +            files.add(newstring(FindFileData.cFileName, (int)strlen(FindFileData.cFileName) - extsize));
  1326. +        } while(FindNextFile(Find, &FindFileData));
  1327. +        FindClose(Find);
  1328. +        return true;
  1329. +    }
  1330. +    #else
  1331. +    string pathname;
  1332. +    copystring(pathname, dir);
  1333. +    DIR *d = opendir(path(pathname));
  1334. +    if(d)
  1335. +    {
  1336. +        struct dirent *de;
  1337. +        while((de = readdir(d)) != NULL)
  1338. +        {
  1339. +            if(!ext) files.add(newstring(de->d_name));
  1340. +            else
  1341. +            {
  1342. +                int namelength = (int)strlen(de->d_name) - extsize;
  1343. +                if(namelength > 0 && de->d_name[namelength] == '.' && strncmp(de->d_name+namelength+1, ext, extsize-1)==0)
  1344. +                    files.add(newstring(de->d_name, namelength));
  1345. +            }
  1346. +        }
  1347. +        closedir(d);
  1348. +        return true;
  1349. +    }
  1350. +    #endif
  1351. +    else return false;
  1352. +}
  1353. +
  1354. +int listfiles(const char *dir, const char *ext, vector<char *> &files)
  1355. +{
  1356. +    int dirs = 0;
  1357. +    if(listdir(dir, ext, files)) dirs++;
  1358. +    string s;
  1359. +    if(homedir[0])
  1360. +    {
  1361. +        formatstring(s)("%s%s", homedir, dir);
  1362. +        if(listdir(s, ext, files)) dirs++;
  1363. +    }
  1364. +    loopv(packagedirs)
  1365. +    {
  1366. +        formatstring(s)("%s%s", packagedirs[i], dir);
  1367. +        if(listdir(s, ext, files)) dirs++;
  1368. +    }
  1369. +#ifndef STANDALONE
  1370. +    dirs += listzipfiles(dir, ext, files);
  1371. +#endif
  1372. +    return dirs;
  1373. +}
  1374. +
  1375. +bool delfile(const char *path)
  1376. +{
  1377. +    return !remove(path);
  1378. +}
  1379. +
  1380. +bool copyfile(const char *source, const char *destination)
  1381. +{
  1382. +    FILE *from = fopen(source, "rb");
  1383. +    FILE *dest = fopen(destination, "wb");
  1384. +    
  1385. +    if(!from) { return false; }
  1386. +    if(!dest) { return false; }
  1387. +    size_t len;
  1388. +    uchar buf[1024];
  1389. +    while(len = fread(&buf, sizeof(uchar), 1024, from))
  1390. +    {
  1391. +        fwrite(&buf, sizeof(uchar), len, dest);
  1392. +    }
  1393. +    fclose(from);
  1394. +    fclose(dest);
  1395. +    return true;
  1396. +}
  1397. +
  1398. +bool preparedir(const char *destination)
  1399. +{
  1400. +    string dir;
  1401. +    copystring(dir, parentdir(destination));
  1402. +    vector<char *> dirs;
  1403. +    while(!fileexists(dir, "r"))
  1404. +    {
  1405. +        dirs.add(newstring(dir));
  1406. +        copystring(dir, parentdir(dir));
  1407. +    }
  1408. +    for(int i = dirs.length() - 1; i >= 0; --i) if(!createdir(dirs[i])) return false;
  1409. +    return true;
  1410. +}
  1411. +
  1412. +#ifndef STANDALONE
  1413. +static int rwopsseek(SDL_RWops *rw, int offset, int whence)
  1414. +{
  1415. +    stream *f = (stream *)rw->hidden.unknown.data1;
  1416. +    if((!offset && whence==SEEK_CUR) || f->seek(offset, whence)) return f->tell();
  1417. +    return -1;
  1418. +}
  1419. +
  1420. +static int rwopsread(SDL_RWops *rw, void *buf, int size, int nmemb)
  1421. +{
  1422. +    stream *f = (stream *)rw->hidden.unknown.data1;
  1423. +    return f->read(buf, size*nmemb)/size;
  1424. +}
  1425. +
  1426. +static int rwopswrite(SDL_RWops *rw, const void *buf, int size, int nmemb)
  1427. +{
  1428. +    stream *f = (stream *)rw->hidden.unknown.data1;
  1429. +    return f->write(buf, size*nmemb)/size;
  1430. +}
  1431. +
  1432. +static int rwopsclose(SDL_RWops *rw)
  1433. +{
  1434. +    return 0;
  1435. +}
  1436. +
  1437. +SDL_RWops *stream::rwops()
  1438. +{
  1439. +    SDL_RWops *rw = SDL_AllocRW();
  1440. +    if(!rw) return NULL;
  1441. +    rw->hidden.unknown.data1 = this;
  1442. +    rw->seek = rwopsseek;
  1443. +    rw->read = rwopsread;
  1444. +    rw->write = rwopswrite;
  1445. +    rw->close = rwopsclose;
  1446. +    return rw;
  1447. +}
  1448. +#endif
  1449. +
  1450. +long stream::size()
  1451. +{
  1452. +    long pos = tell(), endpos;
  1453. +    if(pos < 0 || !seek(0, SEEK_END)) return -1;
  1454. +    endpos = tell();
  1455. +    return pos == endpos || seek(pos, SEEK_SET) ? endpos : -1;
  1456. +}
  1457. +
  1458. +bool stream::getline(char *str, int len)
  1459. +{
  1460. +    loopi(len-1)
  1461. +    {
  1462. +        if(read(&str[i], 1) != 1) { str[i] = '\0'; return i > 0; }
  1463. +        else if(str[i] == '\n') { str[i+1] = '\0'; return true; }
  1464. +    }
  1465. +    if(len > 0) str[len-1] = '\0';
  1466. +    return true;
  1467. +}
  1468. +
  1469. +#ifdef __linux__
  1470. +#include <sys/statvfs.h>
  1471. +#define MINFSSIZE 50000000ull           // 50MB
  1472. +#endif
  1473. +
  1474. +struct filestream : stream
  1475. +{
  1476. +    FILE *file;
  1477. +
  1478. +    filestream() : file(NULL) {}
  1479. +    ~filestream() { close(); }
  1480. +
  1481. +    bool open(const char *name, const char *mode)
  1482. +    {
  1483. +        if(file) return false;
  1484. +        file = fopen(name, mode);
  1485. +#ifdef __linux__
  1486. +        struct statvfs buf;
  1487. +        if(file && strchr(mode,'w'))
  1488. +        {
  1489. +            int fail = fstatvfs(fileno(file), &buf);
  1490. +            if (fail || (unsigned long long)buf.f_frsize * (unsigned long long)buf.f_bavail < MINFSSIZE)
  1491. +            {
  1492. +                close();
  1493. +                return false;
  1494. +            }
  1495. +        }
  1496. +#endif
  1497. +        return file!=NULL;
  1498. +    }
  1499. +
  1500. +    bool opentemp(const char *name, const char *mode)
  1501. +    {
  1502. +        if(file) return false;
  1503. +#ifdef WIN32
  1504. +        file = fopen(name, mode);
  1505. +#else
  1506. +        file = tmpfile();
  1507. +#endif
  1508. +        return file!=NULL;
  1509. +    }
  1510. +
  1511. +    void close()
  1512. +    {
  1513. +        if(file) { fclose(file); file = NULL; }
  1514. +    }
  1515. +
  1516. +    bool end() { return feof(file)!=0; }
  1517. +    long tell() { return ftell(file); }
  1518. +    bool seek(long offset, int whence) { return fseek(file, offset, whence) >= 0; }
  1519. +    int read(void *buf, int len) { return (int)fread(buf, 1, len, file); }
  1520. +    int write(const void *buf, int len) { return (int)fwrite(buf, 1, len, file); }
  1521. +    int getchar() { return fgetc(file); }
  1522. +    bool putchar(int c) { return fputc(c, file)!=EOF; }
  1523. +    bool getline(char *str, int len) { return fgets(str, len, file)!=NULL; }
  1524. +    bool putstring(const char *str) { return fputs(str, file)!=EOF; }
  1525. +
  1526. +    int printf(const char *fmt, ...)
  1527. +    {
  1528. +        va_list v;
  1529. +        va_start(v, fmt);
  1530. +        int result = vfprintf(file, fmt, v);
  1531. +        va_end(v);
  1532. +        return result;
  1533. +    }
  1534. +};
  1535. +
  1536. +#ifndef STANDALONE
  1537. +VAR(dbggz, 0, 0, 1);
  1538. +#endif
  1539. +
  1540. +struct gzstream : stream
  1541. +{
  1542. +    enum
  1543. +    {
  1544. +        MAGIC1   = 0x1F,
  1545. +        MAGIC2   = 0x8B,
  1546. +        BUFSIZE  = 16384,
  1547. +        OS_UNIX  = 0x03
  1548. +    };
  1549. +
  1550. +    enum
  1551. +    {
  1552. +        F_ASCII    = 0x01,
  1553. +        F_CRC      = 0x02,
  1554. +        F_EXTRA    = 0x04,
  1555. +        F_NAME     = 0x08,
  1556. +        F_COMMENT  = 0x10,
  1557. +        F_RESERVED = 0xE0
  1558. +    };
  1559. +
  1560. +    stream *file;
  1561. +    z_stream zfile;
  1562. +    uchar *buf;
  1563. +    bool reading, writing, autoclose;
  1564. +    uint crc;
  1565. +    int headersize;
  1566. +
  1567. +    gzstream() : file(NULL), buf(NULL), reading(false), writing(false), autoclose(false), crc(0), headersize(0)
  1568. +    {
  1569. +        zfile.zalloc = NULL;
  1570. +        zfile.zfree = NULL;
  1571. +        zfile.opaque = NULL;
  1572. +        zfile.next_in = zfile.next_out = NULL;
  1573. +        zfile.avail_in = zfile.avail_out = 0;
  1574. +    }
  1575. +
  1576. +    ~gzstream()
  1577. +    {
  1578. +        close();
  1579. +    }
  1580. +
  1581. +    void writeheader()
  1582. +    {
  1583. +        uchar header[] = { MAGIC1, MAGIC2, Z_DEFLATED, 0, 0, 0, 0, 0, 0, OS_UNIX };
  1584. +        file->write(header, sizeof(header));
  1585. +    }
  1586. +
  1587. +    void readbuf(int size = BUFSIZE)
  1588. +    {
  1589. +        if(!zfile.avail_in) zfile.next_in = (Bytef *)buf;
  1590. +        size = min(size, int(&buf[BUFSIZE] - &zfile.next_in[zfile.avail_in]));
  1591. +        int n = file->read(zfile.next_in + zfile.avail_in, size);
  1592. +        if(n > 0) zfile.avail_in += n;
  1593. +    }
  1594. +
  1595. +    int readbyte(int size = BUFSIZE)
  1596. +    {
  1597. +        if(!zfile.avail_in) readbuf(size);
  1598. +        if(!zfile.avail_in) return 0;
  1599. +        zfile.avail_in--;
  1600. +        return *(uchar *)zfile.next_in++;
  1601. +    }
  1602. +
  1603. +    void skipbytes(int n)
  1604. +    {
  1605. +        while(n > 0 && zfile.avail_in > 0)
  1606. +        {
  1607. +            int skipped = min(n, (int)zfile.avail_in);
  1608. +            zfile.avail_in -= skipped;
  1609. +            zfile.next_in += skipped;
  1610. +            n -= skipped;
  1611. +        }
  1612. +        if(n <= 0) return;
  1613. +        file->seek(n, SEEK_CUR);
  1614. +    }
  1615. +
  1616. +    bool checkheader()
  1617. +    {
  1618. +        readbuf(10);
  1619. +        if(readbyte() != MAGIC1 || readbyte() != MAGIC2 || readbyte() != Z_DEFLATED) return false;
  1620. +        int flags = readbyte();
  1621. +        if(flags & F_RESERVED) return false;
  1622. +        skipbytes(6);
  1623. +        if(flags & F_EXTRA)
  1624. +        {
  1625. +            int len = readbyte(512);
  1626. +            len |= readbyte(512)<<8;
  1627. +            skipbytes(len);
  1628. +        }
  1629. +        if(flags & F_NAME) while(readbyte(512));
  1630. +        if(flags & F_COMMENT) while(readbyte(512));
  1631. +        if(flags & F_CRC) skipbytes(2);
  1632. +        headersize = file->tell() - zfile.avail_in;
  1633. +        return zfile.avail_in > 0 || !file->end();
  1634. +    }
  1635. +
  1636. +    bool open(stream *f, const char *mode, bool needclose, int level)
  1637. +    {
  1638. +        if(file) return false;
  1639. +        for(; *mode; mode++)
  1640. +        {
  1641. +            if(*mode=='r') { reading = true; break; }
  1642. +            else if(*mode=='w') { writing = true; break; }
  1643. +        }
  1644. +        if(reading)
  1645. +        {
  1646. +            if(inflateInit2(&zfile, -MAX_WBITS) != Z_OK) reading = false;
  1647. +        }
  1648. +        else if(writing && deflateInit2(&zfile, level, Z_DEFLATED, -MAX_WBITS, min(MAX_MEM_LEVEL, 8), Z_DEFAULT_STRATEGY) != Z_OK) writing = false;
  1649. +        if(!reading && !writing) return false;
  1650. +
  1651. +        autoclose = needclose;
  1652. +        file = f;
  1653. +        crc = crc32(0, NULL, 0);
  1654. +        buf = new uchar[BUFSIZE];
  1655. +
  1656. +        if(reading)
  1657. +        {
  1658. +            if(!checkheader()) { stopreading(); return false; }
  1659. +        }
  1660. +        else if(writing) writeheader();
  1661. +        return true;
  1662. +    }
  1663. +
  1664. +    uint getcrc() { return crc; }
  1665. +
  1666. +    void finishreading()
  1667. +    {
  1668. +        if(!reading) return;
  1669. +#ifndef STANDALONE
  1670. +        if(dbggz)
  1671. +        {
  1672. +            uint checkcrc = 0, checksize = 0;
  1673. +            loopi(4) checkcrc |= uint(readbyte()) << (i*8);
  1674. +            loopi(4) checksize |= uint(readbyte()) << (i*8);
  1675. +            if(checkcrc != crc)
  1676. +                conoutf("gzip crc check failed: read %X, calculated %X", checkcrc, crc);
  1677. +            if(checksize != zfile.total_out)
  1678. +                conoutf("gzip size check failed: read %d, calculated %d", checksize, zfile.total_out);
  1679. +        }
  1680. +#endif
  1681. +    }
  1682. +
  1683. +    void stopreading()
  1684. +    {
  1685. +        if(!reading) return;
  1686. +        inflateEnd(&zfile);
  1687. +        reading = false;
  1688. +    }
  1689. +
  1690. +    void finishwriting()
  1691. +    {
  1692. +        if(!writing) return;
  1693. +        for(;;)
  1694. +        {
  1695. +            int err = zfile.avail_out > 0 ? deflate(&zfile, Z_FINISH) : Z_OK;
  1696. +            if(err != Z_OK && err != Z_STREAM_END) break;
  1697. +            flush();
  1698. +            if(err == Z_STREAM_END) break;
  1699. +        }
  1700. +        uchar trailer[8] =
  1701. +        {
  1702. +            crc&0xFF, (crc>>8)&0xFF, (crc>>16)&0xFF, (crc>>24)&0xFF,
  1703. +            zfile.total_in&0xFF, (zfile.total_in>>8)&0xFF, (zfile.total_in>>16)&0xFF, (zfile.total_in>>24)&0xFF
  1704. +        };
  1705. +        file->write(trailer, sizeof(trailer));
  1706. +    }
  1707. +
  1708. +    void stopwriting()
  1709. +    {
  1710. +        if(!writing) return;
  1711. +        deflateEnd(&zfile);
  1712. +        writing = false;
  1713. +    }
  1714. +
  1715. +    void close()
  1716. +    {
  1717. +        if(reading) finishreading();
  1718. +        stopreading();
  1719. +        if(writing) finishwriting();
  1720. +        stopwriting();
  1721. +        DELETEA(buf);
  1722. +        if(autoclose) DELETEP(file);
  1723. +    }
  1724. +
  1725. +    bool end() { return !reading && !writing; }
  1726. +    long tell() { return reading ? zfile.total_out : (writing ? zfile.total_in : -1); }
  1727. +
  1728. +    bool seek(long offset, int whence)
  1729. +    {
  1730. +        if(writing || !reading) return false;
  1731. +
  1732. +        if(whence == SEEK_END)
  1733. +        {
  1734. +            uchar skip[512];
  1735. +            while(read(skip, sizeof(skip)) == sizeof(skip));
  1736. +            return !offset;
  1737. +        }
  1738. +        else if(whence == SEEK_CUR) offset += zfile.total_out;
  1739. +
  1740. +        if(offset >= (int)zfile.total_out) offset -= zfile.total_out;
  1741. +        else if(offset < 0 || !file->seek(headersize, SEEK_SET)) return false;
  1742. +        else
  1743. +        {
  1744. +            if(zfile.next_in && zfile.total_in <= uint(zfile.next_in - buf))
  1745. +            {
  1746. +                zfile.avail_in += zfile.total_in;
  1747. +                zfile.next_in -= zfile.total_in;
  1748. +            }
  1749. +            else
  1750. +            {
  1751. +                zfile.avail_in = 0;
  1752. +                zfile.next_in = NULL;
  1753. +            }
  1754. +            inflateReset(&zfile);
  1755. +            crc = crc32(0, NULL, 0);
  1756. +        }
  1757. +
  1758. +        uchar skip[512];
  1759. +        while(offset > 0)
  1760. +        {
  1761. +            int skipped = min(offset, (long)sizeof(skip));
  1762. +            if(read(skip, skipped) != skipped) { stopreading(); return false; }
  1763. +            offset -= skipped;
  1764. +        }
  1765. +
  1766. +        return true;
  1767. +    }
  1768. +
  1769. +    int read(void *buf, int len)
  1770. +    {
  1771. +        if(!reading || !buf || !len) return 0;
  1772. +        zfile.next_out = (Bytef *)buf;
  1773. +        zfile.avail_out = len;
  1774. +        while(zfile.avail_out > 0)
  1775. +        {
  1776. +            if(!zfile.avail_in)
  1777. +            {
  1778. +                readbuf(BUFSIZE);
  1779. +                if(!zfile.avail_in) { stopreading(); break; }
  1780. +            }
  1781. +            int err = inflate(&zfile, Z_NO_FLUSH);
  1782. +            if(err == Z_STREAM_END) { crc = crc32(crc, (Bytef *)buf, len - zfile.avail_out); finishreading(); stopreading(); return len - zfile.avail_out; }
  1783. +            else if(err != Z_OK) { stopreading(); break; }
  1784. +        }
  1785. +        crc = crc32(crc, (Bytef *)buf, len - zfile.avail_out);
  1786. +        return len - zfile.avail_out;
  1787. +    }
  1788. +
  1789. +    bool flush()
  1790. +    {
  1791. +        if(zfile.next_out && zfile.avail_out < BUFSIZE)
  1792. +        {
  1793. +            if(file->write(buf, BUFSIZE - zfile.avail_out) != int(BUFSIZE - zfile.avail_out))
  1794. +                return false;
  1795. +        }
  1796. +        zfile.next_out = buf;
  1797. +        zfile.avail_out = BUFSIZE;
  1798. +        return true;
  1799. +    }
  1800. +
  1801. +    int write(const void *buf, int len)
  1802. +    {
  1803. +        if(!writing || !buf || !len) return 0;
  1804. +        zfile.next_in = (Bytef *)buf;
  1805. +        zfile.avail_in = len;
  1806. +        while(zfile.avail_in > 0)
  1807. +        {
  1808. +            if(!zfile.avail_out && !flush()) { stopwriting(); break; }
  1809. +            int err = deflate(&zfile, Z_NO_FLUSH);
  1810. +            if(err != Z_OK) { stopwriting(); break; }
  1811. +        }
  1812. +        crc = crc32(crc, (Bytef *)buf, len - zfile.avail_in);
  1813. +        return len - zfile.avail_in;
  1814. +    }
  1815. +};
  1816. +
  1817. +
  1818. +stream *openrawfile(const char *filename, const char *mode)
  1819. +{
  1820. +    const char *found = findfile(filename, mode);
  1821. +#ifndef STANDALONE
  1822. +    if(mode && (mode[0]=='w' || mode[0]=='a')) conoutf("writing to file: %s", found);
  1823. +#endif
  1824. +    if(!found) return NULL;
  1825. +    filestream *file = new filestream;
  1826. +    if(!file->open(found, mode))
  1827. +    {
  1828. +#ifndef STANDALONE
  1829. +//         conoutf("file failure! %s",filename);
  1830. +#endif
  1831. +        delete file; return NULL;
  1832. +    }
  1833. +    return file;
  1834. +}
  1835. +
  1836. +stream *openfile(const char *filename, const char *mode)
  1837. +{
  1838. +#ifndef STANDALONE
  1839. +    stream *s = openzipfile(filename, mode);
  1840. +    if(s) return s;
  1841. +#endif
  1842. +    return openrawfile(filename, mode);
  1843. +}
  1844. +
  1845. +int getfilesize(const char *filename)
  1846. +{
  1847. +    stream *f = openfile(filename, "rb");
  1848. +    if(!f) return -1;
  1849. +    int len = f->size();
  1850. +    delete f;
  1851. +    return len;
  1852. +}
  1853. +
  1854. +stream *opentempfile(const char *name, const char *mode)
  1855. +{
  1856. +    const char *found = findfile(name, mode);
  1857. +    filestream *file = new filestream;
  1858. +    if(!file->opentemp(found ? found : name, mode)) { delete file; return NULL; }
  1859. +    return file;
  1860. +}
  1861. +
  1862. +stream *opengzfile(const char *filename, const char *mode, stream *file, int level)
  1863. +{
  1864. +    stream *source = file ? file : openfile(filename, mode);
  1865. +    if(!source) return NULL;
  1866. +    gzstream *gz = new gzstream;
  1867. +    if(!gz->open(source, mode, !file, level)) { if(!file) delete source; return NULL; }
  1868. +    return gz;
  1869. +}
  1870. +
  1871. +char *loadfile(const char *fn, int *size, const char *mode)
  1872. +{
  1873. +    stream *f = openfile(fn, mode ? mode : "rb");
  1874. +    if(!f) return NULL;
  1875. +    int len = f->size();
  1876. +    if(len<=0) { delete f; return NULL; }
  1877. +    char *buf = new char[len+1];
  1878. +    if(!buf) { delete f; return NULL; }
  1879. +    buf[len] = 0;
  1880. +    int rlen = f->read(buf, len);
  1881. +    delete f;
  1882. +    if(len!=rlen && (!mode || strchr(mode, 'b')))
  1883. +    {
  1884. +        delete[] buf;
  1885. +        return NULL;
  1886. +    }
  1887. +    if(size!=NULL) *size = len;
  1888. +    return buf;
  1889. +}
  1890. +
  1891. Index: src/tools.h
  1892. ===================================================================
  1893. --- src/tools.h (revision 6612)
  1894. +++ src/tools.h (working copy)
  1895. @@ -901,6 +901,10 @@
  1896.  extern int listfiles(const char *dir, const char *ext, vector<char *> &files);
  1897.  extern int listzipfiles(const char *dir, const char *ext, vector<char *> &files);
  1898.  extern bool delfile(const char *path);
  1899. +extern bool copyfile(const char *source, const char *destination);
  1900. +extern bool preparedir(const char *destination);
  1901. +extern bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL);
  1902. +extern bool removezip(const char *name);
  1903.  extern struct mapstats *loadmapstats(const char *filename, bool getlayout);
  1904.  extern bool cmpb(void *b, int n, enet_uint32 c);
  1905.  extern bool cmpf(char *fn, enet_uint32 c);
  1906. Index: src/worldio.cpp
  1907. ===================================================================
  1908. --- src/worldio.cpp (revision 6612)
  1909. +++ src/worldio.cpp (working copy)
  1910. @@ -840,6 +840,12 @@
  1911.      delete f;
  1912.  }
  1913.  
  1914. +// get all dependencies for the current map
  1915. +void curmapdeps()
  1916. +{
  1917. +    
  1918. +}
  1919. +
  1920.  COMMAND(listmapdependencies, ARG_1STR);
  1921.  
  1922.  void listmapdependencies_all(int sure)
  1923. Index: src/zip.cpp
  1924. ===================================================================
  1925. --- src/zip.cpp (revision 6612)
  1926. +++ src/zip.cpp (working copy)
  1927. @@ -259,20 +259,20 @@
  1928.      }
  1929.  }
  1930.  
  1931. -bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL)
  1932. +bool addzip(const char *name, const char *mount, const char *strip)
  1933.  {
  1934.      string pname;
  1935.      copystring(pname, name);
  1936.      path(pname);
  1937. -    int plen = (int)strlen(pname);
  1938. -    if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");
  1939. +    /*int plen = (int)strlen(pname);
  1940. +    if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");*/
  1941.  
  1942. -    ziparchive *exists = findzip(pname);
  1943. +    /*ziparchive *exists = findzip(pname);
  1944.      if(exists)
  1945.      {
  1946.          conoutf("already added zip %s", pname);
  1947.          return true;
  1948. -    }
  1949. +    }*/
  1950.  
  1951.      FILE *f = fopen(findfile(pname, "rb"), "rb");
  1952.      if(!f)
  1953. @@ -295,7 +295,7 @@
  1954.      mountzip(*arch, files, mount, strip);
  1955.      archives.add(arch);
  1956.  
  1957. -    conoutf("added zip %s", pname);
  1958. +    //conoutf("added zip %s", pname);
  1959.      return true;
  1960.  }
  1961.      
  1962. @@ -304,8 +304,8 @@
  1963.      string pname;
  1964.      copystring(pname, name);
  1965.      path(pname);
  1966. -    int plen = (int)strlen(pname);
  1967. -    if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");
  1968. +    /*int plen = (int)strlen(pname);
  1969. +    if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");*/
  1970.      ziparchive *exists = findzip(pname);
  1971.      if(!exists)
  1972.      {
  1973. @@ -317,7 +317,7 @@
  1974.          conoutf("zip %s has open files", pname);
  1975.          return false;
  1976.      }
  1977. -    conoutf("removed zip %s", exists->name);
  1978. +    //conoutf("removed zip %s", exists->name);
  1979.      archives.removeobj(exists);
  1980.      delete exists;
  1981.      return true;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement