void ChatUserCallback (const TTV_ChatUserList* joinList, const TTV_ChatUserList* leaveList, const TTV_ChatUserList* userInfoList, void* /*userdata*/) { for (uint i = 0; i < leaveList->userCount; ++i) { RemoveChatUser(&leaveList->userList[i]); } for (uint i = 0; i < joinList->userCount; ++i) { AddChatUser(&joinList->userList[i]); } for (uint i = 0; i < userInfoList->userCount; ++i) { UpdateChatUser(&userInfoList->userList[i]); } ////////////////////////////////////////////////////////////////////////// // Important to free user lists when we are done with them ////////////////////////////////////////////////////////////////////////// TTV_Chat_FreeUserList(joinList); TTV_Chat_FreeUserList(leaveList); TTV_Chat_FreeUserList(userInfoList); }
void UpdateChatUser(const TTV_ChatUserInfo* user) { RemoveChatUser(user); AddChatUser(user); }
char * ParseIRCMessage(char *Line, int iMode) { char szRemLine[MAXLOCALSTRING] =""; char *pszTempStr; char szPrefix[MAXLOCALSTRING] = ""; char szHackPrefix[MAXLOCALSTRING] = ""; char szTarget[MAXLOCALSTRING] = ""; char szNick[MAXLOCALSTRING] = ""; char szCmd[MAXLOCALSTRING] = ""; char szCTCPCmd[MAXLOCALSTRING] = ""; static char szResponse[MAXLOCALSTRING] = ""; int iPrefixLen = 0; // JAS: Get rid of optimized warning szRemLine[MAXLOCALSTRING-1] = '\0'; szPrefix[MAXLOCALSTRING-1] = '\0'; szHackPrefix[MAXLOCALSTRING-1] = '\0'; szTarget[MAXLOCALSTRING-1] = '\0'; szNick[MAXLOCALSTRING-1] = '\0'; szCmd[MAXLOCALSTRING-1] = '\0'; szCTCPCmd[MAXLOCALSTRING-1] = '\0'; szResponse[MAXLOCALSTRING-1] = '\0'; if(strlen(Line)>=MAXLOCALSTRING) { return NULL; } //Nick included.... if(iMode==MSG_REMOTE) { strncpy(szRemLine, Line, sizeof(szRemLine)-1); //Start by getting the prefix if(Line[0]==':') { // pszTempStr=GetWordNum(0,Line+1); strncpy(szPrefix, pszTempStr, sizeof(szPrefix)-1); strncpy(szHackPrefix, pszTempStr, sizeof(szHackPrefix)-1); strncpy(szRemLine, Line+1+strlen(szPrefix), sizeof(szRemLine)-1); } //Next, get the Nick pszTempStr=strtok(szHackPrefix,"!"); if(pszTempStr) { strncpy(szNick, pszTempStr, sizeof(szNick)-1); } else { strncpy(szNick,szPrefix,31); szNick[31]=0; } iPrefixLen=strlen(szPrefix); } else if(iMode==MSG_LOCAL) { strncpy(szRemLine, Line, sizeof(szRemLine)-1); strncpy(szNick, Nick_name, sizeof(szNick)-1); strncpy(szPrefix, Nick_name, sizeof(szPrefix)-1); iPrefixLen=-2; } //Next is the command pszTempStr=GetWordNum(0,szRemLine); if(pszTempStr[0]) { strncpy(szCmd, pszTempStr, sizeof(szCmd)-1); } else { //Shouldn't ever happen, but we can't be sure of what the host will send us. return NULL; } //Move the szRemLine string up strncpy(szRemLine, Line+iPrefixLen+strlen(szCmd)+2, sizeof(szRemLine)-1); //Now parse the commands! if(stricmp(szCmd,NOX("PRIVMSG"))==0) { pszTempStr=GetWordNum(0,szRemLine); strncpy(szTarget, pszTempStr, sizeof(szTarget)-1); strncpy(szRemLine, Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+4, sizeof(szRemLine)-1); if(szRemLine[0]==':') { strncpy(szCTCPCmd, GetWordNum(0,szRemLine+1), sizeof(szCTCPCmd)-1); if(szCTCPCmd[strlen(szCTCPCmd)-1]==0x01) szCTCPCmd[strlen(szCTCPCmd)-1]=0x00; } else { strncpy(szCTCPCmd, GetWordNum(0,szRemLine), sizeof(szCTCPCmd)-1); if(szCTCPCmd[strlen(szCTCPCmd)-1]==0x01) szCTCPCmd[strlen(szCTCPCmd)-1]=0x00; } if(szCTCPCmd[0]==0x01) { //Handle ctcp message strncpy(szRemLine, Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+strlen(szCTCPCmd)+6, sizeof(szRemLine)-1); szRemLine[strlen(szRemLine)-1] = '\0';//null out the ending 0x01 if(stricmp(szCTCPCmd+1,NOX("ACTION"))==0) { //Posture snprintf(szResponse, SSIZE(szResponse), "* %s %s", szNick, szRemLine); return szResponse; } if(iMode==MSG_LOCAL) { strncpy(szHackPrefix, Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+4, sizeof(szHackPrefix)-1); szRemLine[strlen(szRemLine)-1] = '\0'; snprintf(szResponse, SSIZE(szResponse), NOX("** CTCP %s %s %s"), szTarget, szCTCPCmd+1, szRemLine); return szResponse; } if(stricmp(szCTCPCmd+1,NOX("PING"))==0) { snprintf(szResponse, SSIZE(szResponse), NOX("/NOTICE %s :\001PING %s\001"), szNick, szRemLine);//Don't need the trailing \001 because szremline has it. SendChatString(szResponse,1); return NULL; } if(stricmp(szCTCPCmd+1,NOX("VERSION"))==0) { return NULL; } strncpy(szRemLine, 1 + GetWordNum(0,Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+4), sizeof(szRemLine)-1); szRemLine[strlen(szRemLine)-1] = '\0'; snprintf(szResponse, SSIZE(szResponse), NOX("** CTCP Message from %s (%s)"), szNick, szRemLine); return szResponse; } //differentiate between channel and private if(szTarget[0]=='#') { pszTempStr=GetWordNum(0,szRemLine); snprintf(szResponse, SSIZE(szResponse), "[%s] %s", szNick, pszTempStr); return szResponse; } else { if(iMode == MSG_LOCAL) { pszTempStr=GetWordNum(0,szRemLine); snprintf(szResponse, SSIZE(szResponse), NOX("Private Message to <%s>: %s"), szNick, pszTempStr); } else { pszTempStr=GetWordNum(0,szRemLine); snprintf(szResponse, SSIZE(szResponse), NOX("Private Message from <%s>: %s"), szNick, pszTempStr); } return szResponse; } } //don't handle any other messages locally. if(iMode==MSG_LOCAL) { return NULL; } if(stricmp(szCmd,NOX("NOTICE"))==0) { pszTempStr=GetWordNum(0,szRemLine); strncpy(szTarget, pszTempStr, sizeof(szTarget)-1); strncpy(szRemLine, Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+4, sizeof(szRemLine)-1); if(szRemLine[0]==':') { strncpy(szCTCPCmd, GetWordNum(0,szRemLine+1), sizeof(szCTCPCmd)-1); if(szCTCPCmd[strlen(szCTCPCmd)-1]==0x01) szCTCPCmd[strlen(szCTCPCmd)-1]=0x00; } else { strncpy(szCTCPCmd, GetWordNum(0,szRemLine), sizeof(szCTCPCmd)-1); if(szCTCPCmd[strlen(szCTCPCmd)-1]==0x01) szCTCPCmd[strlen(szCTCPCmd)-1]=0x00; } if(szCTCPCmd[0]==0x01) { //Handle ctcp message strncpy(szRemLine, Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+strlen(szCTCPCmd)+6, sizeof(szRemLine)-1); szRemLine[strlen(szRemLine)-1] = '\0';//null out the ending 0x01 if(stricmp(szCTCPCmd+1,NOX("PING"))==0) { return NULL; } //Default message strncpy(szRemLine, 1 + GetWordNum(0,Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+4), sizeof(szRemLine)-1); szRemLine[strlen(szRemLine)-1] = '\0'; snprintf(szResponse, SSIZE(szResponse), XSTR("** CTCP Message from %s (%s)", 635), szNick, szRemLine); return szResponse; } snprintf(szResponse, SSIZE(szResponse), "%s", szRemLine); return NULL; } if(stricmp(szCmd,NOX("JOIN"))==0) { //see if it is me! if(stricmp(Nick_name,szNick)==0) { Joined_channel = 1; if(stricmp(szChat_channel,NOX("#autoselect"))==0) { strncpy(szChat_channel, GetWordNum(0,szRemLine), sizeof(szChat_channel)-1); AddChatCommandToQueue(CC_YOURCHANNEL,szChat_channel,strlen(szChat_channel)+1); } } pszTempStr=GetWordNum(0,szRemLine); strncpy(szTarget, pszTempStr, sizeof(szTarget)-1); AddChatUser(szNick); snprintf(szResponse, SSIZE(szResponse), XSTR("** %s has joined %s", 636), szNick, szTarget); return NULL;//szResponse; //Add them to the userlist too! } if(stricmp(szCmd,NOX("PART"))==0) { pszTempStr=GetWordNum(0,szRemLine); strncpy(szTarget, pszTempStr, sizeof(szTarget)-1); strncpy(szRemLine, Line+iPrefixLen+strlen(szCmd)+strlen(szTarget)+3, sizeof(szRemLine)-1); //see if it is me! if(stricmp(Nick_name,szNick)==0) { RemoveAllChatUsers(); } RemoveChatUser(szNick); return NULL; //Remove them to the userlist too! } if(stricmp(szCmd,NOX("KICK"))==0) { pszTempStr=GetWordNum(0,szRemLine); strncpy(szTarget, pszTempStr, sizeof(szTarget)-1); pszTempStr=GetWordNum(1,szRemLine); strncpy(szHackPrefix, pszTempStr, sizeof(szHackPrefix)-1); pszTempStr=GetWordNum(2,szRemLine); //see if it is me! if(stricmp(Nick_name,GetWordNum(1,szRemLine))==0) { //Yup, it's me! szChat_channel[0] = '\0'; AddChatCommandToQueue(CC_KICKED,NULL,0); RemoveAllChatUsers(); } snprintf(szResponse, SSIZE(szResponse), XSTR("*** %s has kicked %s from channel %s (%s)", 637), szNick, szHackPrefix, szTarget, pszTempStr); //Remove them to the userlist too! RemoveChatUser(szNick); return szResponse; } if(stricmp(szCmd,NOX("NICK"))==0) { //see if it is me! if(stricmp(Nick_name,szNick)==0) { //Yup, it's me! strncpy(Nick_name, GetWordNum(0,szRemLine), sizeof(Nick_name)-1); } char nicks[70]; snprintf(nicks, SSIZE(nicks), "%s %s", szNick, GetWordNum(0, szRemLine)); AddChatCommandToQueue(CC_NICKCHANGED,nicks,strlen(nicks)+1); RemoveChatUser(szNick); AddChatUser(GetWordNum(0,szRemLine)); snprintf(szResponse, SSIZE(szResponse), XSTR("*** %s is now known as %s", 638), szNick, GetWordNum(0, szRemLine)); return szResponse; } if(stricmp(szCmd,NOX("PING"))==0) { //respond with pong (GetWordNum(0,szRemLine)) snprintf(szResponse, SSIZE(szResponse), NOX("/PONG :%s"), GetWordNum(0, szRemLine)); SendChatString(szResponse,1); return NULL; } if(stricmp(szCmd,NOX("MODE"))==0) { //Channel Mode info return NULL; } if(stricmp(szCmd, "403")==0) { // ERR_NOSUCHCHANNEL - Used to indicate the given channel name is invalid. Joined_channel = -1; return NULL; } if(stricmp(szCmd,"401")==0) { //This is whois user info, we can get their tracker info from here. -5 char szWhoisUser[33]; memset(szWhoisUser, 0, sizeof(szWhoisUser)); strncpy(szWhoisUser, GetWordNum(1,szRemLine), sizeof(szWhoisUser)-1); Getting_user_tracker_error = 1; Getting_user_channel_error = 1; snprintf(szResponse, SSIZE(szResponse), XSTR("**Error: %s is not online!", 639), szWhoisUser); return szResponse; } if(stricmp(szCmd,"311")==0) { char szWhoisUser[33]; memset(szWhoisUser, 0, sizeof(szWhoisUser)); strncpy(szWhoisUser, GetWordNum(1,szRemLine), sizeof(szWhoisUser)-1); //This is whois user info, we can get their tracker info from here. -5 strncpy(User_req_tracker_id, GetWordNum(5,szRemLine), sizeof(User_req_tracker_id)-1); return NULL; } if(stricmp(szCmd,"319")==0) { char szWhoisUser[33]; memset(szWhoisUser, 0, sizeof(szWhoisUser)); strncpy(szWhoisUser, GetWordNum(1,szRemLine), sizeof(szWhoisUser)-1); //This is whois channel info -- what channel they are on -2 strncpy(User_req_channel, GetWordNum(2,szRemLine), sizeof(User_req_channel)-1); return NULL; } //End of whois and we didn't get a channel means they aren't in a channel. if(stricmp(szCmd,"318")==0) { if(!*User_req_channel) { User_req_channel[0] = '*'; } } if(stricmp(szCmd,"321")==0) { //start of channel list FlushChannelList(); GettingChannelList = 1; return NULL; } if(stricmp(szCmd,"322")==0) { //channel list data if(GettingChannelList == 1) { char channel_list_name[33]; char sztopic[200]; memset(channel_list_name, 0, sizeof(channel_list_name)); memset(sztopic, 0, sizeof(sztopic)); strncpy(sztopic, GetWordNum(3,szRemLine), sizeof(sztopic)-1); strncpy(channel_list_name, GetWordNum(1,szRemLine), sizeof(channel_list_name)-1); AddChannel(channel_list_name,(short)atoi(GetWordNum(2,szRemLine)),sztopic); } return NULL; } if(stricmp(szCmd,"323")==0) { //end of channel list GettingChannelList = 2; return NULL; } if(stricmp(szCmd,"324")==0) { //Channel Mode info return NULL; } if(stricmp(szCmd,"332")==0) { //Channel Topic, update status bar. if(stricmp(szChat_channel,szTarget)==0) { //strncpy(szChanTopic,GetWordNum(2,szRemLine),70); } //sprintf(NewMsg.Message,"*** %s has changed the topic to: %s",szNick,GetWordNum(2,szRemLine)); return NULL; } if(stricmp(szCmd,NOX("TOPIC"))==0) { //Channel Topic, update status bar. if(stricmp(szChat_channel,szTarget)==0) { //strncpy(szChanTopic,GetWordNum(1,szRemLine),70); } //sprintf(NewMsg.Message,"*** %s has changed the topic to: %s",szNick,GetWordNum(1,szRemLine)); return NULL; } if(stricmp(szCmd,NOX("QUIT"))==0) { //Remove the user! RemoveChatUser(szNick); return NULL; } if(stricmp(szCmd,"376")==0) //end of motd, trigger autojoin... { if (!Chat_server_connected) { Chat_server_connected=1; } // end of motd strncpy(szResponse, PXO_CHAT_END_OF_MOTD_PREFIX, sizeof(szResponse)-1); return szResponse; } if((stricmp(szCmd,"377")==0)|| (stricmp(szCmd,"372")==0)) { //Stip the message, and display it. pszTempStr=GetWordNum(3,Line); snprintf(szResponse, SSIZE(szResponse), "%s%s", PXO_CHAT_MOTD_PREFIX, pszTempStr); return szResponse; } //Ignore these messages if(((stricmp(szCmd,"366")==0))|| (stricmp(szCmd,"333")==0) || //Who set the topic (stricmp(szCmd,"329")==0)) //Time Channel created { return NULL; } if(stricmp(szCmd,"353")==0) { //Names in the channel. pszTempStr = GetWordNum(3,Line+iPrefixLen+strlen(szCmd)+2); strncpy(szRemLine, pszTempStr, sizeof(szRemLine)-1); pszTempStr = strtok(szRemLine," "); while(pszTempStr) { if(pszTempStr[0]=='@') { AddChatUser(pszTempStr+1); } else if(pszTempStr[0]=='+') { AddChatUser(pszTempStr+1); } else { AddChatUser(pszTempStr); } pszTempStr=strtok(NULL," "); } return NULL; } //MOTD Codes if((stricmp(szCmd,"001")==0)|| (stricmp(szCmd,"002")==0)|| (stricmp(szCmd,"003")==0)|| (stricmp(szCmd,"004")==0)|| (stricmp(szCmd,"251")==0)|| (stricmp(szCmd,"254")==0)|| (stricmp(szCmd,"255")==0)|| (stricmp(szCmd,"265")==0)|| (stricmp(szCmd,"372")==0)|| (stricmp(szCmd,"375")==0) ) { return NULL; // return szResponse; } if(stricmp(szCmd,"432")==0) { //Channel Mode info snprintf(szResponse, SSIZE(szResponse), "%s", XSTR("Your nickname contains invalid characters", 640)); AddChatCommandToQueue(CC_DISCONNECTED,NULL,0); return szResponse; } if(stricmp(szCmd,"433")==0) { //Channel Mode info char new_nick[33]; snprintf(new_nick, SSIZE(new_nick), "%s%d", Orignial_nick_name, Nick_variety); strncpy(Nick_name, new_nick, sizeof(Nick_name)-1); Nick_variety++; snprintf(szResponse, SSIZE(szResponse), NOX("/NICK %s"), new_nick); SendChatString(szResponse,1); return NULL; } //Default print strncpy(szResponse, Line, sizeof(szResponse)-1); return NULL; }