diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index a4179e87..31feb922 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -12,7 +12,7 @@ flaginfo flaginfos[2]; void mode(int n) { nextmode = n; - if(m_mp(n) || !multiplayer()) addmsg(SV_GAMEMODE, "ri", n); + if(m_mp(n) || !multiplayer()) addmsg(SV_GAMEMODE, "ri", n); } COMMAND(mode, ARG_1INT); @@ -1137,8 +1137,8 @@ int vote(int v) putint(p, SV_VOTE); putint(p, v); sendpackettoserv(1, p.finalize()); - // flowtron : 2008 11 06 : I don't think the following comments are still current - if(!curvote) { /*printf(":: curvote vanished!\n");*/ return 0; } // flowtron - happens when I call "/stopdemo"! .. seems the map-load happens in-between + // flowtron : 2008 11 06 : I don't think the following comments are still current + if(!curvote) { /*printf(":: curvote vanished!\n");*/ return 0; } // flowtron - happens when I call "/stopdemo"! .. seems the map-load happens in-between curvote->stats[v]++; curvote->localplayervoted = true; return 1; @@ -1214,6 +1214,18 @@ void setnext(char *arg1, char *arg2) } COMMAND(setnext, ARG_2STR); +void gonext(char *arg1) +{ + if(calledvote || !multiplayer(false)) return; + packetbuf p(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); + putint(p, SV_CALLVOTE); + putint(p, SA_MAP); + sendstring("+1", p); + putint(p, atoi(arg1)); + sendpackettoserv(1, p.finalize()); +} +COMMAND(gonext, ARG_1STR); + COMMANDN(callvote, scallvote, ARG_3STR); //fixme,ah COMMAND(vote, ARG_1EXP); diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 7e460365..7554ce17 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -1069,6 +1069,7 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) n_no = getint(p); type = getint(p); } + if (type == SA_MAP && d == NULL) d = player1; // gonext uses this if( type < 0 || type >= SA_NUM || !d ) return; votedisplayinfo *v = NULL; string a; @@ -1110,6 +1111,8 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) loopi(n_yes) votecount(VOTE_YES); loopi(n_no) votecount(VOTE_NO); } + extern int vote(int); + if (d == player1) vote(VOTE_YES); break; } diff --git a/source/src/server.cpp b/source/src/server.cpp index 0747e4c8..3f4cfbb3 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -1915,8 +1915,9 @@ struct voteinfo int owner, callmillis, result, num, type; char text[MAXTRANS]; serveraction *action; + bool gonext; - voteinfo() : boot(0), owner(0), callmillis(0), result(VOTE_NEUTRAL), action(NULL) {} + voteinfo() : boot(0), owner(0), callmillis(0), result(VOTE_NEUTRAL), action(NULL), gonext(false) {} ~voteinfo() { delete action; } void end(int result) @@ -2001,6 +2002,7 @@ void scallvoteerr(voteinfo *v, int error) } bool map_queued = false; +void callvotepacket (int, voteinfo *); bool scallvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was called { @@ -2042,13 +2044,15 @@ bool scallvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was calle nextgamemode = v->num-GMODE_NUM; copystring(nextmapname, v->text); } - sendpacket(-1, 1, msg, v->owner); - scallvotesuc(v); + if (!v->gonext) sendpacket(-1, 1, msg, v->owner); // FIXME in fact, all votes should go to the server, registered, and then go back to the clients + else callvotepacket (-1, v); // also, no vote should exclude the caller... these would provide many code advantages/facilities + scallvotesuc(v); // but we cannot change the vote system now for compatibility issues... so, TODO return true; } } -void callvotepacket (int cn) { // FIXME, it would be far smart if the msg buffer from SV_CALLVOTE was simply saved +void callvotepacket (int cn, voteinfo *v = curvote) +{ // FIXME, it would be far smart if the msg buffer from SV_CALLVOTE was simply saved int n_yes = 0, n_no = 0; loopv(clients) if(clients[i]->type!=ST_EMPTY) { @@ -2058,31 +2062,31 @@ void callvotepacket (int cn) { // FIXME, it would be far smart if the msg buffer packetbuf q(MAXTRANS, ENET_PACKET_FLAG_RELIABLE); putint(q, SV_CALLVOTE); - putint(q, -1); - putint(q, curvote->owner); - putint(q, n_yes); - putint(q, n_no); - putint(q, curvote->type); - switch(curvote->type) + putint(q, -1); + putint(q, v->owner); + putint(q, n_yes); + putint(q, n_no); + putint(q, v->type); + switch(v->type) { case SA_KICK: case SA_BAN: - putint(q, curvote->num); - sendstring(curvote->text, q); + putint(q, v->num); + sendstring(v->text, q); break; case SA_MAP: - sendstring(curvote->text, q); - putint(q, curvote->num); + sendstring(v->text, q); + putint(q, v->num); break; case SA_SERVERDESC: - sendstring(curvote->text, q); + sendstring(v->text, q); break; case SA_STOPDEMO: case SA_REMBANS: case SA_SHUFFLETEAMS: break; default: - putint(q, curvote->num); + putint(q, v->num); break; } sendpacket(cn, 1, q.finalize()); @@ -3071,12 +3075,27 @@ void process(ENetPacket *packet, int sender, int chan) { getstring(text, p); filtertext(text, text); - strncpy(vi->text,text,MAXTRANS-1); int mode = getint(p); - vi->num = mode; + vi->gonext = text[0]=='+' && text[1]=='1'; + if (vi->gonext) + { + int ccs = mode ? maprot.next(false,false) : maprot.get_next(); + configset *c = maprot.get(ccs); + if(c) + { + strcpy(vi->text,c->mapname); + mode = vi->num = c->mode; + } + else fatal("unable to get next map in maprot"); + } + else + { + strncpy(vi->text,text,MAXTRANS-1); + vi->num = mode; + } int qmode = (mode >= GMODE_NUM ? mode - GMODE_NUM : mode); if(mode==GMODE_DEMO) vi->action = new demoplayaction(newstring(text)); - else vi->action = new mapaction(newstring(text), qmode, sender, qmode!=mode); + else vi->action = new mapaction(newstring(vi->text), qmode, sender, qmode!=mode); break; } case SA_KICK: @@ -3483,6 +3502,7 @@ void serverslice(uint timeout) // main server update, called from cube main lo //start next game if(nextmapname[0]) startgame(nextmapname, nextgamemode); else maprot.next(); + nextmapname[0] = '\0'; map_queued = false; } diff --git a/source/src/serverfiles.h b/source/src/serverfiles.h index 01ab87a3..551f162b 100644 --- a/source/src/serverfiles.h +++ b/source/src/serverfiles.h @@ -327,6 +327,19 @@ struct servermaprot : serverconfigfile } configset *current() { return configsets.inrange(curcfgset) ? &configsets[curcfgset] : NULL; } + configset *get(int ccs) { return configsets.inrange(ccs) ? &configsets[ccs] : NULL; } + int get_next() + { + int ccs = curcfgset; + while(!strcmp(configsets[curcfgset].mapname,configsets[ccs].mapname)) + { + ccs++; + if(!configsets.inrange(ccs)) ccs=0; + if (ccs == curcfgset) break; + } + curcfgset = ccs; + return ccs; + } }; // serverblacklist.cfg