46
45
const char *format, ...)
47
46
fc__attribute((__format__ (__printf__, 4, 5)));
48
/****************************************************************************
49
Returns whether 'dest' is ignoring the 'sender' connection.
50
****************************************************************************/
51
static inline bool conn_is_ignored(const struct connection *sender,
52
const struct connection *dest)
54
if (NULL != sender && NULL != dest) {
55
return conn_pattern_list_match(dest->server.ignore_list, sender);
49
61
/**************************************************************************
50
62
Formulate a name for this connection, prefering the player name when
51
63
available and unambiguous (since this is the "standard" case), else
60
72
|| strcmp(player_name(pplayer), ANON_PLAYER_NAME) == 0) {
61
my_snprintf(buffer, len, "(%s)", pconn->username);
73
fc_snprintf(buffer, len, "(%s)", pconn->username);
63
my_snprintf(buffer, len, "%s", player_name(pplayer));
75
fc_snprintf(buffer, len, "%s", player_name(pplayer));
103
115
notify_conn(pconn->self, NULL, E_CHAT_ERROR, ftc_server,
104
_("%s is an anonymous name. Use connection name"), name);
116
_("%s is an anonymous name. Use connection name."), name);
119
log_error("Unkown variant in %s(): %d.", __FUNCTION__, player_conn);
115
127
struct connection *dest, char *msg)
117
129
char sender_name[MAX_LEN_CHAT_NAME], dest_name[MAX_LEN_CHAT_NAME];
119
msg = skip_leading_spaces(msg);
121
form_chat_name(sender, sender_name, sizeof(sender_name));
122
131
form_chat_name(dest, dest_name, sizeof(dest_name));
133
if (conn_is_ignored(sender, dest)) {
134
send_chat_msg(sender, NULL, ftc_warning,
135
_("You cannot send messages to %s; you are ignored."),
140
msg = skip_leading_spaces(msg);
141
form_chat_name(sender, sender_name, sizeof(sender_name));
124
143
send_chat_msg(sender, sender, ftc_chat_private,
125
144
"->*%s* %s", dest_name, msg);
144
163
msg = skip_leading_spaces(msg);
145
164
form_chat_name(sender, sender_name, sizeof(sender_name));
166
/* Find the user of the player 'pdest'. */
167
conn_list_iterate(pdest->connections, pconn) {
168
if (!pconn->observer) {
170
if (conn_is_ignored(sender, pconn)) {
171
send_chat_msg(sender, NULL, ftc_warning,
172
_("You cannot send messages to %s; you are ignored."),
174
return; /* NB: stop here, don't send to observers. */
179
} conn_list_iterate_end;
147
181
/* Repeat the message for the sender. */
148
182
send_chat_msg(sender, sender, ftc_chat_private,
149
183
"->{%s} %s", player_name(pdest), msg);
151
185
/* Send the message to destination. */
152
conn_list_iterate(pdest->connections, pconn) {
153
if (!pconn->observer) {
154
/* Found the real player connection! */
156
if (dest != sender) {
157
send_chat_msg(dest, sender, ftc_chat_private,
158
"{%s} %s", sender_name, msg);
162
} conn_list_iterate_end;
186
if (NULL != dest && dest != sender) {
187
send_chat_msg(dest, sender, ftc_chat_private,
188
"{%s} %s", sender_name, msg);
164
191
/* Send the message to player observers. */
165
192
package_chat_msg(&packet, sender, ftc_chat_private,
166
193
"{%s -> %s} %s", sender_name, player_name(pdest), msg);
167
194
conn_list_iterate(pdest->connections, pconn) {
168
if (pconn != dest && pconn != sender) {
197
&& !conn_is_ignored(sender, pconn)) {
169
198
send_packet_chat_msg(pconn, &packet);
171
200
} conn_list_iterate_end;
174
203
&& sender->playing != pdest) {
175
204
/* The sender is another player. */
176
205
conn_list_iterate(sender->playing->connections, pconn) {
177
if (pconn != sender) {
206
if (pconn != sender && !conn_is_ignored(sender, pconn)) {
178
207
send_packet_chat_msg(pconn, &packet);
180
209
} conn_list_iterate_end;
209
lsend_packet_chat_msg(aplayer->connections, &packet);
238
conn_list_iterate(aplayer->connections, pconn) {
239
if (!conn_is_ignored(sender, pconn)) {
240
send_packet_chat_msg(pconn, &packet);
242
} conn_list_iterate_end;
210
243
players = event_cache_player_add(players, aplayer);
211
244
} players_iterate_end;
230
263
_("%s to global observers: %s"), sender_name, msg);
232
265
conn_list_iterate(game.est_connections, dest_conn) {
233
if (conn_is_global_observer(dest_conn)) {
266
if (conn_is_global_observer(dest_conn)
267
&& !conn_is_ignored(sender, dest_conn)) {
234
268
send_packet_chat_msg(dest_conn, &packet);
236
270
} conn_list_iterate_end;
282
316
avoiding sending both original and echo if sender is in destination
284
318
**************************************************************************/
285
void handle_chat_msg_req(struct connection *pconn, char *message)
319
void handle_chat_msg_req(struct connection *pconn, const char *message)
321
char real_message[MAX_LEN_MSG], *cp;
288
322
bool double_colon;
290
/* this loop to prevent players from sending multiple lines
291
* which can be abused */
292
for (cp = message; *cp != '\0'; cp++) {
324
sz_strlcpy(real_message, message);
326
/* This loop to prevent players from sending multiple lines which can
328
for (cp = real_message; *cp != '\0'; cp++) {
293
329
if (*cp == '\n' || *cp == '\r') {
302
338
So consider this an incentive for IRC support,
303
339
or change it in stdinhand.h - rp
305
if (message[0] == SERVER_COMMAND_PREFIX) {
341
if (real_message[0] == SERVER_COMMAND_PREFIX) {
306
342
/* pass it to the command parser, which will chop the prefix off */
307
(void) handle_stdin_input(pconn, message, FALSE);
343
(void) handle_stdin_input(pconn, real_message, FALSE);
311
347
/* Send to allies command */
312
if (message[0] == ALLIESCHAT_COMMAND_PREFIX) {
348
if (real_message[0] == ALLIESCHAT_COMMAND_PREFIX) {
313
349
/* this won't work if we aren't attached to a player */
314
350
if (NULL == pconn->playing && !pconn->observer) {
315
351
notify_conn(pconn->self, NULL, E_CHAT_ERROR, ftc_server,
320
356
if (NULL != pconn->playing) {
321
chat_msg_to_allies(pconn, message + 1);
357
chat_msg_to_allies(pconn, real_message + 1);
323
chat_msg_to_global_observers(pconn, message + 1);
359
chat_msg_to_global_observers(pconn, real_message + 1);
348
384
else complain (might be a typo-ed intended private message)
351
cp=strchr(message, ':');
387
cp = strchr(real_message, ':');
353
if (cp && (cp != &message[0])) {
389
if (cp && (cp != &real_message[0])) {
354
390
enum m_pre_result match_result_player, match_result_conn;
355
391
struct player *pdest = NULL;
356
392
struct connection *conn_dest = NULL;
357
393
char name[MAX_LEN_NAME];
360
(void) mystrlcpy(name, message,
361
MIN(sizeof(name), cp - message + 1));
396
(void) fc_strlcpy(name, real_message, MIN(sizeof(name),
397
cp - real_message + 1));
363
399
double_colon = (*(cp+1) == ':');
364
400
if (double_colon) {
365
conn_dest = find_conn_by_user_prefix(name, &match_result_conn);
401
conn_dest = conn_by_user_prefix(name, &match_result_conn);
366
402
if (match_result_conn == M_PRE_AMBIGUOUS) {
367
403
complain_ambiguous(pconn, name, 1);
375
411
/* single colon */
376
pdest = find_player_by_name_prefix(name, &match_result_player);
412
pdest = player_by_name_prefix(name, &match_result_player);
377
413
if (match_result_player == M_PRE_AMBIGUOUS) {
378
414
complain_ambiguous(pconn, name, 0);
388
424
/* else try for connection name match before complaining */
390
conn_dest = find_conn_by_user_prefix(name, &match_result_conn);
426
conn_dest = conn_by_user_prefix(name, &match_result_conn);
391
427
if (match_result_conn == M_PRE_AMBIGUOUS) {
392
428
complain_ambiguous(pconn, name, 1);
406
442
/* Didn't match; check heuristics to see if this is likely
407
443
* to be a global message
409
cpblank=strchr(message, ' ');
445
cpblank = strchr(real_message, ' ');
410
446
if (!cpblank || (cp < cpblank)) {
411
447
if (double_colon) {
412
448
notify_conn(pconn->self, NULL, E_CHAT_ERROR, ftc_server,