new voting
git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@1305 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
+37
-21
@@ -622,7 +622,41 @@ void flagmsg(int flag, int action)
|
||||
}
|
||||
}
|
||||
|
||||
// server administration
|
||||
void vote(int yes)
|
||||
{
|
||||
ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
|
||||
ucharbuf p(packet->data, packet->dataLength);
|
||||
putint(p, SV_VOTE);
|
||||
putint(p, yes > 0 ? VOTE_YES : VOTE_NO);
|
||||
enet_packet_resize(packet, p.length());
|
||||
sendpackettoserv(1, packet);
|
||||
}
|
||||
|
||||
void callvote(char *type, char *arg1, char *arg2 = NULL)
|
||||
{
|
||||
int t = atoi(type);
|
||||
ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
|
||||
ucharbuf p(packet->data, packet->dataLength);
|
||||
putint(p, SV_CALLVOTE);
|
||||
putint(p, t);
|
||||
switch(t)
|
||||
{
|
||||
case SA_MAP:
|
||||
sendstring(arg1, p);
|
||||
putint(p, atoi(arg2));
|
||||
break;
|
||||
case SA_KICK:
|
||||
case SA_BAN:
|
||||
case SA_MASTERMODE:
|
||||
case SA_AUTOTEAM:
|
||||
case SA_FORCETEAM:
|
||||
case SA_GIVEMASTER:
|
||||
putint(p, atoi(arg1));
|
||||
break;
|
||||
}
|
||||
enet_packet_resize(packet, p.length());
|
||||
sendpackettoserv(1, packet);
|
||||
}
|
||||
|
||||
void setmaster(int claim)
|
||||
{
|
||||
@@ -636,28 +670,10 @@ void setadmin(char *claim, char *password)
|
||||
else addmsg(SV_SETADMIN, "ris", atoi(claim) != 0 ? 1 : 0, password);
|
||||
}
|
||||
|
||||
void serveropcommand(int cmd, int a) // one of MCMD_*
|
||||
{
|
||||
addmsg(SV_SERVOPCMD, "rii", cmd, a);
|
||||
}
|
||||
|
||||
void kick(int player) { serveropcommand(SOPCMD_KICK, player); }
|
||||
void ban(int player) { serveropcommand(SOPCMD_BAN, player); }
|
||||
void removebans() { serveropcommand(SOPCMD_REMBANS, 0); }
|
||||
void autoteam(int enable) { serveropcommand(SOPCMD_AUTOTEAM, enable); }
|
||||
void mastermode(int mode) { serveropcommand(SOPCMD_MASTERMODE, mode); }
|
||||
void forceteam(int player) { serveropcommand(SOPCMD_FORCETEAM, player); }
|
||||
void givemaster(int player) { serveropcommand(SOPCMD_GIVEMASTER, player); }
|
||||
|
||||
COMMAND(vote, ARG_1INT);
|
||||
COMMAND(callvote, ARG_3STR);
|
||||
COMMAND(setmaster, ARG_1INT);
|
||||
COMMAND(setadmin, ARG_2STR);
|
||||
COMMAND(kick, ARG_1INT);
|
||||
COMMAND(ban, ARG_1INT);
|
||||
COMMAND(removebans, ARG_NONE);
|
||||
COMMAND(autoteam, ARG_1INT);
|
||||
COMMAND(mastermode, ARG_1INT);
|
||||
COMMAND(forceteam, ARG_1INT);
|
||||
COMMAND(givemaster, ARG_1INT);
|
||||
|
||||
struct mline { string name, cmd; };
|
||||
static vector<mline> mlines;
|
||||
|
||||
@@ -22,7 +22,8 @@ void changemap(char *name) // request map change, server ma
|
||||
{
|
||||
ENetPacket *packet = enet_packet_create(NULL, MAXTRANS, ENET_PACKET_FLAG_RELIABLE);
|
||||
ucharbuf p(packet->data, packet->dataLength);
|
||||
putint(p, SV_MAPCHANGE);
|
||||
putint(p, SV_CALLVOTE);
|
||||
putint(p, SA_MAP);
|
||||
sendstring(name, p);
|
||||
putint(p, nextmode);
|
||||
enet_packet_resize(packet, p.length());
|
||||
@@ -560,47 +561,51 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
|
||||
break;
|
||||
}
|
||||
|
||||
/* fixme,ah
|
||||
case SV_SERVOPCMD:
|
||||
{
|
||||
int cmd = getint(p), arg = getint(p);
|
||||
playerent *pl = (arg == getclientnum() ? NULL : getclient(arg));
|
||||
switch(cmd)
|
||||
{
|
||||
case SOPCMD_KICK:
|
||||
case SOPCMD_BAN:
|
||||
case SA_KICK:
|
||||
case SA_BAN:
|
||||
{
|
||||
if(pl) conoutf("%s has been %s", colorname(pl), cmd == SOPCMD_KICK ? "kicked" : "banned");
|
||||
if(pl) conoutf("%s has been %s", colorname(pl), cmd == SA_KICK ? "kicked" : "banned");
|
||||
break;
|
||||
}
|
||||
case SOPCMD_REMBANS:
|
||||
case SA_REMBANS:
|
||||
conoutf("bans removed");
|
||||
break;
|
||||
|
||||
case SOPCMD_MASTERMODE:
|
||||
case SA_MASTERMODE:
|
||||
conoutf("mastermode set to \"%s\"", arg ? "private" : "open");
|
||||
break;
|
||||
|
||||
case SOPCMD_AUTOTEAM:
|
||||
case SA_AUTOTEAM:
|
||||
autoteambalance = arg == 1;
|
||||
if(!joining) conoutf("autoteam is %s", autoteambalance ? "enabled" : "disabled");
|
||||
break;
|
||||
|
||||
case SOPCMD_GIVEMASTER:
|
||||
case SA_GIVEMASTER:
|
||||
if(pl) conoutf("the admin gave master state to %s", colorname(pl));
|
||||
break;
|
||||
|
||||
case SOPCMD_FORCETEAM:
|
||||
case SA_FORCETEAM:
|
||||
if(pl) conoutf("player %s was forced to change the team", colorname(pl));
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
/*fixme,ah
|
||||
case SV_SERVOPCMDDENIED:
|
||||
{
|
||||
conoutf("\f3denied. you have to be at least %s to perform this action", getint(p) == CR_ADMIN ? "admin" : "master");
|
||||
break;
|
||||
}
|
||||
*/
|
||||
|
||||
case SV_FORCETEAM:
|
||||
{
|
||||
@@ -608,6 +613,74 @@ void parsemessages(int cn, playerent *d, ucharbuf &p)
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_AUTOTEAM:
|
||||
autoteambalance = 1 == getint(p);
|
||||
break;
|
||||
|
||||
case SV_CALLVOTE:
|
||||
{
|
||||
if(!d) return;
|
||||
string action;
|
||||
int type;
|
||||
switch(type = getint(p))
|
||||
{
|
||||
case SA_KICK:
|
||||
case SA_BAN:
|
||||
{
|
||||
playerent *v = getclient(getint(p));
|
||||
if(!v) return;
|
||||
s_sprintf(action)("%s player %s", type==SA_KICK ? "kick" : "ban", colorname(v));
|
||||
break;
|
||||
}
|
||||
case SA_REMBANS: s_strcpy(action, "remove all bans"); break;
|
||||
case SA_MASTERMODE: s_sprintf(action)("set mastermode to %s", getint(p) == MM_OPEN ? "open" : "private"); break;
|
||||
case SA_AUTOTEAM: s_sprintf(action)("%s autoteam", getint(p) == 1 ? "enable" : "disable"); break;
|
||||
case SA_FORCETEAM:
|
||||
{
|
||||
playerent *v = getclient(getint(p));
|
||||
if(!v) return;
|
||||
s_sprintf(action)("force player %s to the enemy team", colorname(v));
|
||||
break;
|
||||
}
|
||||
case SA_GIVEMASTER:
|
||||
{
|
||||
playerent *v = getclient(getint(p));
|
||||
if(!v) return;
|
||||
s_sprintf(action)("give master to player %s", colorname(v));
|
||||
break;
|
||||
}
|
||||
case SA_MAP:
|
||||
getstring(text, p);
|
||||
s_sprintf(action)("load map %s in mode %s", text, modestr(getint(p)));
|
||||
break;
|
||||
default: return; // fixme
|
||||
}
|
||||
s_sprintfd(msg)("%s voted: %s", colorname(d), action);
|
||||
conoutf(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_VOTE:
|
||||
{
|
||||
getint(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_VOTERESULT:
|
||||
{
|
||||
getint(p);
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_VOTEERR:
|
||||
{
|
||||
char *verr[VOTEE_NUM] = { "voting is currently disabled", "there is already a vote pending", "you have already voted", "vote limit reached for the current game" };
|
||||
int e = getint(p);
|
||||
if(e < 0 || e >= VOTEE_NUM) return;
|
||||
conoutf("\f3could not vote: %s", verr[e]);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
neterr("type");
|
||||
return;
|
||||
|
||||
@@ -387,6 +387,7 @@ int main(int argc, char **argv)
|
||||
exec("config/prefabs.cfg");
|
||||
exec("config/sounds.cfg");
|
||||
exec("config/securemaps.cfg");
|
||||
exec("config/admin.cfg");
|
||||
execfile("config/servers.cfg");
|
||||
persistidents = true;
|
||||
|
||||
|
||||
@@ -115,7 +115,7 @@ char msgsizesl[] = // size inclusive message token, 0 for variable
|
||||
SV_MODELSKIN, 2,
|
||||
SV_FLAGPICKUP, 2, SV_FLAGDROP, 2, SV_FLAGRETURN, 2, SV_FLAGSCORE, 2, SV_FLAGRESET, 2, SV_FLAGINFO, 0, SV_FLAGS, 2,
|
||||
SV_ARENAWIN, 2,
|
||||
SV_SETMASTER, 2, SV_SETADMIN, 0, SV_SERVOPINFO, 3, SV_SERVOPCMD, 3, SV_SERVOPCMDDENIED, 2,
|
||||
SV_SETMASTER, 2, SV_SETADMIN, 0, SV_SERVOPINFO, 3, SV_CALLVOTE, 0, SV_VOTE, 2, SV_VOTEERR, 2, SV_VOTERESULT, 2,
|
||||
SV_FORCETEAM, 2, SV_AUTOTEAM, 2,
|
||||
SV_CONNECT, 0,
|
||||
SV_CLIENT, 0,
|
||||
|
||||
@@ -20,13 +20,16 @@ enum
|
||||
SV_MODELSKIN,
|
||||
SV_FLAGPICKUP, SV_FLAGDROP, SV_FLAGRETURN, SV_FLAGSCORE, SV_FLAGRESET, SV_FLAGINFO, SV_FLAGS,
|
||||
SV_ARENAWIN,
|
||||
SV_SETMASTER, SV_SETADMIN, SV_SERVOPINFO, SV_SERVOPCMD, SV_SERVOPCMDDENIED,
|
||||
SV_SETMASTER, SV_SETADMIN, SV_SERVOPINFO, SV_CALLVOTE, SV_VOTE, SV_VOTEERR, SV_VOTERESULT,
|
||||
SV_FORCETEAM, SV_AUTOTEAM,
|
||||
SV_CONNECT,
|
||||
SV_CLIENT,
|
||||
SV_CLIENT
|
||||
};
|
||||
|
||||
enum { SOPCMD_KICK = 0, SOPCMD_BAN, SOPCMD_REMBANS, SOPCMD_MASTERMODE, SOPCMD_AUTOTEAM, SOPCMD_FORCETEAM, SOPCMD_GIVEMASTER, SOPCMD_NUM};
|
||||
enum { SA_KICK = 0, SA_BAN, SA_REMBANS, SA_MASTERMODE, SA_AUTOTEAM, SA_FORCETEAM, SA_GIVEMASTER, SA_MAP, SA_NUM};
|
||||
enum { VOTE_NEUTRAL = 0, VOTE_YES, VOTE_NO };
|
||||
enum { VOTEE_DISABLED = 0, VOTEE_CUR, VOTEE_MUL, VOTEE_MAX, VOTEE_TLIMIT, VOTEE_NUM };
|
||||
enum { MM_OPEN, MM_PRIVATE, MM_NUM };
|
||||
|
||||
#define DMF 16.0f
|
||||
#define DNF 100.0f
|
||||
|
||||
+252
-67
@@ -13,7 +13,6 @@ static const int DEATHMILLIS = 250;
|
||||
|
||||
enum { GE_NONE = 0, GE_SHOT, GE_EXPLODE, GE_HIT, GE_AKIMBO, GE_RELOAD, GE_SUICIDE, GE_PICKUP };
|
||||
enum { ST_EMPTY, ST_LOCAL, ST_TCPIP };
|
||||
enum { MM_OPEN, MM_PRIVATE, MM_NUM };
|
||||
|
||||
int mastermode = MM_OPEN;
|
||||
|
||||
@@ -186,9 +185,10 @@ struct client // server side version of "dynent" type
|
||||
int clientnum;
|
||||
ENetPeer *peer;
|
||||
string hostname;
|
||||
string mapvote;
|
||||
//string mapvote; // fixme,ah
|
||||
string name, team;
|
||||
int modevote;
|
||||
//int modevote; // fixme,ah
|
||||
int vote;
|
||||
int role;
|
||||
bool isauthed; // for passworded servers
|
||||
bool timesync;
|
||||
@@ -206,7 +206,8 @@ struct client // server side version of "dynent" type
|
||||
|
||||
void mapchange()
|
||||
{
|
||||
mapvote[0] = 0;
|
||||
//mapvote[0] = 0; // fixme,ah
|
||||
vote = VOTE_NEUTRAL;
|
||||
state.reset();
|
||||
events.setsizenodelete(0);
|
||||
timesync = false;
|
||||
@@ -1001,7 +1002,8 @@ void readscfg(char *cfg)
|
||||
|
||||
void resetvotes()
|
||||
{
|
||||
loopv(clients) clients[i]->mapvote[0] = 0;
|
||||
//loopv(clients) clients[i]->mapvote[0] = 0; // fixme,ah
|
||||
loopv(clients) clients[i]->vote = VOTE_NEUTRAL;
|
||||
}
|
||||
|
||||
void forceteam(int client, int team)
|
||||
@@ -1067,34 +1069,6 @@ void nextcfgset(bool notify = true) // load next maprotation set
|
||||
resetmap(c.mapname, c.mode, c.time, notify);
|
||||
}
|
||||
|
||||
bool vote(char *map, int reqmode, int sender)
|
||||
{
|
||||
if(!valid_client(sender)) return false;
|
||||
|
||||
if(configsets.length() && curcfgset < configsets.length() && !configsets[curcfgset].vote && clients[sender]->role == CR_DEFAULT)
|
||||
{
|
||||
s_sprintfd(msg)("%s voted, but voting is currently disabled", clients[sender]->name);
|
||||
sendservmsg(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_strcpy(clients[sender]->mapvote, map);
|
||||
clients[sender]->modevote = reqmode;
|
||||
int yes = 0, no = 0;
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY)
|
||||
{
|
||||
if(clients[i]->mapvote[0]) { if(strcmp(clients[i]->mapvote, map)==0 && clients[i]->modevote==reqmode) yes++; else no++; }
|
||||
else no++;
|
||||
}
|
||||
if(yes==1 && no==0) return true; // single player
|
||||
s_sprintfd(msg)("%s suggests mode \"%s\" on map %s (set map to vote)", clients[sender]->name, modestr(reqmode), map);
|
||||
sendservmsg(msg);
|
||||
if(yes/(float)(yes+no) <= 0.5f && clients[sender]->role == CR_DEFAULT) return false;
|
||||
sendservmsg("vote passed");
|
||||
resetvotes();
|
||||
return true;
|
||||
}
|
||||
|
||||
struct ban
|
||||
{
|
||||
ENetAddress address;
|
||||
@@ -1142,6 +1116,7 @@ void changeclientrole(int client, int role, char *pwd = NULL, bool force=false)
|
||||
else if(pwd && pwd[0]) disconnect_client(client, DISC_SOPLOGINFAIL); // avoid brute-force
|
||||
}
|
||||
|
||||
/*
|
||||
void serveropcmddenied(int receiver, int requiredrole)
|
||||
{
|
||||
sendf(receiver, 1, "rii", SV_SERVOPCMDDENIED, requiredrole);
|
||||
@@ -1149,33 +1124,33 @@ void serveropcmddenied(int receiver, int requiredrole)
|
||||
|
||||
void serveropcmd(int sender, int cmd, int a)
|
||||
{
|
||||
if(!isdedicated || !valid_client(sender) || cmd < 0 || cmd >= SOPCMD_NUM) return;
|
||||
if(!isdedicated || !valid_client(sender) || cmd < 0 || cmd >= SA_NUM) return;
|
||||
#define requirerole(r) if(clients[sender]->role < r) { sendf(sender, 1, "rii", SV_SERVOPCMDDENIED, r); return; }
|
||||
|
||||
switch(cmd)
|
||||
{
|
||||
case SOPCMD_KICK:
|
||||
case SA_KICK:
|
||||
{
|
||||
requirerole(CR_MASTER);
|
||||
if(!valid_client(a)) return;
|
||||
disconnect_client(a, DISC_MKICK);
|
||||
break;
|
||||
}
|
||||
case SOPCMD_MASTERMODE:
|
||||
case SA_MASTERMODE:
|
||||
{
|
||||
requirerole(CR_MASTER);
|
||||
if(a < 0 || a >= MM_NUM) return;
|
||||
mastermode = a;
|
||||
break;
|
||||
}
|
||||
case SOPCMD_AUTOTEAM:
|
||||
case SA_AUTOTEAM:
|
||||
{
|
||||
requirerole(CR_MASTER);
|
||||
if(a < 0 || a > 1) return;
|
||||
if((autoteam = a == 1) == true && m_teammode) shuffleteams();
|
||||
break;
|
||||
}
|
||||
case SOPCMD_BAN:
|
||||
case SA_BAN:
|
||||
{
|
||||
requirerole(CR_MASTER);
|
||||
if(!valid_client(a)) return;
|
||||
@@ -1184,20 +1159,20 @@ void serveropcmd(int sender, int cmd, int a)
|
||||
disconnect_client(a, DISC_MBAN);
|
||||
break;
|
||||
}
|
||||
case SOPCMD_REMBANS:
|
||||
case SA_REMBANS:
|
||||
{
|
||||
requirerole(CR_MASTER);
|
||||
if(bans.length()) bans.setsize(0);
|
||||
break;
|
||||
}
|
||||
case SOPCMD_FORCETEAM:
|
||||
case SA_FORCETEAM:
|
||||
{
|
||||
requirerole(CR_MASTER);
|
||||
if(!valid_client(a)) return;
|
||||
forceteam(a, team_opposite(team_int(clients[a]->team)));
|
||||
break;
|
||||
}
|
||||
case SOPCMD_GIVEMASTER:
|
||||
case SA_GIVEMASTER:
|
||||
{
|
||||
requirerole(CR_ADMIN);
|
||||
if(!valid_client(a)) return;
|
||||
@@ -1207,6 +1182,191 @@ void serveropcmd(int sender, int cmd, int a)
|
||||
}
|
||||
sendf(-1, 1, "riii", SV_SERVOPCMD, cmd, a);
|
||||
}
|
||||
*/
|
||||
|
||||
struct serveraction
|
||||
{
|
||||
int type, role;
|
||||
virtual void perform() = 0;
|
||||
virtual bool isvalid() { return true; }
|
||||
};
|
||||
|
||||
struct mapaction : serveraction
|
||||
{
|
||||
char *map;
|
||||
int mode;
|
||||
void perform() { resetmap(map, mode); }
|
||||
mapaction(char *map, int mode) : map(map), mode(mode) { type = SA_MAP; role = CR_MASTER; }
|
||||
~mapaction() { DELETEA(map); }
|
||||
};
|
||||
|
||||
struct playeraction : serveraction
|
||||
{
|
||||
int cn;
|
||||
void disconnect(int reason) { disconnect_client(cn, reason); }
|
||||
bool isvalid() { return valid_client(cn); }
|
||||
playeraction(int cn) : cn(cn) {}
|
||||
};
|
||||
|
||||
struct forceteamaction : playeraction
|
||||
{
|
||||
void perform() { forceteam(cn, team_opposite(team_int(clients[cn]->team))); }
|
||||
forceteamaction(int cn) : playeraction(cn) { type = SA_FORCETEAM; role = CR_MASTER; }
|
||||
};
|
||||
|
||||
struct givemasteraction : playeraction
|
||||
{
|
||||
void perform() { changeclientrole(cn, CR_MASTER, NULL, true); }
|
||||
givemasteraction(int cn) : playeraction(cn) { type = SA_GIVEMASTER; role = CR_ADMIN; }
|
||||
};
|
||||
|
||||
struct kickaction : playeraction
|
||||
{
|
||||
void perform() { disconnect(DISC_MKICK); }
|
||||
kickaction(int cn) : playeraction(cn) { type = SA_KICK; role = CR_MASTER; }
|
||||
};
|
||||
|
||||
struct banaction : playeraction
|
||||
{
|
||||
void perform()
|
||||
{
|
||||
ban b = { clients[cn]->peer->address, lastsec+20*60 };
|
||||
bans.add(b);
|
||||
disconnect(DISC_MBAN);
|
||||
}
|
||||
banaction(int cn) : playeraction(cn) { type = SA_BAN; role = CR_MASTER; }
|
||||
};
|
||||
|
||||
struct removebansaction : serveraction
|
||||
{
|
||||
void perform() { bans.setsize(0); }
|
||||
removebansaction() { type = SA_REMBANS; role = CR_MASTER; }
|
||||
};
|
||||
|
||||
struct mastermodeaction : serveraction
|
||||
{
|
||||
int mode;
|
||||
void perform() { mastermode = mode; }
|
||||
bool isvalid() { return mode >= 0 && mode < MM_NUM; }
|
||||
mastermodeaction(int mode) : mode(mode) { type = SA_MASTERMODE; role = CR_MASTER; }
|
||||
};
|
||||
|
||||
struct autoteamaction : serveraction
|
||||
{
|
||||
bool enabled;
|
||||
void perform()
|
||||
{
|
||||
sendf(-1, 1, "ri2", SV_AUTOTEAM, (autoteam = enabled) == 1 ? 1 : 0);
|
||||
if(m_teammode) shuffleteams();
|
||||
}
|
||||
autoteamaction(bool enabled) : enabled(enabled) { type = SA_AUTOTEAM; role = CR_MASTER; }
|
||||
};
|
||||
|
||||
struct voteinfo
|
||||
{
|
||||
int owner, secs;
|
||||
serveraction *action;
|
||||
void pass() { if(action) action->perform(); }
|
||||
bool isvalid() { return valid_client(owner) && action != NULL && action->isvalid(); }
|
||||
bool isalive() { return secs > lastsec; }
|
||||
};
|
||||
|
||||
voteinfo *curvote = NULL;
|
||||
|
||||
void checkvotes(bool forceend = false)
|
||||
{
|
||||
if(!curvote) return;
|
||||
int stats[3] = {0};
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY) { stats[clients[i]->vote]++; };
|
||||
int total = stats[VOTE_NO]+stats[VOTE_YES]+stats[VOTE_NEUTRAL];
|
||||
loopi(2) if(stats[i]/(float)total > 0.51f || (forceend && VOTE_NO==i))
|
||||
{
|
||||
resetvotes();
|
||||
sendf(-1, 1, "ri2", SV_VOTERESULT, i);
|
||||
if(VOTE_YES==i) curvote->pass();
|
||||
delete curvote;
|
||||
curvote = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
bool vote(int sender, int vote)
|
||||
{
|
||||
if(!curvote || !valid_client(sender) || vote < VOTE_YES || vote > VOTE_NO) return false;
|
||||
if(clients[sender]->vote != VOTE_NEUTRAL)
|
||||
{
|
||||
sendf(sender, 1, "ri2", SV_VOTEERR, VOTEE_MUL);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
clients[sender]->vote = vote;
|
||||
checkvotes();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool callvote(voteinfo *v)
|
||||
{
|
||||
if(!v || !v->isvalid()) return false;
|
||||
if(isdedicated && clients[v->owner]->role >= v->action->role) // pass server op commands
|
||||
{
|
||||
v->action->perform();
|
||||
return false;
|
||||
}
|
||||
else // regular vote
|
||||
{
|
||||
if(curvote)
|
||||
{
|
||||
sendf(v->owner, 1, "ri2", SV_VOTEERR, VOTEE_CUR);
|
||||
return false;
|
||||
}
|
||||
else if(configsets.length() && curcfgset < configsets.length() && !configsets[curcfgset].vote && clients[v->owner]->role == CR_DEFAULT)
|
||||
{
|
||||
sendf(v->owner, 1, "ri2", SV_VOTEERR, VOTEE_DISABLED);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
curvote = v;
|
||||
if(!vote(v->owner, VOTE_YES))
|
||||
{
|
||||
delete curvote;
|
||||
curvote = NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/*bool vote(char *map, int reqmode, int sender)
|
||||
{
|
||||
if(!valid_client(sender)) return false;
|
||||
|
||||
if(configsets.length() && curcfgset < configsets.length() && !configsets[curcfgset].vote && clients[sender]->role == CR_DEFAULT)
|
||||
{
|
||||
s_sprintfd(msg)("%s voted, but voting is currently disabled", clients[sender]->name);
|
||||
sendservmsg(msg);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_strcpy(clients[sender]->mapvote, map);
|
||||
clients[sender]->modevote = reqmode;
|
||||
int yes = 0, no = 0;
|
||||
loopv(clients) if(clients[i]->type!=ST_EMPTY)
|
||||
{
|
||||
if(clients[i]->mapvote[0]) { if(strcmp(clients[i]->mapvote, map)==0 && clients[i]->modevote==reqmode) yes++; else no++; }
|
||||
else no++;
|
||||
}
|
||||
if(yes==1 && no==0) return true; // single player
|
||||
s_sprintfd(msg)("%s suggests mode \"%s\" on map %s (set map to vote)", clients[sender]->name, modestr(reqmode), map);
|
||||
sendservmsg(msg);
|
||||
if(yes/(float)(yes+no) <= 0.5f && clients[sender]->role == CR_DEFAULT) return false;
|
||||
sendservmsg("vote passed");
|
||||
resetvotes();
|
||||
return true;
|
||||
}*/
|
||||
|
||||
// sending of maps between clients
|
||||
|
||||
@@ -1315,8 +1475,8 @@ void sendwelcome(int n)
|
||||
}
|
||||
putint(p, -1);
|
||||
}
|
||||
putint(p, SV_SERVOPCMD);
|
||||
putint(p, SOPCMD_AUTOTEAM);
|
||||
// fixme,ah
|
||||
putint(p, SV_AUTOTEAM);
|
||||
putint(p, autoteam);
|
||||
if(motd)
|
||||
{
|
||||
@@ -1335,7 +1495,7 @@ int checktype(int type, client *cl)
|
||||
static int edittypes[] = { SV_EDITENT, SV_EDITH, SV_EDITT, SV_EDITS, SV_EDITD, SV_EDITE };
|
||||
if(cl && smode!=1) loopi(sizeof(edittypes)/sizeof(int)) if(type == edittypes[i]) return -1;
|
||||
// server only messages
|
||||
static int servtypes[] = { SV_INITS2C, SV_MAPRELOAD, SV_SERVMSG, SV_GIBDAMAGE, SV_DAMAGE, SV_HITPUSH, SV_SHOTFX, SV_DIED, SV_SPAWNSTATE, SV_FORCEDEATH, SV_ITEMACC, SV_ITEMSPAWN, SV_TIMEUP, SV_CDIS, SV_PONG, SV_RESUME, SV_FLAGINFO, SV_ARENAWIN, SV_CLIENT };
|
||||
static int servtypes[] = { SV_INITS2C, SV_MAPRELOAD, SV_SERVMSG, SV_GIBDAMAGE, SV_DAMAGE, SV_HITPUSH, SV_SHOTFX, SV_DIED, SV_SPAWNSTATE, SV_FORCEDEATH, SV_ITEMACC, SV_ITEMSPAWN, SV_TIMEUP, SV_CDIS, SV_PONG, SV_RESUME, SV_FLAGINFO, SV_ARENAWIN, SV_CLIENT, SV_VOTERESULT };
|
||||
if(cl) loopi(sizeof(servtypes)/sizeof(int)) if(type == servtypes[i]) return -1;
|
||||
return type;
|
||||
}
|
||||
@@ -1432,18 +1592,7 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1
|
||||
QUEUE_MSG;
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_MAPCHANGE:
|
||||
{
|
||||
getstring(text, p);
|
||||
filtertext(text, text);
|
||||
int reqmode = getint(p);
|
||||
if(cl->type==ST_TCPIP && !m_mp(reqmode)) reqmode = 0;
|
||||
if(smapname[0] && !mapreload && !vote(text, reqmode, sender)) return;
|
||||
resetmap(text, reqmode);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
case SV_ITEMLIST:
|
||||
{
|
||||
int n;
|
||||
@@ -1634,6 +1783,11 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_FLAGS:
|
||||
cl->state.flagscore = getint(p);
|
||||
QUEUE_MSG;
|
||||
break;
|
||||
|
||||
case SV_SETMASTER:
|
||||
{
|
||||
changeclientrole(sender, getint(p) != 0 ? CR_MASTER : CR_DEFAULT, NULL);
|
||||
@@ -1648,18 +1802,47 @@ void process(ENetPacket *packet, int sender, int chan) // sender may be -1
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_SERVOPCMD:
|
||||
{
|
||||
int cmd = getint(p);
|
||||
int arg = getint(p);
|
||||
serveropcmd(sender, cmd, arg);
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_FLAGS:
|
||||
cl->state.flagscore = getint(p);
|
||||
QUEUE_MSG;
|
||||
case SV_CALLVOTE:
|
||||
{
|
||||
voteinfo *vi = new voteinfo;
|
||||
switch(getint(p))
|
||||
{
|
||||
case SA_MAP:
|
||||
getstring(text, p);
|
||||
filtertext(text, text);
|
||||
vi->action = new mapaction(newstring(text), getint(p));
|
||||
break;
|
||||
case SA_KICK:
|
||||
vi->action = new kickaction(getint(p));
|
||||
break;
|
||||
case SA_BAN:
|
||||
vi->action = new banaction(getint(p));
|
||||
break;
|
||||
case SA_REMBANS:
|
||||
vi->action = new removebansaction();
|
||||
break;
|
||||
case SA_MASTERMODE:
|
||||
vi->action = new mastermodeaction(getint(p));
|
||||
break;
|
||||
case SA_AUTOTEAM:
|
||||
vi->action = new autoteamaction(getint(p) > 0);
|
||||
break;
|
||||
case SA_GIVEMASTER:
|
||||
vi->action = new givemasteraction(getint(p) > 0);
|
||||
break;
|
||||
}
|
||||
vi->owner = sender;
|
||||
vi->secs = lastsec+60;
|
||||
if(callvote(vi)) { QUEUE_MSG; }
|
||||
else delete vi;
|
||||
break;
|
||||
}
|
||||
|
||||
case SV_VOTE:
|
||||
{
|
||||
vote(sender, getint(p));
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
@@ -1751,6 +1934,8 @@ void serverslice(uint timeout) // main server update, called from cube main lo
|
||||
}
|
||||
if(m_arena) arenacheck();
|
||||
}
|
||||
|
||||
if(curvote && !curvote->isalive()) checkvotes(true);
|
||||
|
||||
int nonlocalclients = numnonlocalclients();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user