static int message_bnet_format(t_packet * packet, t_message_type type, t_connection * me, t_connection * dst, char const * text, unsigned int dstflags) { if (!packet) { eventlog(eventlog_level_error,"message_bnet_format","got NULL packet"); return -1; } if (text && text[0]=='\0') text = " "; /* empty messages crash some clients, just send whitespace */ packet_set_size(packet,sizeof(t_server_message)); packet_set_type(packet,SERVER_MESSAGE); bn_int_set(&packet->u.server_message.unknown1,SERVER_MESSAGE_UNKNOWN1); bn_int_nset(&packet->u.server_message.player_ip,SERVER_MESSAGE_PLAYER_IP_DUMMY); bn_int_set(&packet->u.server_message.unknown3,SERVER_MESSAGE_UNKNOWN3); switch (type) { case message_type_adduser: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_ADDUSER); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * playerinfo; char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); if (!(playerinfo = conn_get_playerinfo(me))) playerinfo = ""; packet_append_string(packet,playerinfo); } break; case message_type_join: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_JOIN); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * playerinfo; char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); if (!(playerinfo = conn_get_playerinfo(me))) playerinfo = ""; packet_append_string(packet,playerinfo); /* FIXME: should we just send "" here instead of playerinfo? */ } break; case message_type_part: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_PART); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); packet_append_string(packet,""); } break; case message_type_whisper: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPER); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); packet_append_string(packet,text); } break; case message_type_talk: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_TALK); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatcharname(me, me))) /* FIXME: second should be dst but cache gets in the way */ return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); packet_append_string(packet,text); } break; case message_type_broadcast: if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_BROADCAST); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); packet_append_string(packet,text); } break; case message_type_channel: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNEL); { t_channel const * channel; if (!(channel = conn_get_channel(me))) bn_int_set(&packet->u.server_message.flags,0); else bn_int_set(&packet->u.server_message.flags,cflags_to_bncflags(channel_get_flags(channel))); } bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatname(me))) return -1; packet_append_string(packet,tname); conn_unget_chatname(me,tname); packet_append_string(packet,text); } break; case message_type_userflags: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_USERFLAGS); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * playerinfo; char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); if (!(playerinfo = conn_get_playerinfo(me))) playerinfo = ""; #if 0 /* FIXME: which is correct? does it depend on the client type? */ packet_append_string(packet,""); #else packet_append_string(packet,playerinfo); #endif } break; case message_type_whisperack: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_WHISPERACK); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); packet_append_string(packet,text); } break; case message_type_channelfull: /* FIXME */ bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELFULL); bn_int_set(&packet->u.server_message.flags,0); bn_int_set(&packet->u.server_message.latency,0); packet_append_string(packet,""); packet_append_string(packet,""); break; case message_type_channeldoesnotexist: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELDOESNOTEXIST); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; tname = conn_get_chatname(me); packet_append_string(packet,tname); conn_unget_chatname(me,tname); packet_append_string(packet,text); } break; case message_type_channelrestricted: /* FIXME */ bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_CHANNELRESTRICTED); bn_int_set(&packet->u.server_message.flags,0); bn_int_set(&packet->u.server_message.latency,0); packet_append_string(packet,""); packet_append_string(packet,""); break; case message_type_info: if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_INFO); bn_int_set(&packet->u.server_message.flags,0); bn_int_set(&packet->u.server_message.latency,0); packet_append_string(packet,""); packet_append_string(packet,text); break; case message_type_error: if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_ERROR); bn_int_set(&packet->u.server_message.flags,0); bn_int_set(&packet->u.server_message.latency,0); packet_append_string(packet,""); packet_append_string(packet,text); break; case message_type_emote: if (!me) { eventlog(eventlog_level_error,"message_bnet_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bnet_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ bn_int_set(&packet->u.server_message.type,SERVER_MESSAGE_TYPE_EMOTE); bn_int_set(&packet->u.server_message.flags,conn_get_flags(me)|dstflags); bn_int_set(&packet->u.server_message.latency,conn_get_latency(me)); { char const * tname; if(!(tname = conn_get_chatcharname(me, me))) /* FIXME: second should be dst but cache gets in the way */ return -1; packet_append_string(packet,tname); conn_unget_chatcharname(me,tname); packet_append_string(packet,text); } break; default: eventlog(eventlog_level_error,"message_bnet_format","got bad message type %d",(int)type); return -1; } return 0; }
static int message_bot_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,"message_bot_format","got NULL packet"); return -1; } /* special-case the login banner so it doesn't have numbers * at the start of each line */ if (me && conn_get_state(me)!=conn_state_loggedin && conn_get_state(me)!=conn_state_destroy && type!=message_type_null) /* this does not apply for NULL messages */ { if (!text) { #if 0 /* battle.net actually sends them during login */ if (type==message_type_null) return 0; /* don't display null messages during the login */ #endif eventlog(eventlog_level_error,"message_bot_format","got NULL text for non-loggedin state"); return -1; } if (!(msgtemp = malloc(strlen(text)+4))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%s\r\n",text); } else switch (type) { case message_type_null: if (!(msgtemp = malloc(32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s\r\n",EID_NULL,"NULL"); break; case message_type_uniqueid: /* FIXME: need to send this for some bots, also needed to support guest accounts */ if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (!(msgtemp = malloc(strlen(text)+32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s\r\n",EID_UNIQUENAME,"NAME",text); break; case message_type_adduser: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; if (!(msgtemp = malloc(32+strlen(tname)+32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x [%s]\r\n",EID_SHOWUSER,"USER",tname,conn_get_flags(me)|dstflags,conn_get_fake_clienttag(me)); conn_unget_chatcharname(me,tname); } break; case message_type_join: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; if (!(msgtemp = malloc(32+strlen(tname)+32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x [%s]\r\n",EID_JOIN,"JOIN",tname,conn_get_flags(me)|dstflags,conn_get_fake_clienttag(me)); conn_unget_chatcharname(me,tname); } break; case message_type_part: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; if (!(msgtemp = malloc(32+strlen(tname)+32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x\r\n",EID_LEAVE,"LEAVE",tname,conn_get_flags(me)|dstflags); conn_unget_chatcharname(me,tname); } break; case message_type_whisper: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; if (!(msgtemp = malloc(32+strlen(tname)+32+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_WHISPER,"WHISPER",tname,conn_get_flags(me)|dstflags,text); conn_unget_chatcharname(me,tname); } break; case message_type_talk: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ { char const * tname; if(!(tname = conn_get_chatcharname(me, me))) /* FIXME: second should be dst but cache gets in the way */ return -1; if (!(msgtemp = malloc(32+strlen(tname)+32+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_TALK,"TALK",tname,conn_get_flags(me)|dstflags,text); conn_unget_chatcharname(me,tname); } break; case message_type_broadcast: if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ if (!(msgtemp = malloc(32+32+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_BROADCAST,"_",text); /* FIXME: what does this look like on Battle.net? */ break; case message_type_channel: if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (!(msgtemp = malloc(32+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_CHANNEL,"CHANNEL",text); break; case message_type_userflags: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; if (!(msgtemp = malloc(32+strlen(tname)+16))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x\r\n",EID_USERFLAGS,"USER",tname,conn_get_flags(me)|dstflags); conn_unget_chatcharname(me,tname); } break; case message_type_whisperack: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } { char const * tname; if(!(tname = conn_get_chatcharname(me, dst))) return -1; if (!(msgtemp = malloc(32+strlen(tname)+32+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_WHISPERSENT,"WHISPER",tname,conn_get_flags(me)|dstflags,text); conn_unget_chatcharname(me,tname); } break; case message_type_channelfull: if (!(msgtemp = malloc(32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u \r\n",EID_CHANNELFULL); /* FIXME */ break; case message_type_channeldoesnotexist: if (!(msgtemp = malloc(32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u \r\n",EID_CHANNELDOESNOTEXIST); /* FIXME */ break; case message_type_channelrestricted: if (!(msgtemp = malloc(32))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u \r\n",EID_CHANNELRESTRICTED); /* FIXME */ break; case message_type_info: if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (!(msgtemp = malloc(32+16+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_INFO,"INFO",text); break; case message_type_error: if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (!(msgtemp = malloc(32+16+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s \"%s\"\r\n",EID_ERROR,"ERROR",text); break; case message_type_emote: if (!me) { eventlog(eventlog_level_error,"message_bot_format","got NULL connection for %s",message_type_get_str(type)); return -1; } if (!text) { eventlog(eventlog_level_error,"message_bot_format","got NULL text for %s",message_type_get_str(type)); return -1; } if (dstflags&MF_X) return -1; /* player is ignored */ { char const * tname; if(!(tname = conn_get_chatcharname(me, me))) /* FIXME: second should be dst but cache gets in the way */ return -1; if (!(msgtemp = malloc(32+strlen(tname)+32+strlen(text)))) { eventlog(eventlog_level_error,"message_bot_format","could not allocate memory for msgtemp"); return -1; } sprintf(msgtemp,"%u %s %s %04x \"%s\"\r\n",EID_EMOTE,"EMOTE",tname,conn_get_flags(me)|dstflags,text); conn_unget_chatcharname(me,tname); } break; default: eventlog(eventlog_level_error,"message_bot_format","got bad message type %d",(int)type); return -1; } if (strlen(msgtemp)>=MAX_MESSAGE_LEN) { msgtemp[MAX_MESSAGE_LEN] = '\0'; /* now truncate to max size */ msgtemp[MAX_MESSAGE_LEN-1] = '\n'; /* and add EOL signs - message have to be send properly */ msgtemp[MAX_MESSAGE_LEN-2] = '\r'; } { int retval; retval = packet_append_ntstring(packet,msgtemp); free(msgtemp); return retval; } }
extern int irc_send_rpl_namreply(t_connection * c, t_channel const * channel) { char temp[MAX_IRC_MESSAGE_LEN]; char const * ircname; int first = 1; t_connection * m; if (!c) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL connection"); return -1; } if (!channel) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL channel"); return -1; } memset(temp,0,sizeof(temp)); ircname = irc_convert_channel(channel); if (!ircname) { eventlog(eventlog_level_error,__FUNCTION__,"channel has NULL ircname"); return -1; } /* '@' = secret; '*' = private; '=' = public */ if ((1+1+strlen(ircname)+2+1)<=MAX_IRC_MESSAGE_LEN) { sprintf(temp,"%c %s :",((channel_get_permanent(channel))?('='):('*')),ircname); } else { eventlog(eventlog_level_warn,__FUNCTION__,"maximum message length exceeded"); return -1; } /* FIXME: Add per user flags (@(op) and +(voice))*/ for (m = channel_get_first(channel);m;m = channel_get_next()) { char const * name = conn_get_chatname(m); char flg[5] = ""; unsigned int flags; if (!name) continue; flags = conn_get_flags(m); if (flags & MF_BLIZZARD) strcat(flg,"@"); else if ((flags & MF_BNET) || (flags & MF_GAVEL)) strcat(flg,"%"); else if (flags & MF_VOICE) strcat(flg,"+"); if ((strlen(temp)+((!first)?(1):(0))+strlen(flg)+strlen(name)+1)<=sizeof(temp)) { if (!first) strcat(temp," "); if((conn_get_wol(c) == 1)) { if ((channel_wol_get_game_owner(channel) != NULL) && (strcmp(channel_wol_get_game_owner(channel),name) == 0)) { strcat(temp,"@"); } sprintf(temp,"%s%s,0,%u",temp,name,conn_get_addr(m)); } else { strcat(temp,flg); strcat(temp,name); } first = 0; } conn_unget_chatname(m,name); } irc_send(c,RPL_NAMREPLY,temp); return 0; }