diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 2c4a86a6..634e8aa1 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -811,7 +811,7 @@ void receivefile(uchar *data, int len) case SV_SENDDEMO: { systemtime(); - s_sprintfd(fname)("demos/%d.dmo", now_utc); //totalmillis); + s_sprintfd(fname)("demos/%d.dmo", now_utc); path(fname); FILE *demo = openfile(fname, "wb"); if(!demo) diff --git a/source/src/main.cpp b/source/src/main.cpp index d1b1a57a..f054a1b4 100644 --- a/source/src/main.cpp +++ b/source/src/main.cpp @@ -475,7 +475,7 @@ int main(int argc, char **argv) #endif bool dedicated = false; - int uprate = 0, maxcl = DEFAULTCLIENTS, scthreshold = -5, port = 0, permdemo = -1; + int uprate = 0, maxcl = DEFAULTCLIENTS, kthreshold = -5, bthreshold = -6, port = 0, permdemo = -1; const char *sdesc = "", *sdesc_pre = "", *sdesc_suf = "", *ip = "", *master = NULL, *passwd = "", *maprot = NULL, *adminpwd = NULL, *pwdfile = NULL, *blfile = NULL, *srvmsg = NULL; pushscontext(IEXC_CFG); @@ -536,7 +536,8 @@ int main(int argc, char **argv) case 'V': verbose = 1; break; case 'c': maxcl = atoi(a); break; case 'o': srvmsg = a; break; - case 'k': scthreshold = atoi(a); break; + case 'k': kthreshold = atoi(a); break; + case 'y': bthreshold = atoi(a); break; case 'f': port = atoi(a); break; case 'D': permdemo = isdigit(*a) ? atoi(a) : 0; break; default: conoutf("unknown commandline option"); @@ -560,7 +561,7 @@ int main(int argc, char **argv) if(enet_initialize()<0) fatal("Unable to initialise network module"); initclient(); - initserver(dedicated, uprate, sdesc, sdesc_pre, sdesc_suf, ip, port, master, passwd, maxcl, maprot, adminpwd, pwdfile, blfile, srvmsg, scthreshold, permdemo); // never returns if dedicated + initserver(dedicated, uprate, sdesc, sdesc_pre, sdesc_suf, ip, port, master, passwd, maxcl, maprot, adminpwd, pwdfile, blfile, srvmsg, kthreshold, bthreshold, permdemo); // never returns if dedicated initlog("world"); empty_world(7, true); diff --git a/source/src/protocol.h b/source/src/protocol.h index 9c7474fc..44fbbce6 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -80,7 +80,7 @@ enum { FM_PICKUP = 0, FM_DROP, FM_LOST, FM_RETURN, FM_SCORE, FM_KTFSCORE, FM_SCO #define DNF 100.0f #define DVELF 4.0f -enum { DISC_NONE = 0, DISC_EOP, DISC_CN, DISC_MKICK, DISC_MBAN, DISC_TAGT, DISC_BANREFUSE, DISC_WRONGPW, DISC_SOPLOGINFAIL, DISC_MAXCLIENTS, DISC_MASTERMODE, DISC_AUTOKICK, DISC_DUP, DISC_NUM }; +enum { DISC_NONE = 0, DISC_EOP, DISC_CN, DISC_MKICK, DISC_MBAN, DISC_TAGT, DISC_BANREFUSE, DISC_WRONGPW, DISC_SOPLOGINFAIL, DISC_MAXCLIENTS, DISC_MASTERMODE, DISC_AUTOKICK, DISC_AUTOBAN, DISC_DUP, DISC_NUM }; #define EXT_ACK -1 #define EXT_VERSION 103 diff --git a/source/src/protos.h b/source/src/protos.h index 1589a8c8..b7ea5f3d 100644 --- a/source/src/protos.h +++ b/source/src/protos.h @@ -623,7 +623,7 @@ extern void localservertoclient(int chan, uchar *buf, int len); extern const char *modestr(int n, bool acronyms = false); extern const char *voteerrorstr(int n); extern void fatal(const char *s, ...); -extern void initserver(bool dedicated, int uprate, const char *sdesc, const char *sdesc_pre, const char *sdesc_suf, const char *ip, int serverport, const char *master, const char *passwd, int maxcl, const char *maprot, const char *adminpwd, const char *pwdfile, const char *blfile, const char *srvmsg, int scthreshold, int permdemo); +extern void initserver(bool dedicated, int uprate, const char *sdesc, const char *sdesc_pre, const char *sdesc_suf, const char *ip, int serverport, const char *master, const char *passwd, int maxcl, const char *maprot, const char *adminpwd, const char *pwdfile, const char *blfile, const char *srvmsg, int kthreshold, int bthreshold, int permdemo); extern void cleanupserver(); extern void localconnect(); extern void localdisconnect(); diff --git a/source/src/server.cpp b/source/src/server.cpp index 70851322..f12985f5 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -270,6 +270,14 @@ bool valid_client(int cn) return clients.inrange(cn) && clients[cn]->type != ST_EMPTY; } +struct ban +{ + ENetAddress address; + int millis; +}; + +vector bans; + struct worldstate { enet_uint32 uses; @@ -397,7 +405,7 @@ bool buildworldstate() } } -int maxclients = DEFAULTCLIENTS, scorethreshold = -5; +int maxclients = DEFAULTCLIENTS, kickthreshold = -5, banthreshold = -6; string smapname, nextmapname; int nextgamemode; @@ -1202,10 +1210,10 @@ void arenacheck() if(autoteam && m_teammode) refillteams(true); } -#define SPAMREPEATINTERVAL 15 // detect doubled lines only if interval < 15 seconds -#define SPAMMAXREPEAT 2 // 3rd time is SPAM +#define SPAMREPEATINTERVAL 20 // detect doubled lines only if interval < 20 seconds +#define SPAMMAXREPEAT 3 // 4th time is SPAM #define SPAMCHARPERMINUTE 220 // good typist -#define SPAMCHARINTERVAL 20 // allow 20 seconds typing at maxspeed +#define SPAMCHARINTERVAL 30 // allow 20 seconds typing at maxspeed bool spamdetect(client *cl, char *text) // checks doubled lines and average typing speed { @@ -1376,7 +1384,13 @@ void serverdamage(client *target, client *actor, int damage, int gun, bool gib, // don't issue respawn yet until DEATHMILLIS has elapsed // ts.respawn(); - if(actor->state.frags < scorethreshold) disconnect_client(actor->clientnum, DISC_AUTOKICK); + if(actor->state.frags < kickthreshold) disconnect_client(actor->clientnum, DISC_AUTOKICK); + else if(actor->state.frags < banthreshold) + { + ban b = { actor->peer->address, servmillis+20*60*1000 }; + bans.add(b); + disconnect_client(actor->clientnum, DISC_AUTOBAN); + } } } @@ -1864,14 +1878,6 @@ void nextcfgset(bool notify = true) // load next maprotation set resetmap(c->mapname, c->mode, c->time, notify); } -struct ban -{ - ENetAddress address; - int millis; -}; - -vector bans; - bool isbanned(int cn) { if(!valid_client(cn)) return false; @@ -2030,7 +2036,7 @@ bool callvote(voteinfo *v, ENetPacket *msg) // true if a regular vote was called const char *disc_reason(int reason) { - static const char *disc_reasons[] = { "normal", "end of packet", "client num", "kicked by server operator", "banned by server operator", "tag type", "connection refused due to ban", "wrong password", "failed admin login", "server FULL - maxclients", "server mastermode is \"private\"", "auto kick - did your score drop below the threshold?", "duplicate connection" }; + static const char *disc_reasons[] = { "normal", "end of packet", "client num", "kicked by server operator", "banned by server operator", "tag type", "connection refused due to ban", "wrong password", "failed admin login", "server FULL - maxclients", "server mastermode is \"private\"", "auto kick - did your score drop below the threshold?", "auto ban - did your score drop below the threshold?", "duplicate connection" }; return reason >= 0 && (size_t)reason < sizeof(disc_reasons)/sizeof(disc_reasons[0]) ? disc_reasons[reason] : "unknown"; } @@ -3319,7 +3325,7 @@ void localconnect() } #endif -void initserver(bool dedicated, int uprate, const char *sdesc, const char *sdesc_pre, const char *sdesc_suf, const char *ip, int serverport, const char *master, const char *passwd, int maxcl, const char *maprot, const char *adminpwd, const char *pwdfile, const char *blfile, const char *srvmsg, int scthreshold, int permdemo) +void initserver(bool dedicated, int uprate, const char *sdesc, const char *sdesc_pre, const char *sdesc_suf, const char *ip, int serverport, const char *master, const char *passwd, int maxcl, const char *maprot, const char *adminpwd, const char *pwdfile, const char *blfile, const char *srvmsg, int kthreshold, int bthreshold, int permdemo) { srand(time(NULL)); @@ -3347,7 +3353,8 @@ void initserver(bool dedicated, int uprate, const char *sdesc, const char *sdesc readscfg(maprot && maprot[0] ? maprot : "config/maprot.cfg"); if(adminpwd && adminpwd[0]) adminpasswd = adminpwd; if(srvmsg && srvmsg[0]) motd = srvmsg; - scorethreshold = min(-1, scthreshold); + kickthreshold = min(-1, kthreshold); + banthreshold = min(-1, bthreshold); readpwdfile(pwdfile && pwdfile[0] ? pwdfile : "config/serverpwd.cfg"); readblacklist(blfile && blfile[0] ? blfile : "config/serverblacklist.cfg"); if(permdemo >= 0) @@ -3396,7 +3403,7 @@ int main(int argc, char **argv) #endif #endif - int uprate = 0, maxcl = DEFAULTCLIENTS, scthreshold = -5, port = 0, permdemo = -1; + int uprate = 0, maxcl = DEFAULTCLIENTS, kthreshold = -5, bthreshold = -6, port = 0, permdemo = -1; const char *sdesc = "", *sdesc_pre = "", *sdesc_suf = "", *ip = "", *master = NULL, *passwd = "", *maprot = "", *admpwd = NULL, *pwdfile = NULL, *blfile = NULL, *srvmsg = NULL, *service = NULL; for(int i = 1; i