cl_parsewhitetext (rid#1239249)

non-standard text messages should be much better for use
server voting fix


git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1281 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
TimeServ 2005-09-07 14:55:25 +00:00
parent e671736021
commit a49ca96a5a
8 changed files with 272 additions and 177 deletions

View file

@ -116,6 +116,7 @@ cvar_t cl_item_bobbing = {"cl_model_bobbing", "0"};
cvar_t requiredownloads = {"requiredownloads","1", NULL, CVAR_ARCHIVE}; cvar_t requiredownloads = {"requiredownloads","1", NULL, CVAR_ARCHIVE};
cvar_t cl_standardchat = {"cl_standardchat", "0"}; cvar_t cl_standardchat = {"cl_standardchat", "0"};
cvar_t cl_parsewhitetext = {"cl_parsewhitetext", "0"};
cvar_t host_mapname = {"host_mapname", ""}; cvar_t host_mapname = {"host_mapname", ""};
@ -2411,6 +2412,7 @@ void CL_Init (void)
Cvar_Register (&requiredownloads, cl_controlgroup); Cvar_Register (&requiredownloads, cl_controlgroup);
Cvar_Register (&cl_standardchat, cl_controlgroup); Cvar_Register (&cl_standardchat, cl_controlgroup);
Cvar_Register (&cl_parsewhitetext, cl_controlgroup);
Cvar_Register (&cl_nopext, cl_controlgroup); Cvar_Register (&cl_nopext, cl_controlgroup);
Cvar_Register (&cl_splitscreen, cl_controlgroup); Cvar_Register (&cl_splitscreen, cl_controlgroup);

View file

@ -26,7 +26,7 @@ void CLNQ_ParseDarkPlaces5Entities(void);
void CL_SetStat (int pnum, int stat, int value); void CL_SetStat (int pnum, int stat, int value);
int nq_dp_protocol; int nq_dp_protocol;
int msgflags;
char *svc_strings[] = char *svc_strings[] =
@ -2967,103 +2967,91 @@ void CLQ2_ParseInventory (void)
{ {
int i; int i;
// TODO: finish this properly
for (i=0 ; i<Q2MAX_ITEMS ; i++) for (i=0 ; i<Q2MAX_ITEMS ; i++)
// cl.inventory[i] = MSG_ReadShort (&net_message); // cl.inventory[i] = MSG_ReadShort (&net_message);
MSG_ReadShort (); // just ignore everything for now MSG_ReadShort (); // just ignore everything for now
} }
#endif #endif
int getplayerid(char *msg);
int build_number( void ); int build_number( void );
//return if we want to print the message. //return if we want to print the message.
qboolean CL_ParseChat(char *text) char *CL_ParseChat(char *text, player_info_t **player)
{ {
extern cvar_t cl_chatsound, cl_nofake; extern cvar_t cl_chatsound, cl_nofake;
int flags;
int offset=0;
qboolean suppress_talksound;
char *p;
extern cvar_t cl_parsewhitetext;
char *s; char *s;
s = strchr(text, ':'); //Hmm.. FIXME: Can a player's name contain a ':'?... I think the answer is a yes... Hmmm.. problematic eh?
if (!s || s[1] != ' ') //wasn't a real chat...
return true;
if (!cls.demoplayback) flags = TP_CategorizeMessage (text, &offset, player);
Sys_ServerActivity(); //chat always flashes the screen..
//check f_ stuff s = text + offset;
if (!strncmp(s+2, "f_", 2))
if (flags)
{ {
static float versionresponsetime; if (!cls.demoplayback)
static float modifiedresponsetime; Sys_ServerActivity(); //chat always flashes the screen..
static float skinsresponsetime;
static float serverresponsetime;
if (!strncmp(s+2, "f_version", 9) && versionresponsetime < Sys_DoubleTime()) //respond to it. //check f_ stuff
if (!strncmp(s, "f_", 2))
{ {
ValidationPrintVersion(text); static float versionresponsetime;
versionresponsetime = Sys_DoubleTime() + 5; static float modifiedresponsetime;
static float skinsresponsetime;
static float serverresponsetime;
if (!strncmp(s, "f_version", 9) && versionresponsetime < Sys_DoubleTime()) //respond to it.
{
ValidationPrintVersion(text);
versionresponsetime = Sys_DoubleTime() + 5;
}
else if (!strncmp(s, "f_server", 8) && serverresponsetime < Sys_DoubleTime()) //respond to it.
{
Validation_Server();
serverresponsetime = Sys_DoubleTime() + 5;
}
else if (!strncmp(s, "f_modified", 10) && modifiedresponsetime < Sys_DoubleTime()) //respond to it.
{
Validation_FilesModified();
modifiedresponsetime = Sys_DoubleTime() + 5;
}
else if (!strncmp(s, "f_skins", 7) && skinsresponsetime < Sys_DoubleTime()) //respond to it.
{
Validation_Skins();
skinsresponsetime = Sys_DoubleTime() + 5;
}
return true;
} }
else if (!strncmp(s+2, "f_server", 9) && serverresponsetime < Sys_DoubleTime()) //respond to it.
{
Validation_Server();
serverresponsetime = Sys_DoubleTime() + 5;
}
else if (!strncmp(s+2, "f_modified", 10) && modifiedresponsetime < Sys_DoubleTime()) //respond to it.
{
Validation_FilesModified();
modifiedresponsetime = Sys_DoubleTime() + 5;
}
else if (!strncmp(s+2, "f_skins", 7) && skinsresponsetime < Sys_DoubleTime()) //respond to it.
{
Validation_Skins();
skinsresponsetime = Sys_DoubleTime() + 5;
}
return true;
}
Validation_CheckIfResponse(text); Validation_CheckIfResponse(text);
{
int flags;
int offset=0;
qboolean suppress_talksound;
char *p;
flags = TP_CategorizeMessage (text, &offset);
if (flags == 2 && !TP_FilterMessage(text + offset)) if (flags == 2 && !TP_FilterMessage(text + offset))
return false; return NULL;
suppress_talksound = false;
if (flags == 2 || (!cl.teamplay && flags))
suppress_talksound = TP_CheckSoundTrigger (text + offset);
if (!cl_chatsound.value || // no sound at all
(cl_chatsound.value == 2 && flags != 2)) // only play sound in mm2
suppress_talksound = true;
if (!suppress_talksound)
S_LocalSound ("misc/talk.wav");
if (cl_nofake.value == 1 || (cl_nofake.value == 2 && flags != 2)) {
for (p = s; *p; p++)
if (*p == 13 || (*p == 10 && p[1]))
*p = ' ';
}
//funky /me stuff
p = strchr(text, ':');
if (!strncmp(p, ": /me", 5))
{
//shift name right 1 (for the *)
memmove(text+1, text, p - text);
*text = '*';
memmove(p+1, p+5, strlen(p+5)+1);
}
} }
return true;
suppress_talksound = false;
if (flags == 2 || (!cl.teamplay && flags))
suppress_talksound = TP_CheckSoundTrigger (text + offset);
if (!cl_chatsound.value || // no sound at all
(cl_chatsound.value == 2 && flags != 2)) // only play sound in mm2
suppress_talksound = true;
if (!suppress_talksound)
S_LocalSound ("misc/talk.wav");
if (cl_nofake.value == 1 || (cl_nofake.value == 2 && flags != 2)) {
for (p = s; *p; p++)
if (*p == 13 || (*p == 10 && p[1]))
*p = ' ';
}
msgflags = flags;
return s;
} }
char printtext[4096]; char printtext[4096];
@ -3081,6 +3069,7 @@ void CL_ParsePrint(char *msg, int level)
*msg = '\0'; *msg = '\0';
if (level != PRINT_CHAT) if (level != PRINT_CHAT)
Stats_ParsePrintLine(printtext); Stats_ParsePrintLine(printtext);
TP_SearchForMsgTriggers(printtext, level); TP_SearchForMsgTriggers(printtext, level);
msg++; msg++;
@ -3088,6 +3077,168 @@ void CL_ParsePrint(char *msg, int level)
} }
} }
void CL_PrintChat(player_info_t *plr, char *msg, qboolean team, qboolean observer)
{
char *t;
int c;
int name_ormask;
extern cvar_t cl_parsewhitetext;
qboolean memessage = false;
if (msg[0] == '/' && msg[1] == 'm' && msg[2] == 'e' && msg[3] == ' ')
{
msg += 4;
memessage = true; // special /me formatting
}
if (plr) // use special formatting with a real chat message
{
name_ormask = 0;
if (cl_standardchat.value)
{
name_ormask = CON_STANDARDMASK;
c = 7;
}
else if (observer)
{
// TODO: we don't even check for this yet...
if (team)
c = 0; // blacken () on observers
else
{
name_ormask = CON_STANDARDMASK;
c = 7;
}
}
else if (cl.teamfortress) //override based on team
{
// TODO: needs some work
switch (plr->bottomcolor)
{ //translate q1 skin colours to console colours
case 10:
case 1:
name_ormask = CON_STANDARDMASK;
case 4: //red
c = 1;
break;
case 11:
name_ormask = CON_STANDARDMASK;
case 3: // green
c = 2;
break;
case 5:
name_ormask = CON_STANDARDMASK;
case 12:
c = 3;
break;
case 6:
case 7:
name_ormask = CON_STANDARDMASK;
case 8:
case 9:
c = 5;
break;
case 2: // light blue
name_ormask = CON_STANDARDMASK;
case 13: //blue
case 14: //blue
c = 6;
break;
default:
name_ormask = CON_STANDARDMASK;
case 0: // white
c = 7;
break;
}
}
else
{
//primary override.
t = Info_ValueForKey(plr->userinfo, "tc");
if (*t)
c = atoi(t);
else
c = plr->userid - 1;
if ((c / 7) & 1)
name_ormask = CON_STANDARDMASK;
c = 1 + (c % 7);
}
c = '0' + c;
if (memessage)
{
con_ormask = CON_STANDARDMASK;
if (!cl_standardchat.value && observer)
Con_Printf ("^0*^7 ");
else
Con_Printf ("* ");
}
if (team) // for team chat don't highlight the name, just the brackets
{
// color is reset every printf so we're safe here
con_ormask = name_ormask;
Con_Printf("^%c(", c);
con_ormask = CON_STANDARDMASK;
Con_Printf("%s", plr->name);
con_ormask = name_ormask;
Con_Printf("^%c)", c);
}
else
{
con_ormask = name_ormask;
Con_Printf("^%c%s", c, plr->name);
}
if (!memessage)
{
// only print seperator with an actual player name
con_ormask = CON_STANDARDMASK;
if (!cl_standardchat.value && observer)
Con_Printf ("^0:^7 ");
else
Con_Printf (": ");
}
else
Con_Printf (" ");
}
// print message
con_ormask = CON_STANDARDMASK;
if (cl_parsewhitetext.value && team && plr)
{
char *u;
while (t = strchr(msg, '{'))
{
u = strchr(msg, '}');
if (u)
{
*t = 0;
*u = 0;
Con_Printf("%s", msg);
con_ormask = 0;
Con_Printf("%s", t+1);
con_ormask = CON_STANDARDMASK;
msg = u+1;
}
else
break;
}
Con_Printf("%s", msg);
con_ormask = 0;
}
else
{
Con_Printf ("%s", msg);
}
con_ormask = 0;
}
char stufftext[4096]; char stufftext[4096];
void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from network segregation. void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from network segregation.
{ {
@ -3114,64 +3265,6 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
} }
} }
int getplayerid(char *msg)
{
int i;
int namelen;
char *colon = strstr(msg, ":");
if (!colon)
return -1;
namelen = colon-msg;
for (i=0 ; i<MAX_CLIENTS ; i++)
{
if (!strncmp(msg, cl.players[i].name, namelen))
if (!cl.players[i].name[namelen])
return i;
}
return -1;
}
int CL_PlayerChatColour(int id)
{
char *msg;
int c;
//primary override.
msg = Info_ValueForKey(cl.players[id].userinfo, "tc");
if (*msg)
{
c = atoi(msg);
return c;
}
//override based on team
if (cl.teamfortress)
{
switch (cl.players[id].bottomcolor)
{ //translate q1 skin colours to console colours
case 4: //red
return 1;
case 13: //blue
return 5;
//fixme: add the others
}
}
return cl.players[id].userid;
}
int getplayerchatcolour(char *msg)
{
int id;
id = getplayerid(msg);
if (id == -1) //not a user/server
return 1;
return CL_PlayerChatColour(id);
}
void CL_ParsePrecache(void) void CL_ParsePrecache(void)
{ {
int i = (unsigned short)MSG_ReadShort(); int i = (unsigned short)MSG_ReadShort();
@ -3308,21 +3401,16 @@ void CL_ParseServerMessage (void)
s = MSG_ReadString (); s = MSG_ReadString ();
if (i == PRINT_CHAT) if (i == PRINT_CHAT)
{ {
char *msg;
player_info_t *plr = NULL;
if (TP_SuppressMessage(s)) if (TP_SuppressMessage(s))
break; //if this was unseen-sent from us, ignore it. break; //if this was unseen-sent from us, ignore it.
if (CL_ParseChat(s)) if (msg = CL_ParseChat(s, &plr))
{ {
CL_ParsePrint(s, i); CL_ParsePrint(s, i);
CL_PrintChat(plr, msg, msgflags & 2, msgflags & 4);
if (!cl_standardchat.value)
Con_TPrintf (TL_CSPECIALPRINT, getplayerchatcolour(s)%6+'1', s); //don't ever print it in white.
else
{
con_ormask = CON_STANDARDMASK;
Con_TPrintf (TL_ST, s); //Standard text - makes LEDs work in the ocrana (so I'm told) charset.
con_ormask = 0; //it's a special/wierd characture set.
}
} }
} }
else else
@ -3768,12 +3856,14 @@ void CLQ2_ParseServerMessage (void)
s = MSG_ReadString (); s = MSG_ReadString ();
if (i == PRINT_CHAT) if (i == PRINT_CHAT)
{ {
char *msg;
player_info_t *plr = NULL;
S_LocalSound ("misc/talk.wav"); S_LocalSound ("misc/talk.wav");
con_ormask = CON_2NDCHARSETTEXT; if (msg = CL_ParseChat(s, &plr))
if (CL_ParseChat(s))
{ {
CL_ParsePrint(s, i); CL_ParsePrint(s, i);
Con_TPrintf (TL_CSPECIALPRINT, getplayerchatcolour(s)%6+'1', s); CL_PrintChat(plr, msg, msgflags & 2, msgflags & 4);
} }
} }
else else
@ -3895,15 +3985,19 @@ void CLNQ_ParseServerMessage (void)
s = MSG_ReadString (); s = MSG_ReadString ();
if (*s == 1 || *s == 2) if (*s == 1 || *s == 2)
{ {
if (CL_ParseChat(s+1)) char *msg;
player_info_t *plr = NULL;
if (msg = CL_ParseChat(s+1, &plr))
{ {
CL_ParsePrint(s+1, 3); CL_ParsePrint(s+1, PRINT_CHAT);
Con_Printf ("^3%s", Translate(s+1)); CL_PrintChat(plr, msg, msgflags & 2, msgflags & 4);
} }
} }
else else
{ {
CL_ParsePrint(s, 3); CL_ParsePrint(s, PRINT_HIGH);
Con_TPrintf (TL_ST, Translate(s)); Con_TPrintf (TL_ST, Translate(s));
} }
con_ormask = 0; con_ormask = 0;

View file

@ -842,7 +842,7 @@ char *TP_PlayerTeam (void);
char *TP_EnemyTeam (void); char *TP_EnemyTeam (void);
char *TP_EnemyName (void); char *TP_EnemyName (void);
void TP_StatChanged (int stat, int value); void TP_StatChanged (int stat, int value);
int TP_CategorizeMessage (char *s, int *offset); int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr);
void TP_NewMap (void); void TP_NewMap (void);
qboolean TP_FilterMessage (char *s); qboolean TP_FilterMessage (char *s);
qboolean TP_CheckSoundTrigger (char *str); qboolean TP_CheckSoundTrigger (char *str);

View file

@ -1917,14 +1917,17 @@ returns a combination of these values:
1 -- normal 1 -- normal
2 -- team message 2 -- team message
4 -- spectator 4 -- spectator
16 -- faked or serverside
Note that sometimes we can't be sure who really sent the message, Note that sometimes we can't be sure who really sent the message,
e.g. when there's a player "unnamed" in your team and "(unnamed)" e.g. when there's a player "unnamed" in your team and "(unnamed)"
in the enemy team. The result will be 3 (1+2) in the enemy team. The result will be 3 (1+2)
Never returns 2 if we are a spectator. Never returns 2 if we are a spectator.
Now additionally returns player info (NULL if no player detected)
====================== ======================
*/ */
int TP_CategorizeMessage (char *s, int *offset) int TP_CategorizeMessage (char *s, int *offset, player_info_t **plr)
{ {
int i, msglen, len; int i, msglen, len;
int flags; int flags;
@ -1937,6 +1940,7 @@ int TP_CategorizeMessage (char *s, int *offset)
return 0; return 0;
*offset = 0; *offset = 0;
*plr = NULL;
for (i=0, player=cl.players ; i < MAX_CLIENTS ; i++, player++) for (i=0, player=cl.players ; i < MAX_CLIENTS ; i++, player++)
{ {
@ -1953,9 +1957,10 @@ int TP_CategorizeMessage (char *s, int *offset)
else else
flags |= 1; flags |= 1;
*offset = len + 2; *offset = len + 2;
*plr = player;
} }
// check messagemode2 // check messagemode2
else if (s[0] == '(' && !cl.spectator && len+4 <= msglen && else if (s[0] == '(' && len+4 <= msglen && !cl.spectator &&
!strncmp(s+len+1, "): ", 3) && !strncmp(s+len+1, "): ", 3) &&
!strncmp(name, s+1, len)) !strncmp(name, s+1, len))
{ {
@ -1963,7 +1968,18 @@ int TP_CategorizeMessage (char *s, int *offset)
if (i == cl.playernum[SP] || ( cl.teamplay && if (i == cl.playernum[SP] || ( cl.teamplay &&
!strcmp(cl.players[cl.playernum[SP]].team, player->team)) ) !strcmp(cl.players[cl.playernum[SP]].team, player->team)) )
flags |= 2; flags |= 2;
*offset = len + 4; *offset = len + 4;
*plr = player;
}
}
if (!flags)
{
if (name = strstr(s, ": ")) // use name as temp
{
*offset = (name - s) + 2;
flags = 16;
} }
} }
@ -3212,22 +3228,8 @@ void CL_Say (qboolean team, char *extra)
} }
*d = '\0'; *d = '\0';
CL_PrintChat(&cl.players[cl.playernum[SP]], text, team, false);
if (!cl_standardchat.value)
colouration = CL_PlayerChatColour(cl.playernum[SP])%6+'1'; //don't ever print it in white.
else
{
con_ormask = CON_STANDARDMASK;
colouration = '7';
}
if (team)
Con_Printf("^%c(%s): %s\n", colouration, cl.players[cl.playernum[SP]].name, text);
else
Con_Printf("^%c%s: %s\n", colouration, cl.players[cl.playernum[SP]].name, text);
con_ormask = 0;
//strip out the extra markup //strip out the extra markup
for (s = sendtext, d = sendtext; *s; s++, d++) for (s = sendtext, d = sendtext; *s; s++, d++)
{ {

View file

@ -266,7 +266,6 @@ static char *defaultlanguagetext =
"TL_FILE_X_MISSING \"\\nThe required model file '%s' could not be found or downloaded.\\n\\n\"\n" "TL_FILE_X_MISSING \"\\nThe required model file '%s' could not be found or downloaded.\\n\\n\"\n"
"TL_GETACLIENTPACK \"You may need to download or purchase a %s client or map pack in order to play on this server.\\n\\n\"\n" "TL_GETACLIENTPACK \"You may need to download or purchase a %s client or map pack in order to play on this server.\\n\\n\"\n"
"TLC_LINEBREAK_MINUS \"------------------\\n\"\n" "TLC_LINEBREAK_MINUS \"------------------\\n\"\n"
"TL_CSPECIALPRINT \"^%c%s\"\n"
"TL_INT_SPACE \"%i \"\n" "TL_INT_SPACE \"%i \"\n"
; ;

View file

@ -310,7 +310,6 @@
NAME(TL_FILE_X_MISSING) NAME(TL_FILE_X_MISSING)
NAME(TL_GETACLIENTPACK) NAME(TL_GETACLIENTPACK)
NAME(TLC_LINEBREAK_MINUS) NAME(TLC_LINEBREAK_MINUS)
NAME(TL_CSPECIALPRINT)
NAME(TL_INT_SPACE) NAME(TL_INT_SPACE)
#else #else

View file

@ -2456,6 +2456,7 @@ void SV_Vote_f (void)
VoteRemoveCommands(command, -1); VoteRemoveCommands(command, -1);
Cbuf_AddText(command, votelevel.value); Cbuf_AddText(command, votelevel.value);
Cbuf_AddText("\n", votelevel.value);
//Cmd_ExecuteString (command, votelevel.value); //Cmd_ExecuteString (command, votelevel.value);
return; return;
} }

View file

@ -413,6 +413,7 @@ qboolean VARGS PFQ2_AreasConnected(int area1, int area2)
#define Q2CHAN_VOICE 2 #define Q2CHAN_VOICE 2
#define Q2CHAN_ITEM 3 #define Q2CHAN_ITEM 3
#define Q2CHAN_BODY 4*/ #define Q2CHAN_BODY 4*/
#define Q2CHAN_NO_PHS_ADD 8
#define Q2CHAN_RELIABLE 16 #define Q2CHAN_RELIABLE 16
void VARGS SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel, void VARGS SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
@ -440,11 +441,8 @@ void VARGS SVQ2_StartSound (vec3_t origin, q2edict_t *entity, int channel,
ent = Q2NUM_FOR_EDICT(entity); ent = Q2NUM_FOR_EDICT(entity);
if (channel & 8) // no PHS flag if (channel & Q2CHAN_NO_PHS_ADD) // no PHS flag
{
use_phs = false; use_phs = false;
channel &= 7;
}
else else
use_phs = true; use_phs = true;