📄 message.c
字号:
/* * Copyright (C) 1998 Mark Baysinger (mbaysing@ucsd.edu) * Copyright (C) 1998,1999,2001,2002 Ross Combs (rocombs@cs.nmsu.edu) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#define MESSAGE_INTERNAL_ACCESS#include "common/setup_before.h"#include <stdio.h>#ifdef HAVE_STDDEF_H# include <stddef.h>#else# ifndef NULL# define NULL ((void *)0)# endif#endif#ifdef STDC_HEADERS# include <stdlib.h>#else# ifdef HAVE_MALLOC_H# include <malloc.h># endif#endif#ifdef HAVE_STRING_H# include <string.h>#else# ifdef HAVE_STRINGS_H# include <strings.h># endif#endif#include "compat/strdup.h"#ifdef HAVE_UNISTD_H# include <unistd.h>#endif#include "compat/gethostname.h"#include <errno.h>#include "compat/strerror.h"#include "connection.h"#include "common/bn_type.h"#include "common/queue.h"#include "common/packet.h"#include "common/bot_protocol.h"#include "common/bnet_protocol.h"#include "common/field_sizes.h"#include "common/eventlog.h"#include "common/list.h"#include "common/util.h"#include "common/version.h"#include "common/addr.h"#include "account.h"#include "account_wrap.h"#include "game.h"#include "channel.h"#include "channel_conv.h"#include "command.h"#include "irc.h"#include "message.h"#include "mail.h"#include "prefs.h"#include "common/tag.h"#include "common/xalloc.h"#include "common/setup_after.h"static int message_telnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);static int message_bot_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);static int message_bnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags);static t_packet * message_cache_lookup(t_message * message, t_connection *dst, unsigned int flags);static char const * message_type_get_str(t_message_type type){ switch (type) { case message_type_adduser: return "adduser"; case message_type_join: return "join"; case message_type_part: return "part"; case message_type_whisper: return "whisper"; case message_type_talk: return "talk"; case message_type_broadcast: return "broadcast"; case message_type_channel: return "channel"; case message_type_userflags: return "userflags"; case message_type_whisperack: return "whisperack"; case message_type_friendwhisperack: //[zap-zero] 20020518 return "friendwhisperack"; case message_type_channelfull: return "channelfull"; case message_type_channeldoesnotexist: return "channeldoesnotexist"; case message_type_channelrestricted: return "channelrestricted"; case message_type_info: return "info"; case message_type_error: return "error"; case message_type_emote: return "emote"; case message_type_uniqueid: return "uniqueid"; case message_type_mode: return "mode"; case message_type_null: return "null"; default: return "UNKNOWN"; }}/* make sure none of the expanded format symbols is longer than this (with null) */#define MAX_INC 64extern char * message_format_line(t_connection const * c, char const * in){ char * out; unsigned int inpos; unsigned int outpos; unsigned int outlen=MAX_INC; unsigned int inlen; char clienttag_str[5]; out = xmalloc(outlen+1); inlen = strlen(in); out[0] = 'I'; for (inpos=0,outpos=1; inpos<inlen; inpos++) { if (in[inpos]!='%') { out[outpos] = in[inpos]; outpos += 1; } else switch (in[++inpos]) { case '%': out[outpos++] = '%'; break; case 'a': sprintf(&out[outpos],"%u",accountlist_get_length()); outpos += strlen(&out[outpos]); break; case 'c': sprintf(&out[outpos],"%d",channellist_get_length()); outpos += strlen(&out[outpos]); break; case 'g': sprintf(&out[outpos],"%d",gamelist_get_length()); outpos += strlen(&out[outpos]); break; case 'h': if (gethostname(&out[outpos],MAX_INC)<0) { eventlog(eventlog_level_error,__FUNCTION__,"could not get hostname (gethostname: %s)",pstrerror(errno)); strcpy(&out[outpos],"localhost"); /* not much else you can do */ } outpos += strlen(&out[outpos]); break; case 'i': sprintf(&out[outpos],UID_FORMAT,conn_get_userid(c)); outpos += strlen(&out[outpos]); break; case 'l': { char const * tname; strncpy(&out[outpos],(tname = (conn_get_chatname(c)?conn_get_chatname(c):conn_get_loggeduser(c))),USER_NAME_MAX-1); conn_unget_chatname(c,tname); } out[outpos+USER_NAME_MAX-1] = '\0'; outpos += strlen(&out[outpos]); break; case 'm': sprintf(&out[outpos],"%s",check_mail(c)); outpos += strlen(&out[outpos]); break; case 'r': strncpy(&out[outpos],addr_num_to_ip_str(conn_get_addr(c)),MAX_INC-1); out[outpos+MAX_INC-1] = '\0'; outpos += strlen(&out[outpos]); break; case 's': sprintf(&out[outpos],"%s",prefs_get_servername()); outpos += strlen(&out[outpos]); break; case 't': sprintf(&out[outpos],"%s",tag_uint_to_str(clienttag_str,conn_get_clienttag(c))); outpos += strlen(&out[outpos]); break; case 'u': sprintf(&out[outpos],"%d",connlist_login_get_length()); outpos += strlen(&out[outpos]); break; case 'v': strcpy(&out[outpos],PVPGN_SOFTWARE" "PVPGN_VERSION); outpos += strlen(&out[outpos]); break; case 'C': /* simulated command */ out[0] = 'C'; break; case 'B': /* BROADCAST */ out[0] = 'B'; break; case 'E': /* ERROR */ out[0] = 'E'; break; case 'G': sprintf(&out[outpos],"%d",game_get_count_by_clienttag(conn_get_clienttag(c))); outpos += strlen(&out[outpos]); break; case 'H': strcpy(&out[outpos],prefs_get_contact_name()); outpos += strlen(&out[outpos]); break; case 'I': /* INFO */ out[0] = 'I'; break; case 'M': /* MESSAGE */ out[0] = 'M'; break; case 'N': strcpy(&out[outpos],clienttag_get_title(conn_get_clienttag(c))); outpos += strlen(&out[outpos]); break; case 'T': /* EMOTE */ out[0] = 'T'; break; case 'U': sprintf(&out[outpos],"%d",conn_get_user_count_by_clienttag(conn_get_clienttag(c))); outpos += strlen(&out[outpos]); break; case 'W': /* INFO */ out[0] = 'W'; break; default: eventlog(eventlog_level_warn,__FUNCTION__,"bad formatter \"%%%c\"",in[inpos-1]); } if ((outpos+MAX_INC)>=outlen) { char * newout; outlen += MAX_INC; newout = xrealloc(out,outlen); out = newout; } } out[outpos] = '\0'; return out;}static int message_telnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags){ char * msgtemp; if (!packet) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL packet"); return -1; } switch (type) { case message_type_uniqueid: if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } msgtemp = xmalloc(strlen(text)+32); sprintf(msgtemp,"Your unique name: %s\r\n",text); break; case message_type_adduser: if (!me) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; tname = conn_get_chatcharname(me, dst); msgtemp = xmalloc(strlen(tname)+32); sprintf(msgtemp,"[%s is here]\r\n",tname); conn_unget_chatcharname(me,tname); } break; case message_type_join: if (!me) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; tname = conn_get_chatcharname(me, dst); msgtemp = xmalloc(strlen(tname)+32); sprintf(msgtemp,"[%s enters]\r\n",tname); conn_unget_chatcharname(me,tname); } break; case message_type_part: if (!me) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; tname = conn_get_chatcharname(me, dst); msgtemp = xmalloc(strlen(tname)+32); sprintf(msgtemp,"[%s leaves]\r\n",tname); conn_unget_chatcharname(me,tname); } break; case message_type_whisper: if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ { char const * tname; char const * newtext; if (me) tname = conn_get_chatcharname(me, dst); else tname = prefs_get_servername(); if ((newtext = escape_chars(text,strlen(text)))) { msgtemp = xmalloc(strlen(tname)+8+strlen(newtext)+4); sprintf(msgtemp,"<from %s> %s\r\n",tname,newtext); xfree((void *)newtext); /* avoid warning */ } else { msgtemp = xmalloc(16+strlen(tname)); sprintf(msgtemp,"<from %s> \r\n",tname); } if (me) conn_unget_chatcharname(me,tname); } break; case message_type_talk: if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ { char const * tname; char const * newtext; if (me) tname = conn_get_chatcharname(me, dst); else tname = prefs_get_servername(); if ((newtext = escape_chars(text,strlen(text)))) { msgtemp = xmalloc(strlen(tname)+4+strlen(newtext)+4); sprintf(msgtemp,"<%s> %s\r\n",tname,newtext); xfree((void *)newtext); /* avoid warning */ } else { msgtemp = xmalloc(strlen(tname)+8); sprintf(msgtemp,"<%s> \r\n",tname); } if (me) conn_unget_chatcharname(me,tname); } break; case message_type_broadcast: if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ { char const * newtext; if ((newtext = escape_chars(text,strlen(text)))) { msgtemp = xmalloc(16+strlen(newtext)+4); sprintf(msgtemp,"Broadcast: %s\r\n",newtext); /* FIXME: show source? */ xfree((void *)newtext); /* avoid warning */ } else { msgtemp = xmalloc(16); sprintf(msgtemp,"Broadcast: \r\n"); /* FIXME: show source? */ } } break; case message_type_channel: if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } msgtemp = xmalloc(strlen(text)+32); sprintf(msgtemp,"Joining channel: \"%s\"\r\n",text); break; case message_type_userflags: if (!me) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type)); return -1; } msgtemp = xstrdup(""); break; case message_type_whisperack: if (!me) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } { char const * tname; char const * newtext; tname = conn_get_chatcharname(me, dst); if ((newtext = escape_chars(text,strlen(text)))) { msgtemp = xmalloc(strlen(tname)+8+strlen(newtext)+4); sprintf(msgtemp,"<to %s> %s\r\n",tname,newtext); xfree((void *)newtext); /* avoid warning */ } else { msgtemp = xmalloc(strlen(tname)+8+strlen(text)+4); sprintf(msgtemp,"<to %s> %s\r\n",tname,text); } conn_unget_chatcharname(me,tname); } break; case message_type_friendwhisperack: // [zap-zero] 20020518 if (!me) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } { char const * newtext; if ((newtext = escape_chars(text,strlen(text)))) { msgtemp = xmalloc(14+8+strlen(newtext)+4); sprintf(msgtemp,"<to your friends> %s\r\n",newtext); xfree((void *)newtext); /* avoid warning */ } else { msgtemp = xmalloc(14+8+strlen(text)+4); sprintf(msgtemp,"<to your friends> %s\r\n",text); } } break; case message_type_channelfull: /* FIXME */ msgtemp = xstrdup(""); break; case message_type_channeldoesnotexist: /* FIXME */ msgtemp = xstrdup(""); break; case message_type_channelrestricted: /* FIXME */ msgtemp = xstrdup(""); break; case message_type_info: if (!text) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL text for %s",message_type_get_str(type)); return -1; } { char const * newtext; if ((newtext = escape_chars(text,strlen(text))))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -