/[LeafOK_CVS]/pvpgn-1.7.4/src/bnetd/message.c
ViewVC logotype

Contents of /pvpgn-1.7.4/src/bnetd/message.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.2 - (show annotations)
Sat Jun 10 16:20:33 2006 UTC (19 years, 9 months ago) by sysadm
Branch: MAIN
CVS Tags: pvpgn_1-7-4-0_MIL, HEAD
Changes since 1.1: +18 -0 lines
Content type: text/x-csrc
Error occurred while calculating annotation data.
Antibot

1 /*
2 * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu)
3 * Copyright (C) 1998,1999,2001,2002 Ross Combs (rocombs@cs.nmsu.edu)
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version 2
8 * of the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18 */
19 #define MESSAGE_INTERNAL_ACCESS
20 #include "common/setup_before.h"
21 #include <stdio.h>
22 #ifdef HAVE_STDDEF_H
23 # include <stddef.h>
24 #else
25 # ifndef NULL
26 # define NULL ((void *)0)
27 # endif
28 #endif
29 #ifdef STDC_HEADERS
30 # include <stdlib.h>
31 #else
32 # ifdef HAVE_MALLOC_H
33 # include <malloc.h>
34 # endif
35 #endif
36 #ifdef HAVE_STRING_H
37 # include <string.h>
38 #else
39 # ifdef HAVE_STRINGS_H
40 # include <strings.h>
41 # endif
42 #endif
43 #include "compat/strdup.h"
44 #ifdef HAVE_UNISTD_H
45 # include <unistd.h>
46 #endif
47 #include "compat/gethostname.h"
48 #include <errno.h>
49 #include "compat/strerror.h"
50 #include "connection.h"
51 #include "common/bn_type.h"
52 #include "common/queue.h"
53 #include "common/packet.h"
54 #include "common/bot_protocol.h"
55 #include "common/bnet_protocol.h"
56 #include "common/field_sizes.h"
57 #include "common/eventlog.h"
58 #include "common/list.h"
59 #include "common/util.h"
60 #include "common/version.h"
61 #include "common/addr.h"
62 #include "account.h"
63 #include "account_wrap.h"
64 #include "game.h"
65 #include "channel.h"
66 #include "channel_conv.h"
67 #include "command.h"
68 #include "irc.h"
69 #include "message.h"
70 #include "mail.h"
71 #include "prefs.h"
72 #include "common/tag.h"
73 #include "common/xalloc.h"
74 #include "common/setup_after.h"
75
76 static int message_telnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);
77 static int message_bot_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);
78 static int message_bnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);
79 static t_packet * message_cache_lookup(t_message * message, t_connection *dst, unsigned int flags);
80
81 static char const * message_type_get_str(t_message_type type)
82 {
83 switch (type)
84 {
85 case message_type_adduser:
86 return "adduser";
87 case message_type_join:
88 return "join";
89 case message_type_part:
90 return "part";
91 case message_type_whisper:
92 return "whisper";
93 case message_type_talk:
94 return "talk";
95 case message_type_broadcast:
96 return "broadcast";
97 case message_type_channel:
98 return "channel";
99 case message_type_userflags:
100 return "userflags";
101 case message_type_whisperack:
102 return "whisperack";
103 case message_type_friendwhisperack: //[zap-zero] 20020518
104 return "friendwhisperack";
105 case message_type_channelfull:
106 return "channelfull";
107 case message_type_channeldoesnotexist:
108 return "channeldoesnotexist";
109 case message_type_channelrestricted:
110 return "channelrestricted";
111 case message_type_info:
112 return "info";
113 case message_type_error:
114 return "error";
115 case message_type_emote:
116 return "emote";
117 case message_type_uniqueid:
118 return "uniqueid";
119 case message_type_mode:
120 return "mode";
121 case message_type_null:
122 return "null";
123 default:
124 return "UNKNOWN";
125 }
126 }
127
128
129 /* make sure none of the expanded format symbols is longer than this (with null) */
130 #define MAX_INC 64
131
132 extern char * message_format_line(t_connection const * c, char const * in)
133 {
134 char * out;
135 unsigned int inpos;
136 unsigned int outpos;
137 unsigned int outlen=MAX_INC;
138 unsigned int inlen;
139 char clienttag_str[5];
140
141 out = xmalloc(outlen+1);
142
143 inlen = strlen(in);
144 out[0] = 'I';
145 for (inpos=0,outpos=1; inpos<inlen; inpos++)
146 {
147 if (in[inpos]!='%')
148 {
149 out[outpos] = in[inpos];
150 outpos += 1;
151 }
152 else
153 switch (in[++inpos])
154 {
155 case '%':
156 out[outpos++] = '%';
157 break;
158
159 case 'a':
160 sprintf(&out[outpos],"%u",accountlist_get_length());
161 outpos += strlen(&out[outpos]);
162 break;
163
164 case 'c':
165 sprintf(&out[outpos],"%d",channellist_get_length());
166 outpos += strlen(&out[outpos]);
167 break;
168
169 case 'g':
170 sprintf(&out[outpos],"%d",gamelist_get_length());
171 outpos += strlen(&out[outpos]);
172 break;
173
174 case 'h':
175 if (gethostname(&out[outpos],MAX_INC)<0)
176 {
177 eventlog(eventlog_level_error,__FUNCTION__,"could not get hostname (gethostname: %s)",pstrerror(errno));
178 strcpy(&out[outpos],"localhost"); /* not much else you can do */
179 }
180 outpos += strlen(&out[outpos]);
181 break;
182
183 case 'i':
184 sprintf(&out[outpos],UID_FORMAT,conn_get_userid(c));
185 outpos += strlen(&out[outpos]);
186 break;
187
188 case 'l':
189 {
190 char const * tname;
191
192 strncpy(&out[outpos],(tname = (conn_get_chatname(c)?conn_get_chatname(c):conn_get_loggeduser(c))),USER_NAME_MAX-1);
193 conn_unget_chatname(c,tname);
194 }
195 out[outpos+USER_NAME_MAX-1] = '\0';
196 outpos += strlen(&out[outpos]);
197 break;
198
199 case 'm':
200 sprintf(&out[outpos],"%s",check_mail(c));
201 outpos += strlen(&out[outpos]);
202 break;
203
204 case 'r':
205 strncpy(&out[outpos],addr_num_to_ip_str(conn_get_addr(c)),MAX_INC-1);
206 out[outpos+MAX_INC-1] = '\0';
207 outpos += strlen(&out[outpos]);
208 break;
209
210 case 't':
211 sprintf(&out[outpos],"%s",tag_uint_to_str(clienttag_str,conn_get_clienttag(c)));
212 outpos += strlen(&out[outpos]);
213 break;
214
215 case 'u':
216 sprintf(&out[outpos],"%d",connlist_login_get_length());
217 outpos += strlen(&out[outpos]);
218 break;
219
220 case 'v':
221 strcpy(&out[outpos],PVPGN_SOFTWARE" "PVPGN_VERSION);
222 outpos += strlen(&out[outpos]);
223 break;
224
225 case 'C': /* simulated command */
226 out[0] = 'C';
227 break;
228
229 case 'B': /* BROADCAST */
230 out[0] = 'B';
231 break;
232
233 case 'E': /* ERROR */
234 out[0] = 'E';
235 break;
236
237 case 'G':
238 sprintf(&out[outpos],"%d",game_get_count_by_clienttag(conn_get_clienttag(c)));
239 outpos += strlen(&out[outpos]);
240 break;
241
242 case 'H':
243 strcpy(&out[outpos],prefs_get_contact_name());
244 outpos += strlen(&out[outpos]);
245 break;
246
247 case 'I': /* INFO */
248 out[0] = 'I';
249 break;
250
251 case 'M': /* MESSAGE */
252 out[0] = 'M';
253 break;
254
255 case 'N':
256 strcpy(&out[outpos],clienttag_get_title(conn_get_clienttag(c)));
257 outpos += strlen(&out[outpos]);
258 break;
259
260 case 'T': /* EMOTE */
261 out[0] = 'T';
262 break;
263
264 case 'U':
265 sprintf(&out[outpos],"%d",conn_get_user_count_by_clienttag(conn_get_clienttag(c)));
266 outpos += strlen(&out[outpos]);
267 break;
268
269 case 'W': /* INFO */
270 out[0] = 'W';
271 break;
272
273 default:
274 eventlog(eventlog_level_warn,__FUNCTION__,"bad formatter \"%%%c\"",in[inpos-1]);
275 }
276
277 if ((outpos+MAX_INC)>=outlen)
278 {
279 char * newout;
280
281 outlen += MAX_INC;
282 newout = xrealloc(out,outlen);
283 out = newout;
284 }
285 }
286 out[outpos] = '\0';
287
288 return out;
289 }
290
291
292 static int message_telnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags)
293 {
294 char * msgtemp;
295
296 if (!packet)
297 {
298 eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
299 return -1;
300 }
301
302 switch (type)
303 {
304 case message_type_uniqueid:
305 if (!text)
306 {
307 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
308 return -1;
309 }
310 msgtemp = xmalloc(strlen(text)+32);
311 sprintf(msgtemp,"Your unique name: %s\r\n",text);
312 break;
313 case message_type_adduser:
314 if (!me)
315 {
316 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
317 return -1;
318 }
319 {
320 char const * tname;
321
322 tname = conn_get_chatcharname(me, dst);
323 msgtemp = xmalloc(strlen(tname)+32);
324 sprintf(msgtemp,"[%s is here]\r\n",tname);
325 conn_unget_chatcharname(me,tname);
326 }
327 break;
328 case message_type_join:
329 if (!me)
330 {
331 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
332 return -1;
333 }
334 {
335 char const * tname;
336
337 tname = conn_get_chatcharname(me, dst);
338 msgtemp = xmalloc(strlen(tname)+32);
339 sprintf(msgtemp,"[%s enters]\r\n",tname);
340 conn_unget_chatcharname(me,tname);
341 }
342 break;
343 case message_type_part:
344 if (!me)
345 {
346 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
347 return -1;
348 }
349 {
350 char const * tname;
351
352 tname = conn_get_chatcharname(me, dst);
353 msgtemp = xmalloc(strlen(tname)+32);
354 sprintf(msgtemp,"[%s leaves]\r\n",tname);
355 conn_unget_chatcharname(me,tname);
356 }
357 break;
358 case message_type_whisper:
359 if (!me)
360 {
361 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
362 return -1;
363 }
364 if (!text)
365 {
366 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
367 return -1;
368 }
369 if (dstflags&MF_X)
370 return -1; /* player is ignored */
371 {
372 char const * tname;
373 char const * newtext;
374
375 tname = conn_get_chatcharname(me, dst);
376 if ((newtext = escape_chars(text,strlen(text))))
377 {
378 msgtemp = xmalloc(strlen(tname)+8+strlen(newtext)+4);
379 sprintf(msgtemp,"<from %s> %s\r\n",tname,newtext);
380 xfree((void *)newtext); /* avoid warning */
381 }
382 else
383 {
384 msgtemp = xmalloc(16+strlen(tname));
385 sprintf(msgtemp,"<from %s> \r\n",tname);
386 }
387 conn_unget_chatcharname(me,tname);
388 }
389 break;
390 case message_type_talk:
391 if (!me)
392 {
393 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
394 return -1;
395 }
396 if (!text)
397 {
398 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
399 return -1;
400 }
401 if (dstflags&MF_X)
402 return -1; /* player is ignored */
403 {
404 char const * tname;
405 char const * newtext;
406
407 tname = conn_get_chatcharname(me, me); /* FIXME: second should be dst but cache gets in the way */
408 if ((newtext = escape_chars(text,strlen(text))))
409 {
410 msgtemp = xmalloc(strlen(tname)+4+strlen(newtext)+4);
411 sprintf(msgtemp,"<%s> %s\r\n",tname,newtext);
412 xfree((void *)newtext); /* avoid warning */
413 }
414 else
415 {
416 msgtemp = xmalloc(strlen(tname)+8);
417 sprintf(msgtemp,"<%s> \r\n",tname);
418 }
419 conn_unget_chatcharname(me,tname);
420 }
421 break;
422 case message_type_broadcast:
423 if (!text)
424 {
425 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
426 return -1;
427 }
428 if (dstflags&MF_X)
429 return -1; /* player is ignored */
430 {
431 char const * newtext;
432
433 if ((newtext = escape_chars(text,strlen(text))))
434 {
435 msgtemp = xmalloc(16+strlen(newtext)+4);
436 sprintf(msgtemp,"Broadcast: %s\r\n",newtext); /* FIXME: show source? */
437 xfree((void *)newtext); /* avoid warning */
438 }
439 else
440 {
441 msgtemp = xmalloc(16);
442 sprintf(msgtemp,"Broadcast: \r\n"); /* FIXME: show source? */
443 }
444 }
445 break;
446 case message_type_channel:
447 if (!text)
448 {
449 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
450 return -1;
451 }
452 msgtemp = xmalloc(strlen(text)+32);
453 sprintf(msgtemp,"Joining channel: \"%s\"\r\n",text);
454 break;
455 case message_type_userflags:
456 if (!me)
457 {
458 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
459 return -1;
460 }
461 msgtemp = xstrdup("");
462 break;
463 case message_type_whisperack:
464 if (!me)
465 {
466 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
467 return -1;
468 }
469 if (!text)
470 {
471 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
472 return -1;
473 }
474 {
475 char const * tname;
476 char const * newtext;
477
478 tname = conn_get_chatcharname(me, dst);
479 if ((newtext = escape_chars(text,strlen(text))))
480 {
481 msgtemp = xmalloc(strlen(tname)+8+strlen(newtext)+4);
482 sprintf(msgtemp,"<to %s> %s\r\n",tname,newtext);
483 xfree((void *)newtext); /* avoid warning */
484 }
485 else
486 {
487 msgtemp = xmalloc(strlen(tname)+8+strlen(text)+4);
488 sprintf(msgtemp,"<to %s> %s\r\n",tname,text);
489 }
490 conn_unget_chatcharname(me,tname);
491 }
492 break;
493 case message_type_friendwhisperack: // [zap-zero] 20020518
494 if (!me)
495 {
496 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
497 return -1;
498 }
499 if (!text)
500 {
501 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
502 return -1;
503 }
504 {
505 char const * newtext;
506
507 if ((newtext = escape_chars(text,strlen(text))))
508 {
509 msgtemp = xmalloc(14+8+strlen(newtext)+4);
510 sprintf(msgtemp,"<to your friends> %s\r\n",newtext);
511 xfree((void *)newtext); /* avoid warning */
512 }
513 else
514 {
515 msgtemp = xmalloc(14+8+strlen(text)+4);
516 sprintf(msgtemp,"<to your friends> %s\r\n",text);
517 }
518 }
519 break;
520
521 case message_type_channelfull:
522 /* FIXME */
523 msgtemp = xstrdup("");
524 break;
525 case message_type_channeldoesnotexist:
526 /* FIXME */
527 msgtemp = xstrdup("");
528 break;
529 case message_type_channelrestricted:
530 /* FIXME */
531 msgtemp = xstrdup("");
532 break;
533 case message_type_info:
534 if (!text)
535 {
536 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
537 return -1;
538 }
539 {
540 char const * newtext;
541
542 if ((newtext = escape_chars(text,strlen(text))))
543 {
544 msgtemp = xmalloc(strlen(newtext)+4);
545 sprintf(msgtemp,"%s\r\n",newtext);
546 xfree((void *)newtext); /* avoid warning */
547 }
548 else
549 {
550 msgtemp = xmalloc(strlen(text)+4);
551 sprintf(msgtemp,"%s\r\n",text);
552 }
553 }
554 break;
555 case message_type_error:
556 if (!text)
557 {
558 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
559 return -1;
560 }
561 {
562 char const * newtext;
563
564 if ((newtext = escape_chars(text,strlen(text))))
565 {
566 msgtemp = xmalloc(8+strlen(newtext)+4);
567 sprintf(msgtemp,"ERROR: %s\r\n",newtext);
568 xfree((void *)newtext); /* avoid warning */
569 }
570 else
571 {
572 msgtemp = xmalloc(8+strlen(text)+4);
573 sprintf(msgtemp,"ERROR: %s\r\n",text);
574 }
575 }
576 break;
577 case message_type_emote:
578 if (!me)
579 {
580 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
581 return -1;
582 }
583 if (!text)
584 {
585 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
586 return -1;
587 }
588 if (dstflags&MF_X)
589 return -1; /* player is ignored */
590 {
591 char const * tname;
592 char const * newtext;
593
594 tname = conn_get_chatcharname(me, me); /* FIXME: second should be dst but cache gets in the way */
595 if ((newtext = escape_chars(text,strlen(text))))
596 {
597 msgtemp = xmalloc(strlen(tname)+4+strlen(newtext)+4);
598 sprintf(msgtemp,"<%s %s>\r\n",tname,newtext);
599 xfree((void *)newtext); /* avoid warning */
600 }
601 else
602 {
603 msgtemp = xmalloc(strlen(tname)+4+strlen(text)+4);
604 sprintf(msgtemp,"<%s %s>\r\n",tname,text);
605 }
606 conn_unget_chatcharname(me,tname);
607 }
608 break;
609 case message_type_mode:
610 if (!me)
611 {
612 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
613 return -1;
614 }
615 {
616 char const * tname;
617
618 tname = conn_get_chatcharname(me,dst);
619 msgtemp = xmalloc(strlen(tname)+32);
620 sprintf(msgtemp,"%s change mode: %s\r\n",tname,text);
621 conn_unget_chatcharname(me,tname);
622 }
623 default:
624 eventlog(eventlog_level_error,__FUNCTION__,"got bad message type %d",(int)type);
625 return -1;
626 }
627
628 {
629 int retval;
630
631 retval = packet_append_ntstring(packet,msgtemp);
632 xfree(msgtemp);
633 return retval;
634 }
635 }
636
637
638 static int message_bot_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags)
639 {
640 char * msgtemp;
641 char clienttag_str[5];
642
643 if (!packet)
644 {
645 eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
646 return -1;
647 }
648
649 /* special-case the login banner so it doesn't have numbers
650 * at the start of each line
651 */
652 if (me &&
653 conn_get_state(me)!=conn_state_loggedin &&
654 conn_get_state(me)!=conn_state_destroy &&
655 type!=message_type_null) /* this does not apply for NULL messages */
656 {
657 if (!text)
658 {
659 #if 0
660 /* battle.net actually sends them during login */
661 if (type==message_type_null)
662 return 0; /* don't display null messages during the login */
663 #endif
664 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for non-loggedin state");
665 return -1;
666 }
667 msgtemp = xmalloc(strlen(text)+4);
668 sprintf(msgtemp,"%s\r\n",text);
669 }
670 else
671 switch (type)
672 {
673 case message_type_null:
674 msgtemp = xmalloc(32);
675 sprintf(msgtemp,"%u %s\r\n",EID_NULL,"NULL");
676 break;
677 case message_type_uniqueid: /* FIXME: need to send this for some bots, also needed to support guest accounts */
678 if (!text)
679 {
680 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
681 return -1;
682 }
683 msgtemp = xmalloc(strlen(text)+32);
684 sprintf(msgtemp,"%u %s %s\r\n",EID_UNIQUENAME,"NAME",text);
685 break;
686 case message_type_adduser:
687 if (!me)
688 {
689 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
690 return -1;
691 }
692 {
693 char const * tname;
694
695 tname = conn_get_chatcharname(me, dst);
696 msgtemp = xmalloc(32+strlen(tname)+32);
697 sprintf(msgtemp,"%u %s %s %04x [%s]\r\n",EID_SHOWUSER,"USER",tname,conn_get_flags(me)|dstflags,tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(me)));
698 conn_unget_chatcharname(me,tname);
699 }
700 break;
701 case message_type_join:
702 if (!me)
703 {
704 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
705 return -1;
706 }
707 {
708 char const * tname;
709
710 tname = conn_get_chatcharname(me, dst);
711 msgtemp = xmalloc(32+strlen(tname)+32);
712 sprintf(msgtemp,"%u %s %s %04x [%s]\r\n",EID_JOIN,"JOIN",tname,conn_get_flags(me)|dstflags,tag_uint_to_str(clienttag_str,conn_get_fake_clienttag(me)));
713 conn_unget_chatcharname(me,tname);
714 }
715 break;
716 case message_type_part:
717 if (!me)
718 {
719 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
720 return -1;
721 }
722 {
723 char const * tname;
724
725 tname = conn_get_chatcharname(me, dst);
726 msgtemp = xmalloc(32+strlen(tname)+32);
727 sprintf(msgtemp,"%u %s %s %04x\r\n",EID_LEAVE,"LEAVE",tname,conn_get_flags(me)|dstflags);
728 conn_unget_chatcharname(me,tname);
729 }
730 break;
731 case message_type_whisper:
732 if (!me)
733 {
734 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
735 return -1;
736 }
737 if (!text)
738 {
739 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
740 return -1;
741 }
742 if (dstflags&MF_X)
743 return -1; /* player is ignored */
744 {
745 char const * tname;
746
747 tname = conn_get_chatcharname(me, dst);
748 msgtemp = xmalloc(32+strlen(tname)+32+strlen(text));
749 sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_WHISPER,"WHISPER",tname,conn_get_flags(me)|dstflags,text);
750 conn_unget_chatcharname(me,tname);
751 }
752 break;
753 case message_type_talk:
754 if (!me)
755 {
756 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
757 return -1;
758 }
759 if (!text)
760 {
761 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
762 return -1;
763 }
764 if (dstflags&MF_X)
765 return -1; /* player is ignored */
766 {
767 char const * tname;
768
769 tname = conn_get_chatcharname(me, me); /* FIXME: second should be dst but cache gets in the way */
770 msgtemp = xmalloc(32+strlen(tname)+32+strlen(text));
771 sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_TALK,"TALK",tname,conn_get_flags(me)|dstflags,text);
772 conn_unget_chatcharname(me,tname);
773 }
774 break;
775 case message_type_broadcast:
776 if (!text)
777 {
778 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
779 return -1;
780 }
781 if (dstflags&MF_X)
782 return -1; /* player is ignored */
783 msgtemp = xmalloc(32+32+strlen(text));
784 sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_BROADCAST,"_",text); /* FIXME: what does this look like on Battle.net? */
785 break;
786 case message_type_channel:
787 if (!text)
788 {
789 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
790 return -1;
791 }
792 msgtemp = xmalloc(32+strlen(text));
793 sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_CHANNEL,"CHANNEL",text);
794 break;
795 case message_type_userflags:
796 if (!me)
797 {
798 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
799 return -1;
800 }
801 {
802 char const * tname;
803
804 tname = conn_get_chatcharname(me, dst);
805 msgtemp = xmalloc(32+strlen(tname)+16);
806 sprintf(msgtemp,"%u %s %s %04x\r\n",EID_USERFLAGS,"USER",tname,conn_get_flags(me)|dstflags);
807 conn_unget_chatcharname(me,tname);
808 }
809 break;
810 case message_type_whisperack:
811 if (!me)
812 {
813 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
814 return -1;
815 }
816 if (!text)
817 {
818 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
819 return -1;
820 }
821 {
822 char const * tname;
823
824 tname = conn_get_chatcharname(me, dst);
825 msgtemp = xmalloc(32+strlen(tname)+32+strlen(text));
826 sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_WHISPERSENT,"WHISPER",tname,conn_get_flags(me)|dstflags,text);
827 conn_unget_chatcharname(me,tname);
828 }
829 break;
830 case message_type_friendwhisperack: // [zap-zero] 20020518
831 if (!me)
832 {
833 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
834 return -1;
835 }
836 if (!text)
837 {
838 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
839 return -1;
840 }
841 {
842 msgtemp = xmalloc(32+16+32+strlen(text));
843 sprintf(msgtemp,"%u %s \"your friends\" %04x \"%s\"\r\n",EID_WHISPERSENT,"WHISPER",conn_get_flags(me)|dstflags,text);
844 }
845 break;
846
847 case message_type_channelfull:
848 msgtemp = xmalloc(32);
849 sprintf(msgtemp,"%u \r\n",EID_CHANNELFULL); /* FIXME */
850 break;
851 case message_type_channeldoesnotexist:
852 msgtemp = xmalloc(32);
853 sprintf(msgtemp,"%u \r\n",EID_CHANNELDOESNOTEXIST); /* FIXME */
854 break;
855 case message_type_channelrestricted:
856 msgtemp = xmalloc(32);
857 sprintf(msgtemp,"%u \r\n",EID_CHANNELRESTRICTED); /* FIXME */
858 break;
859 case message_type_info:
860 if (!text)
861 {
862 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
863 return -1;
864 }
865 msgtemp = xmalloc(32+16+strlen(text));
866 sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_INFO,"INFO",text);
867 break;
868 case message_type_error:
869 if (!text)
870 {
871 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
872 return -1;
873 }
874 msgtemp = xmalloc(32+16+strlen(text));
875 sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_ERROR,"ERROR",text);
876 break;
877 case message_type_emote:
878 if (!me)
879 {
880 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
881 return -1;
882 }
883 if (!text)
884 {
885 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
886 return -1;
887 }
888 if (dstflags&MF_X)
889 return -1; /* player is ignored */
890 {
891 char const * tname;
892
893 tname = conn_get_chatcharname(me, me); /* FIXME: second should be dst but cache gets in the way */
894 msgtemp = xmalloc(32+strlen(tname)+32+strlen(text));
895 sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_EMOTE,"EMOTE",tname,conn_get_flags(me)|dstflags,text);
896 conn_unget_chatcharname(me,tname);
897 }
898 break;
899 default:
900 eventlog(eventlog_level_error,__FUNCTION__,"got bad message type %d",(int)type);
901 return -1;
902 }
903
904 if (strlen(msgtemp)>MAX_MESSAGE_LEN)
905 msgtemp[MAX_MESSAGE_LEN] = '\0'; /* now truncate to max size */
906
907 {
908 int retval;
909
910 retval = packet_append_ntstring(packet,msgtemp);
911 xfree(msgtemp);
912 return retval;
913 }
914 }
915
916
917 static int message_bnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags)
918 {
919 if (!packet)
920 {
921 eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet");
922 return -1;
923 }
924
925 if (text && text[0]=='\0')
926 text = " "; /* empty messages crash some clients, just send whitespace */
927
928 packet_set_size(packet,sizeof(t_server_message));
929 packet_set_type(packet,SERVER_MESSAGE);
930 bn_int_set(&packet->u.server_message.player_ip,SERVER_MESSAGE_PLAYER_IP_DUMMY);
931 bn_int_nset(&packet->u.server_message.account_num,SERVER_MESSAGE_ACCOUNT_NUM);
932 bn_int_set(&packet->u.server_message.reg_auth,SERVER_MESSAGE_REG_AUTH);
933
934 switch (type)
935 {
936 case message_type_adduser:
937 if (!me)
938 {
939 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
940 return -1;
941 }
942 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_ADDUSER);
943 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
944 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
945 {
946 char const * tname;
947 char const * playerinfo;
948
949 tname = conn_get_chatcharname(me, dst);
950 packet_append_string(packet,tname);
951 conn_unget_chatcharname(me,tname);
952 if ((conn_get_clienttag(me) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(me) == CLIENTTAG_WAR3XP_UINT))
953 playerinfo = conn_get_w3_playerinfo(me);
954 else playerinfo = conn_get_playerinfo(me);
955
956 if (playerinfo == NULL) { playerinfo = ""; }
957 packet_append_string(packet,playerinfo);
958 }
959 break;
960 case message_type_join:
961 if (!me)
962 {
963 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
964 return -1;
965 }
966 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_JOIN);
967 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
968 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
969 {
970 char const * tname;
971 char const * playerinfo;
972
973 tname = conn_get_chatcharname(me, dst);
974 packet_append_string(packet,tname);
975 conn_unget_chatcharname(me,tname);
976
977 if ((conn_get_clienttag(me) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(me) == CLIENTTAG_WAR3XP_UINT))
978 playerinfo = conn_get_w3_playerinfo(me);
979 else playerinfo = conn_get_playerinfo(me);
980
981 if (playerinfo == NULL) { playerinfo = ""; }
982 packet_append_string(packet, playerinfo);
983 }
984 break;
985 case message_type_part:
986 if (!me)
987 {
988 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
989 return -1;
990 }
991 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_PART);
992 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
993 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
994 {
995 char const * tname;
996
997 tname = conn_get_chatcharname(me, dst);
998 packet_append_string(packet,tname);
999 conn_unget_chatcharname(me,tname);
1000 packet_append_string(packet,"");
1001 }
1002 break;
1003 case message_type_whisper:
1004 if (!me)
1005 {
1006 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1007 return -1;
1008 }
1009 if (!text)
1010 {
1011 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1012 return -1;
1013 }
1014 if (dstflags&MF_X)
1015 return -1; /* player is ignored */
1016 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPER);
1017 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1018 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1019 {
1020 char const * tname;
1021
1022 tname = conn_get_chatcharname(me, dst);
1023 packet_append_string(packet,tname);
1024 conn_unget_chatcharname(me,tname);
1025 packet_append_string(packet,text);
1026 }
1027 break;
1028 case message_type_talk:
1029 if (!me)
1030 {
1031 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1032 return -1;
1033 }
1034 if (!text)
1035 {
1036 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1037 return -1;
1038 }
1039 if (dstflags&MF_X)
1040 return -1; /* player is ignored */
1041 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_TALK);
1042 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1043 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1044 {
1045 char const * tname;
1046
1047 tname = conn_get_chatcharname(me, dst); /* FIXME: second should be dst but cache gets in the way */
1048 packet_append_string(packet,tname);
1049 conn_unget_chatcharname(me,tname);
1050 packet_append_string(packet,text);
1051 }
1052 break;
1053 case message_type_broadcast:
1054 if (!text)
1055 {
1056 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1057 return -1;
1058 }
1059 if (dstflags&MF_X)
1060 return -1; /* player is ignored */
1061 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_BROADCAST);
1062 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1063 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1064 {
1065 char const * tname;
1066
1067 tname = conn_get_chatcharname(me, dst);
1068 packet_append_string(packet,tname);
1069 conn_unget_chatcharname(me,tname);
1070 packet_append_string(packet,text);
1071 }
1072 break;
1073 case message_type_channel:
1074 if (!me)
1075 {
1076 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1077 return -1;
1078 }
1079 if (!text)
1080 {
1081 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1082 return -1;
1083 }
1084 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNEL);
1085 {
1086 t_channel const * channel;
1087
1088 if (!(channel = conn_get_channel(me)))
1089 bn_int_set(&packet->u.server_message.flags,0);
1090 else
1091 bn_int_set(&packet->u.server_message.flags,cflags_to_bncflags(channel_get_flags(channel)));
1092 }
1093 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1094 {
1095 char const * tname;
1096
1097 tname = conn_get_chatname(me);
1098 packet_append_string(packet,tname);
1099 conn_unget_chatname(me,tname);
1100 packet_append_string(packet,text);
1101 }
1102 break;
1103 case message_type_userflags:
1104 if (!me)
1105 {
1106 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1107 return -1;
1108 }
1109 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_USERFLAGS);
1110 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1111 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1112 {
1113 char const * tname;
1114 char const * playerinfo;
1115
1116 tname = conn_get_chatcharname(me, dst);
1117 packet_append_string(packet,tname);
1118 conn_unget_chatcharname(me,tname);
1119 if ((conn_get_clienttag(me) == CLIENTTAG_WARCRAFT3_UINT) || (conn_get_clienttag(me) == CLIENTTAG_WAR3XP_UINT))
1120 playerinfo = conn_get_w3_playerinfo(me);
1121 else playerinfo = conn_get_playerinfo(me);
1122
1123 if (playerinfo == NULL) { playerinfo = ""; }
1124
1125 packet_append_string(packet, playerinfo);
1126 }
1127 break;
1128 case message_type_whisperack:
1129 if (!me)
1130 {
1131 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1132 return -1;
1133 }
1134 if (!text)
1135 {
1136 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1137 return -1;
1138 }
1139 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPERACK);
1140 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1141 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1142 {
1143 char const * tname;
1144
1145 tname = conn_get_chatcharname(me, dst);
1146 packet_append_string(packet,tname);
1147 conn_unget_chatcharname(me,tname);
1148 packet_append_string(packet,text);
1149 }
1150 break;
1151 case message_type_friendwhisperack: // [zap-zero] 20020518
1152 if (!me)
1153 {
1154 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1155 return -1;
1156 }
1157 if (!text)
1158 {
1159 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1160 return -1;
1161 }
1162 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPERACK);
1163 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1164 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1165 {
1166
1167 packet_append_string(packet,"your friends");
1168 packet_append_string(packet,text);
1169 }
1170 break;
1171
1172 case message_type_channelfull: /* FIXME */
1173 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELFULL);
1174 bn_int_set(&packet->u.server_message.flags,0);
1175 bn_int_set(&packet->u.server_message.latency,0);
1176 packet_append_string(packet,"");
1177 packet_append_string(packet,"");
1178 break;
1179 case message_type_channeldoesnotexist:
1180 if (!me)
1181 {
1182 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1183 return -1;
1184 }
1185 if (!text)
1186 {
1187 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1188 return -1;
1189 }
1190 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELDOESNOTEXIST);
1191 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1192 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1193 {
1194 char const * tname;
1195
1196 tname = conn_get_chatname(me);
1197 packet_append_string(packet,tname);
1198 conn_unget_chatname(me,tname);
1199 packet_append_string(packet,text);
1200 }
1201 break;
1202 case message_type_channelrestricted: /* FIXME */
1203 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELRESTRICTED);
1204 bn_int_set(&packet->u.server_message.flags,0);
1205 bn_int_set(&packet->u.server_message.latency,0);
1206 packet_append_string(packet,"");
1207 packet_append_string(packet,"");
1208 break;
1209 case message_type_info:
1210 if (!text)
1211 {
1212 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1213 return -1;
1214 }
1215 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_INFO);
1216 bn_int_set(&packet->u.server_message.flags,0);
1217 bn_int_set(&packet->u.server_message.latency,0);
1218 packet_append_string(packet,"");
1219 packet_append_string(packet,text);
1220 break;
1221 case message_type_error:
1222 if (!text)
1223 {
1224 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1225 return -1;
1226 }
1227 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_ERROR);
1228 bn_int_set(&packet->u.server_message.flags,0);
1229 bn_int_set(&packet->u.server_message.latency,0);
1230 packet_append_string(packet,"");
1231 packet_append_string(packet,text);
1232 break;
1233 case message_type_emote:
1234 if (!me)
1235 {
1236 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type));
1237 return -1;
1238 }
1239 if (!text)
1240 {
1241 eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type));
1242 return -1;
1243 }
1244 if (dstflags&MF_X)
1245 return -1; /* player is ignored */
1246 bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_EMOTE);
1247 bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags);
1248 bn_int_set(&packet->u.server_message.latency,conn_get_latency(me));
1249 {
1250 char const * tname;
1251
1252 tname = conn_get_chatcharname(me, me); /* FIXME: second should be dst but cache gets in the way */
1253 packet_append_string(packet,tname);
1254 conn_unget_chatcharname(me,tname);
1255 packet_append_string(packet,text);
1256 }
1257 break;
1258 default:
1259 eventlog(eventlog_level_error,__FUNCTION__,"got bad message type %d",(int)type);
1260 return -1;
1261 }
1262
1263 return 0;
1264 }
1265
1266
1267 extern t_message * message_create(t_message_type type, t_connection * src, t_connection * dst, char const * text)
1268 {
1269 t_message * message;
1270
1271 message = xmalloc(sizeof(t_message));
1272 message->num_cached = 0;
1273 message->packets = NULL;
1274 message->classes = NULL;
1275 message->dstflags = NULL;
1276 message->mclasses = NULL;
1277 message->type = type;
1278 message->src = src;
1279 message->dst = dst;
1280 message->text = text;
1281
1282 return message;
1283 }
1284
1285
1286 extern int message_destroy(t_message * message)
1287 {
1288 unsigned int i;
1289
1290 if (!message)
1291 {
1292 eventlog(eventlog_level_error,__FUNCTION__,"got NULL message");
1293 return -1;
1294 }
1295
1296 for (i=0; i<message->num_cached; i++)
1297 if (message->packets[i])
1298 packet_del_ref(message->packets[i]);
1299 if (message->packets)
1300 xfree(message->packets);
1301 if (message->classes)
1302 xfree(message->classes);
1303 if (message->dstflags)
1304 xfree(message->dstflags);
1305 if (message->mclasses)
1306 xfree(message->mclasses);
1307 xfree(message);
1308
1309 return 0;
1310 }
1311
1312
1313 static t_packet * message_cache_lookup(t_message * message, t_connection *dst, unsigned int dstflags)
1314 {
1315 unsigned int i;
1316 t_packet * packet;
1317 t_message_class mclass;
1318 t_conn_class class;
1319
1320 if (!message)
1321 {
1322 eventlog(eventlog_level_error,__FUNCTION__,"got NULL message");
1323 return NULL;
1324 }
1325
1326 class = conn_get_class(dst);
1327 mclass = conn_get_message_class(message->src, dst);
1328 for (i=0; i<message->num_cached; i++)
1329 if (message->classes[i]==class && message->dstflags[i]==dstflags
1330 && message->mclasses[i]==mclass)
1331 return message->packets[i];
1332
1333 {
1334 t_packet * * temp_packets;
1335 t_conn_class * temp_classes;
1336 unsigned int * temp_dstflags;
1337 t_message_class *temp_mclasses;
1338
1339 if (!message->packets)
1340 temp_packets = xmalloc(sizeof(t_packet *)*(message->num_cached+1));
1341 else
1342 temp_packets = xrealloc(message->packets,sizeof(t_packet *)*(message->num_cached+1));
1343
1344 if (!message->classes)
1345 temp_classes = xmalloc(sizeof(t_conn_class)*(message->num_cached+1));
1346 else
1347 temp_classes = xrealloc(message->classes,sizeof(t_conn_class)*(message->num_cached+1));
1348
1349 if (!message->dstflags)
1350 temp_dstflags = xmalloc(sizeof(unsigned int)*(message->num_cached+1));
1351 else
1352 temp_dstflags = xrealloc(message->dstflags,sizeof(unsigned int)*(message->num_cached+1));
1353
1354 if (!message->mclasses)
1355 temp_mclasses = xmalloc(sizeof(t_message_class)*(message->num_cached+1));
1356 else
1357 temp_mclasses = xrealloc(message->mclasses,sizeof(t_message_class)*(message->num_cached+1));
1358
1359 message->packets = temp_packets;
1360 message->classes = temp_classes;
1361 message->dstflags = temp_dstflags;
1362 message->mclasses = temp_mclasses;
1363 }
1364
1365 switch (class)
1366 {
1367 case conn_class_telnet:
1368 if (!(packet = packet_create(packet_class_raw)))
1369 {
1370 eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
1371 return NULL;
1372 }
1373 if (message_telnet_format(packet,message->type,message->src,message->dst,message->text,dstflags)<0)
1374 {
1375 packet_del_ref(packet);
1376 packet = NULL; /* we can cache the NULL too */
1377 }
1378 break;
1379 case conn_class_bot:
1380 if (!(packet = packet_create(packet_class_raw)))
1381 {
1382 eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
1383 return NULL;
1384 }
1385 if (message_bot_format(packet,message->type,message->src,message->dst,message->text,dstflags)<0)
1386 {
1387 packet_del_ref(packet);
1388 packet = NULL; /* we can cache the NULL too */
1389 }
1390 break;
1391 case conn_class_bnet:
1392 if (!(packet = packet_create(packet_class_bnet)))
1393 {
1394 eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
1395 return NULL;
1396 }
1397 if (message_bnet_format(packet,message->type,message->src,dst,message->text,dstflags)<0)
1398 {
1399 packet_del_ref(packet);
1400 packet = NULL; /* we can cache the NULL too */
1401 }
1402 break;
1403 case conn_class_irc:
1404 if (!(packet = packet_create(packet_class_raw)))
1405 {
1406 eventlog(eventlog_level_error,__FUNCTION__,"could not create packet");
1407 return NULL;
1408 }
1409 /* irc_message_format() is in irc.c */
1410 if (irc_message_format(packet,message->type,message->src,message->dst,message->text,dstflags)<0)
1411 {
1412 packet_del_ref(packet);
1413 packet = NULL; /* we can cache the NULL too */
1414 }
1415 break;
1416 case conn_class_init:
1417 case conn_class_file:
1418 case conn_class_d2cs_bnetd:
1419 case conn_class_w3route:
1420 packet = NULL;
1421 break; /* cache the NULL but dont send any error,
1422 * this are normal connections */
1423 default:
1424 eventlog(eventlog_level_error,__FUNCTION__,"unsupported connection class %d",(int)class);
1425 packet = NULL; /* we can cache the NULL too */
1426 }
1427
1428 message->num_cached++;
1429 message->packets[i] = packet;
1430 message->classes[i] = class;
1431 message->dstflags[i] = dstflags;
1432 message->mclasses[i] = mclass;
1433
1434 return packet;
1435 }
1436
1437
1438 extern int message_send(t_message * message, t_connection * dst)
1439 {
1440 t_packet * packet;
1441 unsigned int dstflags;
1442
1443 if (!message)
1444 {
1445 eventlog(eventlog_level_error,__FUNCTION__,"got NULL message");
1446 return -1;
1447 }
1448 if (!dst)
1449 {
1450 eventlog(eventlog_level_error,__FUNCTION__,"got NULL dst connection");
1451 return -1;
1452 }
1453
1454 dstflags = 0;
1455 if (message->src)
1456 {
1457 char const * tname;
1458
1459 if ((tname = conn_get_chatname(message->src)) && conn_check_ignoring(dst,tname)==1)
1460 {
1461 conn_unget_chatname(message->src,tname);
1462 dstflags |= MF_X;
1463 }
1464 if (tname)
1465 conn_unget_chatname(message->src,tname);
1466 }
1467
1468 if (!(packet = message_cache_lookup(message,dst,dstflags)))
1469 return -1;
1470
1471 /* FIXME: this is not needed now, message has dst */
1472 if (conn_get_class(dst)==conn_class_irc) {
1473 /* HACK: IRC message always need the recipient and are therefore bad to cache. */
1474 /* So we only cache a pseudo packet and convert it to a real packet later ... */
1475 packet = packet_duplicate(packet); /* we want to modify packet so we have to create a copy ... */
1476 if (irc_message_postformat(packet,dst)<0) {
1477 packet_del_ref(packet); /* we don't need the previously created copy anymore ... */
1478 return -1;
1479 }
1480 }
1481
1482 conn_push_outqueue(dst,packet);
1483
1484 if (conn_get_class(dst)==conn_class_irc)
1485 packet_del_ref(packet); /* we don't need the previously created copy anymore ... */
1486
1487 return 0;
1488 }
1489
1490
1491 extern int message_send_all(t_message * message)
1492 {
1493 t_connection * c;
1494 t_elem const * curr;
1495 int rez;
1496
1497 if (!message)
1498 {
1499 eventlog(eventlog_level_error,__FUNCTION__,"got NULL message");
1500 return -1;
1501 }
1502
1503 rez = -1;
1504 LIST_TRAVERSE_CONST(connlist(),curr)
1505 {
1506 c = elem_get_data(curr);
1507 if (message_send(message,c)==0)
1508 rez = 0;
1509 }
1510
1511 return rez;
1512 }
1513
1514
1515 extern int message_send_text(t_connection * dst, t_message_type type, t_connection * src, char const * text)
1516 {
1517 t_message * message;
1518 int rez;
1519
1520 if (!dst)
1521 {
1522 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1523 return -1;
1524 }
1525
1526 if (!(message = message_create(type,src,dst,text)))
1527 return -1;
1528 rez = message_send(message,dst);
1529 message_destroy(message);
1530
1531 return rez;
1532 }
1533
1534
1535 extern int message_send_admins(t_connection * src, t_message_type type, char const * text)
1536 {
1537 t_elem const * curr;
1538 t_connection * tc;
1539 int counter = 0;
1540
1541 LIST_TRAVERSE_CONST(connlist(),curr)
1542 {
1543 tc = elem_get_data(curr);
1544 if (!tc)
1545 continue;
1546 if (account_get_auth_admin(conn_get_account(tc),NULL)==1 && tc != src)
1547 {
1548 message_send_text(tc,type,src,text);
1549 counter++;
1550 }
1551 }
1552
1553 return counter;
1554 }
1555
1556
1557 extern int message_send_formatted(t_connection * dst, char const * text)
1558 {
1559 char * line;
1560
1561 if (!dst)
1562 {
1563 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1564 return -1;
1565 }
1566
1567 if (!(line = message_format_line(dst,text)))
1568 {
1569 eventlog(eventlog_level_error,__FUNCTION__,"could not format input text \"%s\"",text);
1570 return -1;
1571 }
1572
1573 /* caller beware: empty messages can crash Blizzard clients */
1574 switch (line[0])
1575 {
1576 case 'C':
1577 if (line[1]=='/')
1578 handle_command(dst,&line[1]);
1579 else
1580 if (conn_get_channel(dst) && !conn_quota_exceeded(dst,&line[1]))
1581 channel_message_send(conn_get_channel(dst),message_type_talk,dst,&line[1]);
1582 break;
1583 case 'B':
1584 message_send_text(dst,message_type_broadcast,dst,&line[1]);
1585 break;
1586 case 'E':
1587 message_send_text(dst,message_type_error,dst,&line[1]);
1588 break;
1589 case 'M':
1590 message_send_text(dst,message_type_talk,dst,&line[1]);
1591 break;
1592 case 'T':
1593 message_send_text(dst,message_type_emote,dst,&line[1]);
1594 break;
1595 case 'I':
1596 case 'W':
1597 message_send_text(dst,message_type_info,dst,&line[1]);
1598 break;
1599 default:
1600 eventlog(eventlog_level_error,__FUNCTION__,"unknown message type '%c'",line[0]);
1601 xfree(line);
1602 return -1;
1603 }
1604
1605 xfree(line);
1606 return 0;
1607 }
1608
1609
1610 extern int message_send_file(t_connection * dst, FILE * fd)
1611 {
1612 char * buff;
1613
1614 if (!dst)
1615 {
1616 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1617 return -1;
1618 }
1619 if (!fd)
1620 {
1621 eventlog(eventlog_level_error,__FUNCTION__,"got NULL fd");
1622 return -1;
1623 }
1624
1625 while ((buff = file_get_line(fd)))
1626 {
1627 message_send_formatted(dst,buff);
1628 }
1629 file_get_line(NULL); // clear file_get_line buffer
1630
1631 return 0;
1632 }
1633
1634 /* sowater, 20050401 */
1635 extern int message_send_checknum(t_connection * dst,t_connection * src, char checknum)
1636 {
1637 char msgbuf[30];
1638 if(!dst) {
1639 eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection");
1640 return -1;
1641 }
1642 if(!checknum) {
1643 eventlog(eventlog_level_error,__FUNCTION__,"got NULL checknum");
1644 return -1;
1645 }
1646 sprintf(msgbuf,"your check id is: %c ",checknum);
1647 message_send_text(dst,message_type_error,src,msgbuf);
1648 return 0;
1649 }
1650

webmaster@leafok.com
ViewVC Help
Powered by ViewVC 1.3.0-beta1