Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Index: config/pcksources.cfg
- ===================================================================
- --- config/pcksources.cfg (revision 0)
- +++ config/pcksources.cfg (revision 0)
- @@ -0,0 +1,3 @@
- +// list of package source servers (only add servers you trust!)
- +
- +addpckserver http://de582.ispfr.net/cube
- Index: config/scontext.cfg
- ===================================================================
- --- config/scontext.cfg (revision 6612)
- +++ config/scontext.cfg (working copy)
- @@ -6,15 +6,19 @@
- context_cfg = 1 // known scripts
- context_prompt = 2 // command prompt
- context_mapcfg = 3 // map configs, we don't trust them
- +context_mdlcfg = 4 // mdl configs, same
- // set allowed commands for the map config context
- mapcfgidents = [ loadnotexture loadsky mapmodelreset mapmodel texturereset texture fog fogcolour mapsoundreset mapsound watercolour shadowyaw ]
- +mdlcfgidents = [ md2anim md2emit md2tag md3anim md3emit md3link md3load md3skin mdlalphatest mdlcachelimit mdlcullface mdlscale mdlshadowdist mdltrans mdltranslucent mdlvertexlight]
- loop i (listlen $mapcfgidents) [ scriptcontext $context_mapcfg (at $mapcfgidents $i) ]
- +loop i (listlen $mdlcfgidents) [ scriptcontext $context_mdlcfg (at $mdlcfgidents $i) ]
- // isolate the map config context
- // this disables access from this context to identifiers located in other contexts
- // also it removes all aliases created in this context once the running context changes
- isolatecontext $context_mapcfg
- +isolatecontext $context_mdlcfg
- // secure this configuration for the rest of the game
- sealcontexts
- \ No newline at end of file
- Index: source/src/audiomanager.cpp
- ===================================================================
- --- source/src/audiomanager.cpp (revision 6613)
- +++ source/src/audiomanager.cpp (working copy)
- @@ -220,19 +220,19 @@
- return -1;
- }
- -void audiomanager::preloadmapsound(entity &e)
- +void audiomanager::preloadmapsound(entity &e, bool trydl)
- {
- if(e.type!=SOUND || !mapsounds.inrange(e.attr1)) return;
- sbuffer *buf = mapsounds[e.attr1].buf;
- - if(!buf->load()) conoutf("\f3failed to load sample %s", buf->name);
- + if(!buf->load(trydl) && !trydl) conoutf("\f3failed to load sample %s", buf->name);
- }
- -void audiomanager::preloadmapsounds()
- +void audiomanager::preloadmapsounds(bool trydl)
- {
- loopv(ents)
- {
- entity &e = ents[i];
- - if(e.type==SOUND) preloadmapsound(e);
- + if(e.type==SOUND) preloadmapsound(e, trydl);
- }
- }
- Index: source/src/client.cpp
- ===================================================================
- --- source/src/client.cpp (revision 6613)
- +++ source/src/client.cpp (working copy)
- @@ -215,7 +215,7 @@
- }
- #endif
- if(!onlyclean) localconnect();
- -
- +
- if(identexists("onDisconnect")) execute("onDisconnect");
- }
- @@ -739,12 +739,22 @@
- conoutf(_("sending map %s to server..."), mapname);
- }
- -void getmap()
- +void getmap(char *name)
- {
- - conoutf(_("requesting map from server..."));
- - packetbuf p(10, ENET_PACKET_FLAG_RELIABLE);
- - putint(p, SV_RECVMAP);
- - sendpackettoserv(2, p.finalize());
- + if(!name || name[0] == '\0')
- + {
- + conoutf(_("requesting map from server..."));
- + packetbuf p(10, ENET_PACKET_FLAG_RELIABLE);
- + putint(p, SV_RECVMAP);
- + sendpackettoserv(2, p.finalize());
- + }
- + else
- + {
- + defformatstring(package)("packages/maps/%s.cgz", name);
- + requirepackage(PCK_MAP, package);
- + if(downloadpackages()) conoutf("map %s installed successfully", name);
- + else conoutf("\f3map download failed.");
- + }
- }
- void deleteservermap(char *mapname)
- @@ -805,7 +815,7 @@
- }
- COMMAND(sendmap, ARG_1STR);
- -COMMAND(getmap, ARG_NONE);
- +COMMAND(getmap, ARG_1STR);
- COMMAND(deleteservermap, ARG_1STR);
- COMMAND(resetsecuremaps, ARG_NONE);
- COMMAND(securemap, ARG_1STR);
- @@ -813,3 +823,172 @@
- COMMAND(listdemos, ARG_NONE);
- COMMANDN(setmr, setminutesremaining, ARG_1INT);
- COMMANDN(rewind, rewinddemo, ARG_1INT);
- +
- +// packages auto - downloader
- +
- +// arrays
- +vector<pckserver *> pckservers;
- +hashtable<const char *, package *> pendingpackages;
- +
- +// cubescript
- +
- +void resetpckservers()
- +{
- + pckservers.deletecontents();
- +}
- +
- +void addpckserver(char *addr)
- +{
- + pckserver *srcserver = new pckserver();
- + srcserver->addr = newstring(addr);
- + srcserver->pending = true;
- + pckservers.add(srcserver);
- +}
- +
- +COMMAND(resetpckservers, ARG_NONE);
- +COMMAND(addpckserver, ARG_1STR);
- +
- +// cURL / Network
- +
- +bool havecurl = false, canceldownloads = false;
- +
- +void setupcurl()
- +{
- + if(curl_global_init(CURL_GLOBAL_NOTHING)) conoutf("\f3could not init cURL, content downloads not available");
- + else
- + {
- + havecurl = true;
- + execfile("config/pcksources.cfg");
- + }
- +}
- +
- +static size_t write_callback(void *ptr, size_t size, size_t nmemb, FILE *stream)
- +{
- + return fwrite(ptr, size, nmemb, stream);
- +}
- +
- +int progress_callback(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
- +{
- + package *pck = (package *)clientp;
- + loadingscreen("downloading...\n%s %.0f/%.0f KB (%.1f%%)\n(ESC to cancel)", pck->name, dlnow/double(1000.0), dltotal/double(1000.0), dltotal == 0 ? 0 : (dlnow/dltotal * double(100.0)));
- + if(interceptkey(SDLK_ESCAPE))
- + {
- + canceldownloads = true;
- + loadingscreen();
- + return 1;
- + }
- + return 0;
- +}
- +
- +int processdonwload(package *pck)
- +{
- + FILE *fp = NULL;
- +
- + if(!pck->pending)
- + {
- + switch(pck->type)
- + {
- + case PCK_TEXTURE: case PCK_AUDIO:
- + {
- + preparedir(pck->name);
- + // with textures/sounds, the image/audio file itself is sent. Just need to copy it from the temporary file
- + if(!copyfile(path("config/tmp", true), pck->name)) conoutf("\f3failed to install %s", pck->name);
- + break;
- + }
- +
- + case PCK_MAP: case PCK_MAPMODEL:
- + {
- + const char *p = path("config/tmp", true);
- + addzip(p, pck->name, NULL, true, pck->type);
- + break;
- + }
- +
- + case PCK_SKYBOX:
- + {
- + const char *p = path("config/tmp", true);
- + char *fname = newstring(pck->name), *ls = strrchr(fname, '/');
- + if(ls) *ls = '\0';
- + addzip(p, fname, NULL, true, pck->type);
- + break;
- + }
- +
- + default:
- + conoutf("could not install package %s", pck->name);
- + break;
- + }
- + }
- + return 0;
- +}
- +
- +// download a package
- +double dlpackage(package *pck)
- +{
- + if(!pck || !pck->source) return false;
- + FILE *outfile = fopen(path("config/tmp", true), "wb");
- + string req;
- + sprintf(req, "%s/%s%s", pck->source->addr, pck->name, (pck->type==PCK_MAP || pck->type==PCK_MAPMODEL || pck->type==PCK_SKYBOX) ? ".zip" : "");
- + conoutf("downloading %s from %s ...", pck->name, pck->source->addr);
- +
- + int result, httpresult = 0;
- + double dlsize;
- + pck->curl = curl_easy_init();
- + curl_easy_setopt(pck->curl, CURLOPT_URL, req);
- + curl_easy_setopt(pck->curl, CURLOPT_WRITEFUNCTION, write_callback);
- + curl_easy_setopt(pck->curl, CURLOPT_WRITEDATA, outfile);
- + curl_easy_setopt(pck->curl, CURLOPT_NOPROGRESS, 0);
- + curl_easy_setopt(pck->curl, CURLOPT_PROGRESSFUNCTION, progress_callback);
- + curl_easy_setopt(pck->curl, CURLOPT_PROGRESSDATA, pck);
- + curl_easy_setopt(pck->curl, CURLOPT_CONNECTTIMEOUT, 10); // generous timeout for Bukz ;)
- + result = curl_easy_perform(pck->curl);
- + curl_easy_getinfo(pck->curl, CURLINFO_RESPONSE_CODE, &httpresult);
- + curl_easy_getinfo(pck->curl, CURLINFO_SIZE_DOWNLOAD, &dlsize);
- + curl_easy_cleanup(pck->curl);
- + pck->curl = NULL;
- + fclose(outfile);
- +
- + pck->pending = false;
- + if(result == CURLE_OPERATION_TIMEDOUT) pck->source->responsive = false; // mark source unresponsive (might want to add more here)
- + if(!result && httpresult == 200) processdonwload(pck);
- + else if(result == CURLE_ABORTED_BY_CALLBACK) conoutf("\f3download cancelled");
- + else conoutf("\f2request for %s failed (cURL %d, HTTP %d)", req, result, httpresult);
- + return (!result && httpresult == 200) ? dlsize : 0;
- +}
- +
- +int downloadpackages()
- +{
- + double total = 0;
- + enumerate(pendingpackages, package *, pck,
- + {
- + total += dlpackage(pck);
- + pendingpackages.remove(pck->name);
- + delete pck;
- + });
- + return (int)total;
- +}
- +
- +bool requirepackage(int type, const char *path)
- +{
- + if(!havecurl || canceldownloads || type < 0 || type >= PCK_NUM || pendingpackages.access(path)) return false;
- +
- + package *pck = new package;
- + pck->name = unixpath(newstring(path));
- + pck->type = type;
- + loopv(pckservers) if(pckservers[i]->responsive) pck->source = pckservers[i];
- + if(!pck->source) { conoutf("\f3no responsive source server found, can't download"); return false; }
- + pck->pending = true;
- +
- + pendingpackages.access(pck->name, pck);
- +
- + return true;
- +}
- +
- +
- +void writepcksourcecfg()
- +{
- + stream *f = openfile(path("config/pcksources.cfg", true), "w");
- + if(!f) return;
- + f->printf("// list of package source servers (only add servers you trust!)\n");
- + loopv(pckservers) f->printf("\naddpckserver %s", pckservers[i]->addr);
- + f->printf("\n");
- + delete f;
- +}
- Index: source/src/clientgame.cpp
- ===================================================================
- --- source/src/clientgame.cpp (revision 6613)
- +++ source/src/clientgame.cpp (working copy)
- @@ -1205,8 +1205,11 @@
- }
- COMMAND(showmapstats, ARG_NONE);
- +extern bool canceldownloads;
- +
- void startmap(const char *name, bool reset) // called just after a map load
- {
- + canceldownloads = false;
- copystring(clientmap, name);
- sendmapidenttoserver = true;
- // Added by Rick
- Index: source/src/command.h
- ===================================================================
- --- source/src/command.h (revision 6613)
- +++ source/src/command.h (working copy)
- @@ -87,7 +87,7 @@
- ARG_VARI
- };
- -enum { IEXC_CORE = 0, IEXC_CFG, IEXC_PROMPT, IEXC_MAPCFG, IEXC_NUM }; // script execution context
- +enum { IEXC_CORE = 0, IEXC_CFG, IEXC_PROMPT, IEXC_MAPCFG, IEXC_MDLCFG, IEXC_NUM }; // script execution context
- // nasty macros for registering script functions, abuses globals to avoid excessive infrastructure
- #define COMMANDN(name, fun, nargs) static bool __dummy_##fun = addcommand(#name, (void (*)())fun, nargs)
- Index: source/src/entity.h
- ===================================================================
- --- source/src/entity.h (revision 6613)
- +++ source/src/entity.h (working copy)
- @@ -622,3 +622,24 @@
- return killmessages[gib?1:0][gun];
- }
- +
- +struct pckserver
- +{
- + char *addr;
- + bool pending, responsive;
- +
- + pckserver() : addr(NULL), pending(false), responsive(true) {}
- +};
- +
- +enum { PCK_TEXTURE, PCK_SKYBOX, PCK_MAPMODEL, PCK_AUDIO, PCK_MAP, PCK_NUM };
- +
- +struct package
- +{
- + char *name;
- + int type;
- + bool pending;
- + pckserver *source;
- + CURL *curl;
- +
- + package() : name(NULL), type(-1), pending(false), source(NULL), curl(NULL) {}
- +};
- Index: source/src/main.cpp
- ===================================================================
- --- source/src/main.cpp (revision 6613)
- +++ source/src/main.cpp (working copy)
- @@ -35,6 +35,7 @@
- writeinitcfg();
- writeservercfg();
- writekillmsgcfg();
- + writepcksourcecfg();
- if(resetcfg) deletecfg();
- else writecfg();
- cleanup(NULL);
- @@ -1110,6 +1111,9 @@
- notexture = noworldtexture = textureload("packages/misc/notexture.jpg");
- if(!notexture) fatal("could not find core textures (hint: run AssaultCube from the parent of the bin directory)");
- + nomodel = loadmodel("misc/gib01", -1); //FIXME: need actual placeholder model
- + if(!notexture) fatal("could not find core models");
- +
- initlog("console");
- persistidents = false;
- // Main font file, all other font files execute from here.
- @@ -1188,6 +1192,9 @@
- initing = NOT_INITING;
- uniformtexres = !hirestextures;
- + initlog("curl");
- + setupcurl();
- +
- initlog("models");
- preload_playermodels();
- preload_hudguns();
- Index: source/src/openal.cpp
- ===================================================================
- --- source/src/openal.cpp (revision 6613)
- +++ source/src/openal.cpp (working copy)
- @@ -254,7 +254,7 @@
- unload();
- }
- -bool sbuffer::load()
- +bool sbuffer::load(bool trydl)
- {
- if(!name) return false;
- if(id) return true;
- @@ -264,79 +264,94 @@
- {
- const char *exts[] = { "", ".wav", ".ogg" };
- string filepath;
- - loopi(sizeof(exts)/sizeof(exts[0]))
- + loopk(2)
- {
- - formatstring(filepath)("packages/audio/%s%s", name, exts[i]);
- - stream *f = openfile(path(filepath), "rb");
- - if(!f) continue;
- -
- - size_t len = strlen(filepath);
- - if(len >= 4 && !strcasecmp(filepath + len - 4, ".ogg"))
- + loopi(sizeof(exts)/sizeof(exts[0]))
- {
- - OggVorbis_File oggfile;
- - if(!ov_open_callbacks(f, &oggfile, NULL, 0, oggcallbacks))
- + formatstring(filepath)("packages/audio/%s%s", name, exts[i]);
- + stream *f = openfile(path(filepath), "rb");
- + if(!f && k>0 && trydl) // only try donwloading after trying all extensions
- {
- - vorbis_info *info = ov_info(&oggfile, -1);
- + requirepackage(PCK_AUDIO, filepath);
- + bool skip = false;
- + loopj(sizeof(exts)/sizeof(exts[0])) if(strstr(name, exts[j])) skip = true; // don't try extensions if name already has a known extension
- + if(skip) break;
- + continue;
- + }
- + if(!f) continue;
- - const size_t BUFSIZE = 32*1024;
- - vector<char> buf;
- - int bitstream;
- - long bytes;
- + size_t len = strlen(filepath);
- + if(len >= 4 && !strcasecmp(filepath + len - 4, ".ogg"))
- + {
- + OggVorbis_File oggfile;
- + if(!ov_open_callbacks(f, &oggfile, NULL, 0, oggcallbacks))
- + {
- + vorbis_info *info = ov_info(&oggfile, -1);
- - do
- + const size_t BUFSIZE = 32*1024;
- + vector<char> buf;
- + int bitstream;
- + long bytes;
- +
- + do
- + {
- + char buffer[BUFSIZE];
- + bytes = ov_read(&oggfile, buffer, BUFSIZE, isbigendian(), 2, 1, &bitstream);
- + loopi(bytes) buf.add(buffer[i]);
- + } while(bytes > 0);
- +
- + alBufferData(id, info->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, buf.getbuf(), buf.length(), info->rate);
- + ov_clear(&oggfile);
- + }
- + else
- {
- - char buffer[BUFSIZE];
- - bytes = ov_read(&oggfile, buffer, BUFSIZE, isbigendian(), 2, 1, &bitstream);
- - loopi(bytes) buf.add(buffer[i]);
- - } while(bytes > 0);
- -
- - alBufferData(id, info->channels == 2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16, buf.getbuf(), buf.length(), info->rate);
- - ov_clear(&oggfile);
- + delete f;
- + continue;
- + }
- }
- else
- {
- + SDL_AudioSpec wavspec;
- + uint32_t wavlen;
- + uint8_t *wavbuf;
- +
- + if(!SDL_LoadWAV_RW(f->rwops(), 1, &wavspec, &wavbuf, &wavlen))
- + {
- + SDL_ClearError();
- + continue;
- + }
- +
- + ALenum format;
- + switch(wavspec.format) // map wav header to openal format
- + {
- + case AUDIO_U8:
- + case AUDIO_S8:
- + format = wavspec.channels==2 ? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8;
- + break;
- + case AUDIO_U16:
- + case AUDIO_S16:
- + format = wavspec.channels==2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
- + break;
- + default:
- + SDL_FreeWAV(wavbuf);
- + delete f;
- + unload();
- + return false;
- + }
- +
- + alBufferData(id, format, wavbuf, wavlen, wavspec.freq);
- + SDL_FreeWAV(wavbuf);
- delete f;
- - continue;
- - }
- - }
- - else
- - {
- - SDL_AudioSpec wavspec;
- - uint32_t wavlen;
- - uint8_t *wavbuf;
- - if(!SDL_LoadWAV_RW(f->rwops(), 1, &wavspec, &wavbuf, &wavlen))
- - {
- - SDL_ClearError();
- - continue;
- - }
- -
- - ALenum format;
- - switch(wavspec.format) // map wav header to openal format
- - {
- - case AUDIO_U8:
- - case AUDIO_S8:
- - format = wavspec.channels==2 ? AL_FORMAT_STEREO8 : AL_FORMAT_MONO8;
- - break;
- - case AUDIO_U16:
- - case AUDIO_S16:
- - format = wavspec.channels==2 ? AL_FORMAT_STEREO16 : AL_FORMAT_MONO16;
- - break;
- - default:
- - SDL_FreeWAV(wavbuf);
- - delete f;
- + if(ALERR)
- + {
- unload();
- return false;
- + };
- }
- - alBufferData(id, format, wavbuf, wavlen, wavspec.freq);
- - SDL_FreeWAV(wavbuf);
- - delete f;
- -
- - if(ALERR) break;
- + return true;
- }
- -
- - return true;
- }
- }
- unload(); // loading failed
- Index: source/src/platform.h
- ===================================================================
- --- source/src/platform.h (revision 6613)
- +++ source/src/platform.h (working copy)
- @@ -71,3 +71,8 @@
- #include <setjmp.h>
- #endif
- +
- +#ifndef CURL_STATICLIB
- +#define CURL_STATICLIB
- +#endif
- +#include "curl/curl.h"
- Index: source/src/protos.h
- ===================================================================
- --- source/src/protos.h (revision 6613)
- +++ source/src/protos.h (working copy)
- @@ -291,20 +291,26 @@
- extern SDL_Surface *creatergbasurface(int width, int height);
- extern SDL_Surface *forcergbsurface(SDL_Surface *os);
- extern SDL_Surface *forcergbasurface(SDL_Surface *os);
- -extern Texture *textureload(const char *name, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f);
- -extern Texture *lookuptexture(int tex, Texture *failtex = notexture);
- +extern Texture *textureload(const char *name, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f, bool trydl = false);
- +extern Texture *lookuptexture(int tex, Texture *failtex = notexture, bool trydl = false);
- extern bool reloadtexture(Texture &t);
- extern bool reloadtexture(const char *name);
- extern void reloadtextures();
- Texture *createtexturefromsurface(const char *name, SDL_Surface *s);
- extern void blitsurface(SDL_Surface *dst, SDL_Surface *src, int x, int y);
- +void loadsky(char *basename, bool reload);
- -static inline Texture *lookupworldtexture(int tex)
- -{ return lookuptexture(tex, noworldtexture); }
- +static inline Texture *lookupworldtexture(int tex, bool trydl = true)
- +{ return lookuptexture(tex, noworldtexture, trydl); }
- extern float skyfloor;
- extern void draw_envbox(int fogdist);
- +extern void setupcurl();
- +extern bool requirepackage(int type, const char *path);
- +extern int downloadpackages();
- +extern void writepcksourcecfg();
- +
- extern int maxtmus;
- extern void inittmus();
- extern void resettmu(int n);
- @@ -346,7 +352,7 @@
- extern void neterr(const char *s);
- extern int getclientnum();
- extern void changeteam(int team, bool respawn = true); // deprecated?
- -extern void getmap();
- +extern void getmap(char *name = NULL);
- extern void newteam(char *name);
- extern bool securemapcheck(const char *map, bool msg = true);
- extern void sendintro();
- @@ -655,11 +661,12 @@
- extern mapmodelinfo &getmminfo(int i);
- extern int findanim(const char *name);
- extern void loadskin(const char *dir, const char *altdir, Texture *&skin);
- -extern model *loadmodel(const char *name, int i = -1);
- +extern model *nomodel;
- +extern model *loadmodel(const char *name, int i = -1, bool trydl = false);
- extern void preload_playermodels();
- extern void preload_entmodels();
- extern void preload_hudguns();
- -extern void preload_mapmodels();
- +extern void preload_mapmodels(bool trydl = false);
- extern void renderclients();
- extern void renderclient(playerent *d);
- extern void renderclient(playerent *d, const char *mdlname, const char *vwepname, int tex = 0);
- Index: source/src/rendermodel.cpp
- ===================================================================
- --- source/src/rendermodel.cpp (revision 6613)
- +++ source/src/rendermodel.cpp (working copy)
- @@ -87,6 +87,7 @@
- mmi.rad = atoi(rad);
- mmi.h = atoi(h);
- mmi.zoff = atoi(zoff);
- + mmi.m = NULL;
- formatstring(mmi.name)("mapmodels/%s", name);
- }
- @@ -102,7 +103,9 @@
- hashtable<const char *, model *> mdllookup;
- -model *loadmodel(const char *name, int i)
- +model *nomodel = NULL;
- +
- +model *loadmodel(const char *name, int i, bool trydl)
- {
- if(!name)
- {
- @@ -116,6 +119,7 @@
- if(mm) m = *mm;
- else
- {
- + pushscontext(IEXC_MDLCFG);
- m = new md2(name);
- loadingmodel = m;
- if(!m->load())
- @@ -127,9 +131,20 @@
- {
- delete m;
- loadingmodel = NULL;
- - return NULL;
- + if(trydl)
- + {
- + defformatstring(dl)("packages/models/%s", name);
- + requirepackage(PCK_MAPMODEL, dl);
- + }
- + else
- + {
- + mdllookup.access(newstring(name), nomodel);
- + conoutf("\f3failed to load model %s", name);
- + }
- }
- }
- + popscontext();
- + if(!loadingmodel) return NULL;
- loadingmodel = NULL;
- mdllookup.access(m->name(), m);
- }
- @@ -511,14 +526,14 @@
- }
- }
- -void preload_mapmodels()
- +void preload_mapmodels(bool trydl)
- {
- loopv(ents)
- {
- entity &e = ents[i];
- if(e.type!=MAPMODEL || !mapmodels.inrange(e.attr2)) continue;
- - if(!loadmodel(NULL, e.attr2)) continue;
- - if(e.attr4) lookuptexture(e.attr4);
- + loadmodel(NULL, e.attr2, trydl);
- + if(e.attr4) lookuptexture(e.attr4, notexture, trydl);
- }
- }
- Index: source/src/sound.h
- ===================================================================
- --- source/src/sound.h (revision 6613)
- +++ source/src/sound.h (working copy)
- @@ -160,7 +160,7 @@
- sbuffer();
- ~sbuffer();
- - bool load();
- + bool load(bool trydl = false);
- void unload();
- };
- @@ -388,8 +388,8 @@
- // init & setup
- void initsound();
- - void preloadmapsound(entity &e);
- - void preloadmapsounds();
- + void preloadmapsound(entity &e, bool trydl = false);
- + void preloadmapsounds(bool trydl = false);
- void applymapsoundchanges();
- // configuration
- Index: source/src/stream.cpp
- ===================================================================
- --- source/src/stream.cpp (revision 6613)
- +++ source/src/stream.cpp (working copy)
- @@ -74,6 +74,12 @@
- return s;
- }
- +char *unixpath(char *s)
- +{
- + for(char *t = s; (t = strchr(t, '\\')); *t++ = '/');
- + return s;
- +}
- +
- char *path(const char *s, bool copy)
- {
- static string tmp;
- @@ -304,6 +310,38 @@
- return !remove(path);
- }
- +bool copyfile(const char *source, const char *destination)
- +{
- + FILE *from = fopen(source, "rb");
- + FILE *dest = fopen(destination, "wb");
- +
- + if(!from || !dest) return false;
- + size_t len;
- + uchar buf[1024];
- + while((len = fread(&buf, sizeof(uchar), 1024, from)))
- + {
- + fwrite(&buf, sizeof(uchar), len, dest);
- + }
- + fclose(from);
- + fclose(dest);
- + return true;
- +}
- +
- +bool preparedir(const char *destination)
- +{
- + string dir;
- + copystring(dir, parentdir(destination));
- + vector<char *> dirs;
- + while(!fileexists(dir, "r"))
- + {
- + dirs.add(newstring(dir));
- + copystring(dir, parentdir(dir));
- + }
- +
- + loopvrev(dirs) if(!createdir(dirs[i])) return false;
- + return true;
- +}
- +
- #ifndef STANDALONE
- static int rwopsseek(SDL_RWops *rw, int offset, int whence)
- {
- Index: source/src/texture.cpp
- ===================================================================
- --- source/src/texture.cpp (revision 6613)
- +++ source/src/texture.cpp (working copy)
- @@ -354,7 +354,7 @@
- VARFP(hirestextures, 0, 1, 1, initwarning("texture resolution", INIT_LOAD));
- bool uniformtexres = !hirestextures;
- -GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f)
- +GLuint loadsurface(const char *texname, int &xs, int &ys, int &bpp, int clamp = 0, bool mipmap = true, bool canreduce = false, float scale = 1.0f, bool trydl = false)
- {
- const char *file = texname;
- if(texname[0]=='<')
- @@ -377,6 +377,11 @@
- delete z;
- }
- if(!s) s = IMG_Load(findfile(file, "rb"));
- + if(!s && trydl)
- + {
- + requirepackage(PCK_TEXTURE, file);
- + return 0;
- + }
- if(!s) { if(!silent_texture_load) conoutf("couldn't load texture %s", texname); return 0; }
- s = fixsurfaceformat(s);
- Uint8 x = 0;
- @@ -420,7 +425,7 @@
- // each texture slot can have multiple texture frames, of which currently only the first is used
- // additional frames can be used for various shaders
- -Texture *textureload(const char *name, int clamp, bool mipmap, bool canreduce, float scale)
- +Texture *textureload(const char *name, int clamp, bool mipmap, bool canreduce, float scale, bool trydl)
- {
- string pname;
- copystring(pname, name);
- @@ -428,7 +433,7 @@
- Texture *t = textures.access(pname);
- if(t) return t;
- int xs, ys, bpp;
- - GLuint id = loadsurface(pname, xs, ys, bpp, clamp, mipmap, canreduce, scale);
- + GLuint id = loadsurface(pname, xs, ys, bpp, clamp, mipmap, canreduce, scale, trydl);
- if(!id) return notexture;
- char *key = newstring(pname);
- t = &textures[key];
- @@ -498,7 +503,7 @@
- COMMAND(texturereset, ARG_NONE);
- COMMAND(texture, ARG_2STR);
- -Texture *lookuptexture(int tex, Texture *failtex)
- +Texture *lookuptexture(int tex, Texture *failtex, bool trydl)
- {
- Texture *t = failtex;
- if(slots.inrange(tex))
- @@ -507,7 +512,7 @@
- if(!s.loaded)
- {
- defformatstring(pname)("packages/textures/%s", s.name);
- - s.tex = textureload(pname, 0, true, true, s.scale);
- + s.tex = textureload(pname, 0, true, true, s.scale, trydl);
- if(s.tex==notexture) s.tex = failtex;
- s.loaded = true;
- }
- @@ -547,19 +552,27 @@
- }
- Texture *sky[6] = {NULL, NULL, NULL, NULL, NULL, NULL};
- +static string skybox;
- -void loadsky(char *basename)
- +void loadsky(char *basename, bool reload)
- {
- const char *side[] = { "lf", "rt", "ft", "bk", "dn", "up" };
- + if(reload) basename = skybox;
- + else copystring(skybox, basename);
- loopi(6)
- {
- defformatstring(name)("packages/%s_%s.jpg", basename, side[i]);
- sky[i] = textureload(name, 3);
- - if(!sky[i]) conoutf("could not load sky texture: %s", name);
- + if(sky[i] == notexture && !reload)
- + {
- + defformatstring(dl)("packages/%s", basename);
- + requirepackage(PCK_SKYBOX, dl);
- + break;
- + }
- }
- }
- -COMMAND(loadsky, ARG_1STR);
- +ICOMMANDF(loadsky, ARG_1STR, (char *name) { loadsky(name, false); return 0; });
- void loadnotexture(char *c)
- {
- Index: source/src/tools.h
- ===================================================================
- --- source/src/tools.h (revision 6613)
- +++ source/src/tools.h (working copy)
- @@ -882,6 +882,7 @@
- extern const char *numtime();
- extern char *path(char *s);
- extern char *path(const char *s, bool copy);
- +extern char *unixpath(char *s);
- extern const char *behindpath(const char *s);
- extern const char *parentdir(const char *directory);
- extern bool fileexists(const char *path, const char *mode);
- @@ -901,6 +902,10 @@
- extern int listfiles(const char *dir, const char *ext, vector<char *> &files);
- extern int listzipfiles(const char *dir, const char *ext, vector<char *> &files);
- extern bool delfile(const char *path);
- +extern bool copyfile(const char *source, const char *destination);
- +extern bool preparedir(const char *destination);
- +extern bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL, bool extract = false, int type = -1);
- +extern bool removezip(const char *name);
- extern struct mapstats *loadmapstats(const char *filename, bool getlayout);
- extern bool cmpb(void *b, int n, enet_uint32 c);
- extern bool cmpf(char *fn, enet_uint32 c);
- Index: source/src/worldio.cpp
- ===================================================================
- --- source/src/worldio.cpp (revision 6613)
- +++ source/src/worldio.cpp (working copy)
- @@ -685,17 +685,44 @@
- popscontext();
- c2skeepalive();
- +
- watch.start();
- + loopi(256) if(texuse[i]) lookupworldtexture(i, true);
- + int texloadtime = watch.stop();
- +
- + c2skeepalive();
- +
- + watch.start();
- + preload_mapmodels(true);
- + int mdlloadtime = watch.stop();
- +
- + c2skeepalive();
- +
- + watch.start();
- + audiomgr.preloadmapsounds(true);
- + int audioloadtime = watch.stop();
- +
- + c2skeepalive();
- +
- + watch.start();
- + int downloaded = downloadpackages();
- + if(downloaded > 0) printf("downloaded content (%d KB in %d seconds)\n", downloaded/1000, watch.stop()/1000);
- +
- + c2skeepalive();
- +
- +
- + loadsky(NULL, true);
- + watch.start();
- loopi(256) if(texuse[i]) lookupworldtexture(i);
- - printf("loaded textures (%d milliseconds)\n", watch.stop());
- + printf("loaded textures (%d milliseconds)\n", texloadtime+watch.stop());
- c2skeepalive();
- watch.start();
- preload_mapmodels();
- - printf("loaded mapmodels (%d milliseconds)\n", watch.stop());
- + printf("loaded mapmodels (%d milliseconds)\n", mdlloadtime+watch.stop());
- c2skeepalive();
- watch.start();
- audiomgr.preloadmapsounds();
- - printf("loaded mapsounds (%d milliseconds)\n", watch.stop());
- + printf("loaded mapsounds (%d milliseconds)\n", audioloadtime+watch.stop());
- c2skeepalive();
- defformatstring(startmillis)("%d", millis_());
- @@ -840,6 +867,12 @@
- delete f;
- }
- +// get all dependencies for the current map
- +void curmapdeps()
- +{
- +
- +}
- +
- COMMAND(listmapdependencies, ARG_1STR);
- void listmapdependencies_all(int sure)
- Index: source/src/zip.cpp
- ===================================================================
- --- source/src/zip.cpp (revision 6613)
- +++ source/src/zip.cpp (working copy)
- @@ -22,7 +22,7 @@
- {
- uint signature;
- ushort version, needversion, flags, compression, modtime, moddate;
- - uint crc32, compressedsize, uncompressedsize;
- + uint crc32, compressedsize, uncompressedsize;
- ushort namelength, extralength, commentlength, disknumber, internalattribs;
- uint externalattribs, offset;
- };
- @@ -43,9 +43,9 @@
- zipfile() : name(NULL), header(0), offset(~0U), size(0), compressedsize(0)
- {
- }
- - ~zipfile()
- - {
- - DELETEA(name);
- + ~zipfile()
- + {
- + DELETEA(name);
- }
- };
- @@ -57,9 +57,10 @@
- FILE *data;
- hashtable<const char *, zipfile> files;
- int openfiles;
- + int type;
- zipstream *owner;
- - ziparchive() : name(NULL), data(NULL), files(512), openfiles(0), owner(NULL)
- + ziparchive() : name(NULL), data(NULL), files(512), openfiles(0), owner(NULL), type(-1)
- {
- }
- ~ziparchive()
- @@ -85,9 +86,9 @@
- if(next + carry < ZIP_DIRECTORY_SIZE || fseek(f, offset, SEEK_SET) < 0 || (int)fread(buf, 1, next, f) != next) return false;
- len = next + carry;
- uchar *search = &buf[next-1];
- - for(; search >= buf; search--) if(*(uint *)search == signature) break;
- + for(; search >= buf; search--) if(*(uint *)search == signature) break;
- if(search >= buf) { src = search; break; }
- - }
- + }
- if(&buf[len] - src < ZIP_DIRECTORY_SIZE) return false;
- @@ -149,7 +150,7 @@
- pname[namelen] = '\0';
- path(pname);
- char *name = newstring(pname);
- -
- +
- zipfile &f = files.add();
- f.name = name;
- f.header = hdr.offset;
- @@ -206,18 +207,36 @@
- return true;
- }
- -static void mountzip(ziparchive &arch, vector<zipfile> &files, const char *mountdir, const char *stripdir)
- +bool extractzipfile(ziparchive *a, zipfile *f, const char *name);
- +
- +bool fitspackage(char *filename, int type)
- {
- + char *extension = strrchr(filename, '.');
- + ++extension;
- + switch(type)
- + {
- + case PCK_MAPMODEL: return !strcmp(extension, "md2") || !strcmp(extension, "md3")
- + || !strcmp(extension, "cfg") || !strcmp(extension, "txt")
- + || !strcmp(extension, "jpg");
- + case PCK_MAP: return !strcmp(extension, "cgz") || !strcmp(extension, "cfg");
- + case PCK_SKYBOX: return !strcmp(extension, "jpg");
- + default: return true;
- + }
- +}
- +
- +static void mountzip(ziparchive &arch, vector<zipfile> &files, const char *mountdir, const char *stripdir, bool extract)
- +{
- string packagesdir = "packages/";
- path(packagesdir);
- int striplen = stripdir ? (int)strlen(stripdir) : 0;
- + if(arch.type == PCK_MAP) mountdir = "packages/maps/";
- if(!mountdir && !stripdir) loopv(files)
- {
- zipfile &f = files[i];
- const char *foundpackages = strstr(f.name, packagesdir);
- if(foundpackages)
- {
- - if(foundpackages > f.name)
- + if(foundpackages > f.name)
- {
- stripdir = f.name;
- striplen = foundpackages - f.name;
- @@ -239,7 +258,8 @@
- if(!mountdir) mountdir = "packages/maps/";
- break;
- }
- - }
- + mountdir = "packages/maps/";
- + }
- }
- string mdir = "", fname;
- if(mountdir)
- @@ -256,26 +276,32 @@
- zipfile &mf = arch.files[mname];
- mf = f;
- mf.name = mname;
- +
- + if(extract)
- + {
- + if(fitspackage(fname, arch.type)) extractzipfile(&arch, &f, fname);
- + else conoutf("\f3could not extract \"%s\" : file extension not supported", fname);
- + }
- }
- }
- -bool addzip(const char *name, const char *mount = NULL, const char *strip = NULL)
- +bool addzip(const char *name, const char *mount, const char *strip, bool extract, int type)
- {
- string pname;
- copystring(pname, name);
- path(pname);
- - int plen = (int)strlen(pname);
- - if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");
- + /*int plen = (int)strlen(pname);
- + if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");*/
- - ziparchive *exists = findzip(pname);
- - if(exists)
- + /*ziparchive *exists = findzip(pname);
- + if(exists)
- {
- conoutf("already added zip %s", pname);
- return true;
- - }
- -
- + }*/
- +
- FILE *f = fopen(findfile(pname, "rb"), "rb");
- - if(!f)
- + if(!f)
- {
- conoutf("could not open file %s", pname);
- return false;
- @@ -288,24 +314,24 @@
- fclose(f);
- return false;
- }
- -
- +
- ziparchive *arch = new ziparchive;
- arch->name = newstring(pname);
- arch->data = f;
- - mountzip(*arch, files, mount, strip);
- - archives.add(arch);
- + arch->type = type;
- + mountzip(*arch, files, mount, strip, extract);
- + if(!extract) archives.add(arch);
- + else delete arch;
- + return true;
- +}
- - conoutf("added zip %s", pname);
- - return true;
- -}
- -
- bool removezip(const char *name)
- {
- string pname;
- copystring(pname, name);
- path(pname);
- - int plen = (int)strlen(pname);
- - if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");
- + /*int plen = (int)strlen(pname);
- + if(plen < 4 || !strchr(&pname[plen-4], '.')) concatstring(pname, ".zip");*/
- ziparchive *exists = findzip(pname);
- if(!exists)
- {
- @@ -317,8 +343,8 @@
- conoutf("zip %s has open files", pname);
- return false;
- }
- - conoutf("removed zip %s", exists->name);
- - archives.removeobj(exists);
- + //conoutf("removed zip %s", exists->name);
- + archives.removeobj(exists);
- delete exists;
- return true;
- }
- @@ -416,11 +442,11 @@
- {
- switch(whence)
- {
- - case SEEK_END: pos += info->offset + info->size; break;
- + case SEEK_END: pos += info->offset + info->size; break;
- case SEEK_CUR: pos += reading; break;
- case SEEK_SET: pos += info->offset; break;
- default: return false;
- - }
- + }
- pos = clamp(pos, long(info->offset), long(info->offset + info->size));
- arch->owner = NULL;
- if(fseek(arch->data, pos, SEEK_SET) < 0) return false;
- @@ -429,10 +455,10 @@
- ended = false;
- return true;
- }
- -
- +
- switch(whence)
- {
- - case SEEK_END: pos += info->size; break;
- + case SEEK_END: pos += info->size; break;
- case SEEK_CUR: pos += zfile.total_out; break;
- case SEEK_SET: break;
- default: return false;
- @@ -443,7 +469,7 @@
- reading = info->offset + info->compressedsize;
- zfile.next_in += zfile.avail_in;
- zfile.avail_in = 0;
- - zfile.total_in = info->compressedsize;
- + zfile.total_in = info->compressedsize;
- arch->owner = NULL;
- ended = false;
- return true;
- @@ -451,7 +477,7 @@
- if(pos < 0) return false;
- if(pos >= (long)zfile.total_out) pos -= zfile.total_out;
- - else
- + else
- {
- if(zfile.next_in && zfile.total_in <= uint(zfile.next_in - buf))
- {
- @@ -491,7 +517,7 @@
- if(fseek(arch->data, reading, SEEK_SET) < 0) { stopreading(); return 0; }
- arch->owner = this;
- }
- -
- +
- int n = (int)fread(buf, 1, min(len, int(info->size + info->offset - reading)), arch->data);
- reading += n;
- if(n < len) ended = true;
- @@ -504,7 +530,7 @@
- {
- if(!zfile.avail_in) readbuf(BUFSIZE);
- int err = inflate(&zfile, Z_NO_FLUSH);
- - if(err != Z_OK)
- + if(err != Z_OK)
- {
- if(err == Z_STREAM_END) ended = true;
- else
- @@ -514,13 +540,33 @@
- #endif
- stopreading();
- }
- - break;
- + break;
- }
- }
- return len - zfile.avail_out;
- }
- };
- +bool extractzipfile(ziparchive *a, zipfile *f, const char *name)
- +{
- + zipstream *s = new zipstream;
- + FILE *target;
- + defformatstring(fname)("%s", findfile(name, "wb"));
- + preparedir(fname);
- + bool error = false;
- + if(s->open(a, f) && (target = fopen(fname, "wb")))
- + {
- + size_t len;
- + uchar copybuf[1024];
- + while((len = s->read(copybuf, 1024))) fwrite(copybuf, 1, len, target);
- + }
- + else error = true;
- + if(error) conoutf("failed to extract zip file %s from archive %s", fname, a->name);
- + if(target) fclose(target);
- + delete s;
- + return !error;
- +}
- +
- stream *openzipfile(const char *name, const char *mode)
- {
- for(; *mode; mode++) if(*mode=='w' || *mode=='a') return NULL;
Add Comment
Please, Sign In to add comment