diff --git a/source/src/client.cpp b/source/src/client.cpp index 3fb15fd1..86731d3b 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -411,12 +411,12 @@ cvector securemaps; void clearsecuremaps() { securemaps.deletecontentsa(); } void securemap(char *map) { if(map) securemaps.add(newstring(map)); } -bool securemapcheck(char *map) +bool securemapcheck(char *map, bool msg) { if(strstr(map, "maps/")==map || strstr(map, "maps\\")==map) map += strlen("maps/"); loopv(securemaps) if(!strcmp(securemaps[i], map)) { - conoutf("\f3map %s is secured, you can not send, receive or overwrite it", map); + if(msg) conoutf("\f3map %s is secured, you can not send, receive or overwrite it", map); return true; } return false; diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index e721bc0c..1fa021bf 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -13,11 +13,18 @@ void neterr(const char *s) disconnect(); } -void changemapserv(char *name, int mode) // forced map change from the server +VARP(autogetmap, 0, 1, 1); + +void changemapserv(char *name, int mode, bool download) // forced map change from the server { gamemode = mode; if(m_demo) return; - load_world(name); + if(!load_world(name) && download) + { + if(securemapcheck(name, false)) return; + if(autogetmap) getmap(); + else conoutf("\"getmap\" to download the current map from the server"); + } } // update the position of other clients in the game in our world @@ -169,11 +176,15 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) break; case SV_MAPCHANGE: + { getstring(text, p); - changemapserv(text, getint(p)); + int mode = getint(p); + bool downloadable = getint(p) > 0; + changemapserv(text, mode, downloadable); if(m_arena && joining>2) deathstate(player1); mapchanged = true; break; + } case SV_ITEMLIST: { diff --git a/source/src/protos.h b/source/src/protos.h index 15faf12b..df5657a1 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -160,10 +160,11 @@ extern void c2sinfo(playerent *d); extern void c2skeepalive(); extern void neterr(const char *s); extern int getclientnum(); -extern void changemapserv(char *name, int mode); +extern void changemapserv(char *name, int mode, bool download = false); extern void changeteam(int team, bool respawn = true); +extern void getmap(); extern void newteam(char *name); -extern bool securemapcheck(char *map); +extern bool securemapcheck(char *map, bool msg = true); extern void sendintro(); extern void getdemo(int i); extern void listdemos(); @@ -326,7 +327,7 @@ extern void render_particles(int time); // worldio extern void save_world(char *fname); -extern void load_world(char *mname); +extern bool load_world(char *mname); extern void writemap(char *name, int size, uchar *data); extern void writecfg(char *name, int size, uchar *data); extern uchar *readmap(char *name, int *size); diff --git a/source/src/server.cpp b/source/src/server.cpp index 3d80e4d3..6a95a2da 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -1300,6 +1300,8 @@ void shuffleteams() } } +bool mapavailable(const char *mapname); + void resetmap(const char *newname, int newmode, int newtime = -1, bool notify = true) { if(m_demo) enddemoplayback(); @@ -1322,7 +1324,7 @@ void resetmap(const char *newname, int newmode, int newtime = -1, bool notify = ctfreset(); if(notify) { - sendf(-1, 1, "risi", SV_MAPCHANGE, smapname, smode); + sendf(-1, 1, "risii", SV_MAPCHANGE, smapname, smode, mapavailable(smapname) ? 1 : 0); if(smode>1 || (smode==0 && numnonlocalclients()>0)) sendf(-1, 1, "ri2", SV_TIMEUP, minremain); } if(m_teammode && !lastteammode) shuffleteams(); @@ -1516,6 +1518,8 @@ string copyname; int copysize, copymapsize, copycfgsize; uchar *copydata = NULL; +bool mapavailable(const char *mapname) { return !strcmp(copyname, mapname); } + void sendmapserv(int n, string mapname, int mapsize, int cfgsize, uchar *data) { if(!mapname[0] || mapsize <= 0 || mapsize + cfgsize > MAXMAPSENDSIZE) return; @@ -1556,6 +1560,7 @@ void welcomepacket(ucharbuf &p, int n) putint(p, SV_MAPCHANGE); sendstring(smapname, p); putint(p, smode); + putint(p, mapavailable(smapname) ? 1 : 0); if(smode>1 || (smode==0 && numnonlocalclients()>0)) { putint(p, SV_TIMEUP); diff --git a/source/src/worldio.cpp b/source/src/worldio.cpp index 3175c646..c279c258 100644 --- a/source/src/worldio.cpp +++ b/source/src/worldio.cpp @@ -110,7 +110,7 @@ void writemap(char *name, int msize, uchar *mdata) setnames(name); backup(cgzname, bakname); FILE *f = openfile(cgzname, "wb"); - if(!f) { conoutf("could not write map to %s", cgzname); return; } + if(!f) { conoutf("\f3could not write map to %s", cgzname); return; } fwrite(mdata, 1, msize, f); fclose(f); conoutf("wrote map %s as file %s", name, cgzname); @@ -120,7 +120,7 @@ uchar *readmap(char *name, int *size) { setnames(name); uchar *data = (uchar *)loadfile(cgzname, size); - if(!data) { conoutf("could not read map %s", cgzname); return NULL; } + if(!data) { conoutf("\f3could not read map %s", cgzname); return NULL; } return data; } @@ -128,7 +128,7 @@ void writecfg(char *name, int size, uchar *data) { setnames(name); FILE *f = openfile(mcfname, "w"); - if(!f) { conoutf("could not write config to %s", mcfname); return; } + if(!f) { conoutf("\f3could not write config to %s", mcfname); return; } fwrite(data, 1, size, f); fclose(f); conoutf("wrote map config to %s", mcfname); @@ -228,7 +228,7 @@ void save_world(char *mname) extern void preparectf(bool cleanonly = false); -void load_world(char *mname) // still supports all map formats that have existed since the earliest cube betas! +bool load_world(char *mname) // still supports all map formats that have existed since the earliest cube betas! { preparectf(true); cleardlights(); @@ -236,7 +236,7 @@ void load_world(char *mname) // still supports all map formats that have clearmapsounds(); setnames(mname); gzFile f = opengzfile(cgzname, "rb9"); - if(!f) { conoutf("could not read map %s", cgzname); return; } + if(!f) { conoutf("\f3could not read map %s", cgzname); return false; } loadingscreen(); gzread(f, &hdr, sizeof(header)-sizeof(int)*16); endianswap(&hdr.version, sizeof(int), 4); @@ -386,6 +386,7 @@ void load_world(char *mname) // still supports all map formats that have c2skeepalive(); preload_mapmodels(); c2skeepalive(); + return true; } COMMANDN(savemap, save_world, ARG_1STR);