From 87ea1d082381654ac3969e3f90a02a5b590311a8 Mon Sep 17 00:00:00 2001 From: Lucas GAUTHERON Date: Sat, 27 Aug 2011 18:52:19 +0000 Subject: [PATCH] private messages (chat) & win32 binaries (warning: new protocol) git-svn-id: svn://svn.code.sf.net/p/actiongame/code/trunk/ac@6614 e016b1c5-ed68-44aa-a2f7-31cac88cffde --- config/resetbinds.cfg | 2 +- config/scripts.cfg | 4 +++ source/src/client.cpp | 53 ++++++++++++++++++++++++++++++++++++--- source/src/clientgame.cpp | 2 ++ source/src/clients2c.cpp | 17 +++++++++++++ source/src/protocol.cpp | 4 +-- source/src/protocol.h | 4 +-- source/src/server.cpp | 39 +++++++++++++++++++++++++++- source/src/server.h | 2 +- 9 files changed, 116 insertions(+), 11 deletions(-) diff --git a/config/resetbinds.cfg b/config/resetbinds.cfg index 965ead0a..2f88fcac 100644 --- a/config/resetbinds.cfg +++ b/config/resetbinds.cfg @@ -67,7 +67,7 @@ bind J "" bind K [ if $old_editbinds [ corner ] [ if $editing [ if (countwalls 1) [ solid 0 ] [ corner ] ] ] ] // Toggle corner/non-solid bind L [ if $editing [ showmenu Lighting ] ] bind M [ if $editing [ domodifier 6 ] ] -bind N "" +bind N [ quickanswer ] bind O "editheight 2 -1" bind P "editheight 2 1" bind Q [ if $editing [ domodifier 1 ] ] diff --git a/config/scripts.cfg b/config/scripts.cfg index 9b4ac7a7..01c25e0e 100644 --- a/config/scripts.cfg +++ b/config/scripts.cfg @@ -233,6 +233,10 @@ const sbconnect [ ] ] ] + +// answer last PM +const quickanswer [ if (>= $lastpm 0) [ saycommand (concat "/pm" $lastpm ""); ] [ saycommand (concat "/pm" ""); ] ] + // For those players who use IRC too much... const join [ connect $arg1 $arg2 $arg3 ] const add2alias [ diff --git a/source/src/client.cpp b/source/src/client.cpp index c7c299ee..7b1b9d11 100644 --- a/source/src/client.cpp +++ b/source/src/client.cpp @@ -277,17 +277,62 @@ VARP(allowhudechos, 0, 1, 1); void hudecho(char *text) { const char *s = strtok(text, "\n"); + void (*outf)(const char *s, ...) = allowhudechos ? hudoutf : conoutf; do { - if(allowhudechos) - hudoutf("%s", s ? s : ""); - else - conoutf("%s", s ? s : ""); + outf("%s", s ? s : ""); s = strtok(NULL, "\n"); } while(s); } +void pm(char *text) +{ + if(!text || !text[0]) return; + int cn = -1; + char digit; + while ((digit = *text++) != '\0') + { + if (digit < '0' || digit > '9') break; + if(cn < 0) cn = 0; + else cn *= 10; + cn += digit - '0'; + } + playerent *to = getclient(cn); + if(!to) + { + conoutf("invalid client number specified"); + return; + } + + if(!isspace(digit)) { --text; } + + // FIXME: + /*if(!text || !text[0] || !isdigit(text[0])) return; + int cn = -1; + char *numend = strpbrk(text, " \t"); + if(!numend) return; + string cnbuf; + copystring(cnbuf, text, min(numend-text+1, MAXSTRLEN)); + cn = atoi(cnbuf); + playerent *to = getclient(cn); + if(!to) + { + conoutf("invalid client number specified"); + return; + } + + if(*numend) numend++;*/ + // :FIXME + + filtertext(text, text); + trimtrailingwhitespace(text); + + addmsg(SV_TEXTPRIVATE, "ris", cn, text); + conoutf("to %s:\f9 %s", colorname(to), highlight(text)); +} +COMMAND(pm, ARG_CONC); + COMMAND(echo, ARG_CONC); COMMAND(hudecho, ARG_CONC); COMMANDN(say, toserver, ARG_CONC); diff --git a/source/src/clientgame.cpp b/source/src/clientgame.cpp index e96d3449..634cbb6f 100644 --- a/source/src/clientgame.cpp +++ b/source/src/clientgame.cpp @@ -489,8 +489,10 @@ void freebotent(botent *d) } } +VAR(lastpm, -1, -1, -1); void zapplayer(playerent *&d) { + if(d && d->clientnum == lastpm) lastpm = -1; DELETEP(d); } diff --git a/source/src/clients2c.cpp b/source/src/clients2c.cpp index 9fc7a2ec..ee080883 100644 --- a/source/src/clients2c.cpp +++ b/source/src/clients2c.cpp @@ -243,6 +243,7 @@ char *mlayout = NULL; int Mv = 0, Ma = 0, F2F = 1000 * MINFF; // moved up:, MA = 0; float Mh = 0; extern int connected; +extern int lastpm; extern bool noflags; bool item_fail = false; int map_quality = MAP_IS_EDITABLE; @@ -497,6 +498,22 @@ void parsemessages(int cn, playerent *d, ucharbuf &p) else return; break; + case SV_TEXTPRIVATE: + { + int cn = getint(p); + getstring(text, p); + filtertext(text, text); + playerent *d = getclient(cn); + if(!d) break; + if(d->ignored) clientlogf("ignored: pm %s %s", colorname(d), text); + else + { + conoutf("%s (PM):\f9 %s", colorname(d), highlight(text)); + lastpm = d->clientnum; + } + break; + } + case SV_MAPCHANGE: { extern int spawnpermission; diff --git a/source/src/protocol.cpp b/source/src/protocol.cpp index 5786441f..ff800306 100644 --- a/source/src/protocol.cpp +++ b/source/src/protocol.cpp @@ -319,13 +319,13 @@ const char *mmfullname(int n) { return (n>=0 && n < MM_NUM) ? mmfullnames[n] : " static const int msgsizes[] = // size inclusive message token, 0 for variable or not-checked sizes { - SV_SERVINFO, 5, SV_WELCOME, 2, SV_INITCLIENT, 0, SV_POS, 0, SV_POSC, 0, SV_POSN, 0, SV_TEXT, 0, SV_TEAMTEXT, 0, SV_TEXTME, 0, SV_TEAMTEXTME, 0, + SV_SERVINFO, 5, SV_WELCOME, 2, SV_INITCLIENT, 0, SV_POS, 0, SV_POSC, 0, SV_POSN, 0, SV_TEXT, 0, SV_TEAMTEXT, 0, SV_TEXTME, 0, SV_TEAMTEXTME, 0, SV_TEXTPRIVATE, 0, SV_SOUND, 2, SV_VOICECOM, 2, SV_VOICECOMTEAM, 2, SV_CDIS, 2, SV_SHOOT, 0, SV_EXPLODE, 0, SV_SUICIDE, 1, SV_AKIMBO, 2, SV_RELOAD, 3, SV_AUTHT, 0, SV_AUTHREQ, 0, SV_AUTHTRY, 0, SV_AUTHANS, 0, SV_AUTHCHAL, 0, SV_GIBDIED, 5, SV_DIED, 5, SV_GIBDAMAGE, 7, SV_DAMAGE, 7, SV_HITPUSH, 6, SV_SHOTFX, 6, SV_THROWNADE, 8, SV_TRYSPAWN, 1, SV_SPAWNSTATE, 23, SV_SPAWN, 3, SV_SPAWNDENY, 2, SV_FORCEDEATH, 2, SV_RESUME, 0, SV_DISCSCORES, 0, SV_TIMEUP, 3, SV_EDITENT, 10, SV_ITEMACC, 2, - SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_ITEMPICKUP, 2, + SV_MAPCHANGE, 0, SV_ITEMSPAWN, 2, SV_PING, 2, SV_PONG, 2, SV_CLIENTPING, 2, SV_GAMEMODE, 2, SV_EDITMODE, 2, SV_EDITH, 7, SV_EDITT, 7, SV_EDITS, 6, SV_EDITD, 6, SV_EDITE, 6, SV_NEWMAP, 2, SV_SENDMAP, 0, SV_RECVMAP, 1, SV_REMOVEMAP, 0, diff --git a/source/src/protocol.h b/source/src/protocol.h index 3eea0ba3..9f3eeb71 100644 --- a/source/src/protocol.h +++ b/source/src/protocol.h @@ -5,7 +5,7 @@ #define CUBE_SERVINFO_PORT_LAN 28762 #define CUBE_SERVINFO_PORT(serverport) (serverport+1) #define CUBE_SERVINFO_TO_SERV_PORT(servinfoport) (servinfoport-1) -#define PROTOCOL_VERSION 1140 // 1132 // bump when protocol changes (use negative numbers for mods!) +#define PROTOCOL_VERSION 1141 // 1132 // bump when protocol changes (use negative numbers for mods!) #define DEMO_VERSION 2 // bump when demo format changes #define DEMO_MAGIC "ASSAULTCUBE_DEMO" #define DEMO_MINTIME 10000 // don't keep demo recordings with less than 10 seconds @@ -18,7 +18,7 @@ extern bool modprotocol; // network messages codes, c2s, c2c, s2c enum { - SV_SERVINFO = 0, SV_WELCOME, SV_INITCLIENT, SV_POS, SV_POSC, SV_POSN, SV_TEXT, SV_TEAMTEXT, SV_TEXTME, SV_TEAMTEXTME, + SV_SERVINFO = 0, SV_WELCOME, SV_INITCLIENT, SV_POS, SV_POSC, SV_POSN, SV_TEXT, SV_TEAMTEXT, SV_TEXTME, SV_TEAMTEXTME, SV_TEXTPRIVATE, SV_SOUND, SV_VOICECOM, SV_VOICECOMTEAM, SV_CDIS, SV_SHOOT, SV_EXPLODE, SV_SUICIDE, SV_AKIMBO, SV_RELOAD, SV_AUTHT, SV_AUTHREQ, SV_AUTHTRY, SV_AUTHANS, SV_AUTHCHAL, SV_GIBDIED, SV_DIED, SV_GIBDAMAGE, SV_DAMAGE, SV_HITPUSH, SV_SHOTFX, SV_THROWNADE, diff --git a/source/src/server.cpp b/source/src/server.cpp index 19b34c5a..5fb71290 100644 --- a/source/src/server.cpp +++ b/source/src/server.cpp @@ -2821,6 +2821,43 @@ void process(ENetPacket *packet, int sender, int chan) break; } + case SV_TEXTPRIVATE: + { + int targ = getint(p); + getstring(text, p); + filtertext(text, text); + trimtrailingwhitespace(text); + + if(!valid_client(targ)) break; + client *target = clients[targ]; + + if(*text) + { + bool canspeech = forbiddenlist.canspeech(text); + if(!spamdetect(cl, text) && canspeech) + { + bool allowed = !(mastermode == MM_MATCH && cl->team != target->team) && cl->role >= roleconf('T'); + logline(ACLOG_INFO, "[%s] %s says to %s: '%s' (%s)", cl->hostname, cl->name, target->name, text, allowed ? "allowed":"disallowed"); + if(allowed) sendf(target->clientnum, 1, "riis", SV_TEXTPRIVATE, cl->clientnum, text); + } + else + { + logline(ACLOG_INFO, "[%s] %s says to %s: '%s', %s", cl->hostname, cl->name, target->name, text, canspeech ? "SPAM detected" : "Forbidden speech"); + if (canspeech) + { + sendservmsg("\f3please do not spam", sender); + if ( cl->spamcount > SPAMMAXREPEAT + 2 ) disconnect_client(cl->clientnum, DISC_ABUSE); + } + else + { + sendservmsg("\f3watch your language!", sender); + kick_abuser(cl->clientnum, cl->badmillis, cl->badspeech, 3); + } + } + } + } + break; + case SV_VOICECOM: case SV_VOICECOMTEAM: { @@ -2839,7 +2876,7 @@ void process(ENetPacket *packet, int sender, int chan) else sendvoicecomteam(s, sender); } } - break; + break; case SV_MAPIDENT: { diff --git a/source/src/server.h b/source/src/server.h index d9577a54..5a544332 100644 --- a/source/src/server.h +++ b/source/src/server.h @@ -416,7 +416,7 @@ extern char *maplayout; const char *messagenames[SV_NUM] = { - "SV_SERVINFO", "SV_WELCOME", "SV_INITCLIENT", "SV_POS", "SV_POSC", "SV_POSN", "SV_TEXT", "SV_TEAMTEXT", "SV_TEXTME", "SV_TEAMTEXTME", + "SV_SERVINFO", "SV_WELCOME", "SV_INITCLIENT", "SV_POS", "SV_POSC", "SV_POSN", "SV_TEXT", "SV_TEAMTEXT", "SV_TEXTME", "SV_TEAMTEXTME", "SV_TEXTPRIVATE", "SV_SOUND", "SV_VOICECOM", "SV_VOICECOMTEAM", "SV_CDIS", "SV_SHOOT", "SV_EXPLODE", "SV_SUICIDE", "SV_AKIMBO", "SV_RELOAD", "SV_AUTHT", "SV_AUTHREQ", "SV_AUTHTRY", "SV_AUTHANS", "SV_AUTHCHAL", "SV_GIBDIED", "SV_DIED", "SV_GIBDAMAGE", "SV_DAMAGE", "SV_HITPUSH", "SV_SHOTFX", "SV_THROWNADE",