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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1.1.1 - (hide annotations) (vendor branch)
Tue Jun 6 03:41:37 2006 UTC (19 years, 9 months ago) by sysadm
Branch: GNU
CVS Tags: arelease
Changes since 1.1: +0 -0 lines
Content type: text/x-csrc
no message

1 sysadm 1.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     }

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