more vote abuse control, and a new vote switch "W": allow or not "weak" kick/ban votes: when the player is not lagging, spamming, tking, or obviously cheating...

git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@5152 e016b1c5-ed68-44aa-a2f7-31cac88cffde
This commit is contained in:
Rafael Barreto
2010-06-06 20:41:07 +00:00
parent f66f445506
commit b5ea3fc741
7 changed files with 46 additions and 20 deletions
+3 -1
View File
@@ -553,11 +553,13 @@
<td>vote for coopedit mode</td></tr>
<tr><td>p</td>
<td>vote for a gamemode that is not supported by the map (default: no one can)</td></tr>
<tr><td>w</td>
<td>vote to kick/ban for "weak" reasons, i.e, the other player is not obviously lagging, nor teamkilling, nor spamming, nor cheating (as far as the server can detect it)</td></tr>
</table>
For example: -PbmA enables ban &amp; mastermode to be voted by normal players but
only admins can change autoteam. The '-P' parameter can be used several times on the commandline.
For example, '-Pb -Pm -PA' is equivalent to '-PbmA'.
The default settings are: "fkBMasRCDE".
The default settings are: "fKBMasRCDEW".
</td>
</tr>
<tr>
+1 -1
View File
@@ -307,7 +307,7 @@ const char *modeacronymnames[] =
"OSOK", "TOSOK", "BOSOK", "HTF", "TKTF", "KTF"
};
const char *voteerrors[] = { "voting is currently disabled", "there is already a vote pending", "already voted", "can't vote that often", "this vote is not allowed in the current environment (singleplayer/multiplayer)", "no permission", "invalid vote" };
const char *voteerrors[] = { "voting is currently disabled", "there is already a vote pending", "already voted", "can't vote that often", "this vote is not allowed in the current environment (singleplayer/multiplayer)", "no permission", "invalid vote", "server denied your call" };
const char *mmfullnames[] = { "open", "private", "match" };
const char *fullmodestr(int n) { return (n>=-1 && size_t(n+1) < sizeof(modefullnames)/sizeof(modefullnames[0])) ? modefullnames[n+1] : "unknown"; }
+1 -1
View File
@@ -53,7 +53,7 @@ extern const char *messagenames[SV_NUM];
enum { SA_KICK = 0, SA_BAN, SA_REMBANS, SA_MASTERMODE, SA_AUTOTEAM, SA_FORCETEAM, SA_GIVEADMIN, SA_MAP, SA_RECORDDEMO, SA_STOPDEMO, SA_CLEARDEMOS, SA_SERVERDESC, SA_SHUFFLETEAMS, SA_NUM};
enum { VOTE_NEUTRAL = 0, VOTE_YES, VOTE_NO, VOTE_NUM };
enum { VOTEE_DISABLED = 0, VOTEE_CUR, VOTEE_MUL, VOTEE_MAX, VOTEE_AREA, VOTEE_PERMISSION, VOTEE_INVALID, VOTEE_NUM };
enum { VOTEE_DISABLED = 0, VOTEE_CUR, VOTEE_MUL, VOTEE_MAX, VOTEE_AREA, VOTEE_PERMISSION, VOTEE_INVALID, VOTEE_WEAK, VOTEE_NUM };
enum { MM_OPEN = 0, MM_PRIVATE, MM_MATCH, MM_NUM }; enum { MM_MASK = 0x03 };
enum { AT_DISABLED = 0, AT_ENABLED = 1, AT_SHUFFLE = 2, AT_NUM };
enum { FA_PICKUP = 0, FA_STEAL, FA_DROP, FA_LOST, FA_RETURN, FA_SCORE, FA_NUM, FA_RESET };
+27 -12
View File
@@ -1846,10 +1846,11 @@ void sendserveropinfo(int receiver)
struct voteinfo
{
bool boot;
int owner, callmillis, result;
serveraction *action;
voteinfo() : owner(0), callmillis(0), result(VOTE_NEUTRAL), action(NULL) {}
voteinfo() : boot(false), owner(0), callmillis(0), result(VOTE_NEUTRAL), action(NULL) {}
~voteinfo() { delete action; }
void end(int result)
@@ -1866,7 +1867,7 @@ struct voteinfo
}
bool isvalid() { return valid_client(owner) && action != NULL && action->isvalid(); }
bool isalive() { return servmillis - callmillis < 40*1000; }
bool isalive() { return servmillis - callmillis < 30*1000; }
void evaluate(bool forceend = false)
{
@@ -1921,7 +1922,7 @@ void scallvotesuc(voteinfo *v)
DELETEP(curvote);
curvote = v;
clients[v->owner]->lastvotecall = servmillis;
clients[v->owner]->nvotes--; // successful votes do not count as abuse
sendf(v->owner, 1, "ri", SV_CALLVOTESUC);
logline(ACLOG_INFO, "[%s] client %s called a vote: %s", clients[v->owner]->hostname, clients[v->owner]->name, v->action->desc ? v->action->desc : "[unknown]");
}
@@ -1937,14 +1938,25 @@ bool scallvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was calle
{
int area = isdedicated ? EE_DED_SERV : EE_LOCAL_SERV;
int error = -1;
client *c = clients[v->owner], *b = v->boot ? clients[cn2boot] : NULL;
if(!v || !v->isvalid()) error = VOTEE_INVALID;
else if(v->action->role > clients[v->owner]->role) error = VOTEE_PERMISSION;
else if(!(area & v->action->area)) error = VOTEE_AREA;
else if(curvote && curvote->result==VOTE_NEUTRAL) error = VOTEE_CUR;
else if(clients[v->owner]->role == CR_DEFAULT && v->action->isdisabled()) error = VOTEE_DISABLED;
else if(clients[v->owner]->lastvotecall && servmillis - clients[v->owner]->lastvotecall < 60*1000 && clients[v->owner]->role != CR_ADMIN && numclients()>1)
error = VOTEE_MAX;
int time = servmillis - c->lastvotecall;
if ( c->nvotes > 0 && time > 4*60*1000 ) c->nvotes -= time/(4*60*1000);
if ( c->nvotes < 0 ) c->nvotes = 0;
c->nvotes++;
if( !v || !v->isvalid() || (v->boot && !b) ) error = VOTEE_INVALID;
else if( v->action->role > c->role ) error = VOTEE_PERMISSION;
else if( !(area & v->action->area) ) error = VOTEE_AREA;
else if( curvote && curvote->result==VOTE_NEUTRAL ) error = VOTEE_CUR;
else if( c->role == CR_DEFAULT && v->action->isdisabled() ) error = VOTEE_DISABLED;
else if( (c->lastvotecall && servmillis - c->lastvotecall < 60*1000 && c->role != CR_ADMIN && numclients()>1) || c->nvotes > 3 ) error = VOTEE_MAX;
else if( c->role < roleconf('W') && v->boot == true && !is_lagging(b) && !b->mute && b->spamcount < 2 ) {
/** not same team, with low ratio, not lagging, and not spamming... so, why to kick? */
if ( !isteam(c->team, b->team) && b->state.frags < ( b->state.deaths ? b->state.deaths : 1 ) * 5 ) error = VOTEE_WEAK;
/** same team, with low tk, not lagging, and not spamming... so, why to kick? */
else if ( isteam(c->team, b->team) && b->state.teamkills <= c->state.teamkills ) error = VOTEE_WEAK;
}
if(error>=0)
{
@@ -2756,7 +2768,7 @@ void process(ENetPacket *packet, int sender, int chan)
while(curmsg<p.length()) cl->position.add(p.buf[curmsg++]);
}
if(maplayout && !m_demo && !m_coop) checkclientpos(cl);
checkmove(cn, val);
checkmove(cl, val);
break;
}
@@ -2801,7 +2813,7 @@ void process(ENetPacket *packet, int sender, int chan)
while(curmsg<p.length()) cl->position.add(p.buf[curmsg++]);
}
if(maplayout && !m_demo && !m_coop) checkclientpos(cl);
checkmove(cn, val);
checkmove(cl, val);
break;
}
@@ -2931,6 +2943,7 @@ void process(ENetPacket *packet, int sender, int chan)
case SV_CALLVOTE:
{
voteinfo *vi = new voteinfo;
vi->boot = false;
int type = getint(p);
switch(type)
{
@@ -2949,6 +2962,7 @@ void process(ENetPacket *packet, int sender, int chan)
getstring(text, p);
filtertext(text, text);
vi->action = new kickaction(cn2boot, newstring(text));
vi->boot = true;
break;
}
case SA_BAN:
@@ -2957,6 +2971,7 @@ void process(ENetPacket *packet, int sender, int chan)
getstring(text, p);
filtertext(text, text);
vi->action = new banaction(cn2boot, newstring(text));
vi->boot = true;
break;
}
case SA_REMBANS:
+4 -2
View File
@@ -226,7 +226,7 @@ struct client // server side version of "dynent" type
int skin[2];
int vote;
int role;
int connectmillis;
int connectmillis, lmillis, ldt, spj;
int mute, spam, lastvc; // server side voice comm spam control
int acversion, acbuildtype;
bool isauthed; // for passworded servers
@@ -253,6 +253,7 @@ struct client // server side version of "dynent" type
medals md;
bool upspawnp;
vec spawnp;
int nvotes;
gameevent &addevent()
{
@@ -281,6 +282,7 @@ struct client // server side version of "dynent" type
md.reset();
upspawnp = false;
spawnp = vec(-1e10f, -1e10f, -1e10f);
lmillis = ldt = spj = 0;
}
void reset()
@@ -301,7 +303,7 @@ struct client // server side version of "dynent" type
spectcn = FPCN_VOID;
mapchange();
freshgame = false; // don't spawn into running games
mute = spam = lastvc = badspeech = badmillis = 0;
mute = spam = lastvc = badspeech = badmillis = nvotes = 0;
}
void zap()
+1 -1
View File
@@ -3,7 +3,7 @@
enum { EE_LOCAL_SERV = 1, EE_DED_SERV = 1<<1 }; // execution environment
int roleconf(int key)
{ // current defaults: "fGkBMasRCDE"
{ // current defaults: "fGkBMasRCDEW"
if(strchr(scl.voteperm, tolower(key))) return CR_DEFAULT;
if(strchr(scl.voteperm, toupper(key))) return CR_ADMIN;
return (key) == tolower(key) ? CR_DEFAULT : CR_ADMIN;
+9 -2
View File
@@ -452,6 +452,10 @@ void checkfrag (client *target, client *actor, int gun, bool gib)
}
}
inline bool is_lagging(client *cl)
{
return ( cl->spj > 80 || gamemillis - cl->lmillis > 400 );
}
/**
If you read README.txt you must know that AC does not have cheat protection implemented.
@@ -469,9 +473,12 @@ This part is here for compatibility purposes.
If you know nothing about these detections, please, just ignore it.
*/
inline void checkmove (int cn, int *v)
inline void checkmove (client *cl, int *v)
{
client *cl = clients[cn];
cl->ldt = gamemillis - cl->lmillis;
cl->lmillis = gamemillis;
if ( cl->ldt < 30 ) cl->ldt = 30;
cl->spj = (( 7 * cl->spj + cl->ldt ) >> 3);
if ( !cl->upspawnp ) {
cl->spawnp = cl->state.o;
cl->upspawnp = true;