/** * Call it to close the connection. It returns immediately */ void DisconnectFromChatServer() { if(!Socket_connected) return; SendChatString(NOX("/QUIT"),1); shutdown(Chatsock,2); closesocket(Chatsock); Socket_connecting = 0; Socket_connected = 0; Input_chat_buffer[0] = '\0'; if(User_list) { vm_free(User_list); User_list = NULL; } if(Chan_list) { vm_free(Chan_list); Chan_list = NULL; } Chat_server_connected = 0; Joining_channel = 0; Joined_channel = 0; RemoveAllChatUsers(); FlushChatCommandQueue(); return; }
char *GetChannelByUser(char *nickname) { char szWhoisCmd[100]; if(GettingUserChannel) { if(Getting_user_channel_error) { Getting_user_channel_error = 0; GettingUserChannel = 0; return (char *)-1; } if(*User_req_channel) { GettingUserChannel = 0; return User_req_channel; } } else { strncpy(Getting_user_channel_info_for, nickname, sizeof(Getting_user_channel_info_for)-1); User_req_channel[0] = '\0'; snprintf(szWhoisCmd, SSIZE(szWhoisCmd), NOX("/WHOIS %s"), nickname); SendChatString(szWhoisCmd,1); GettingUserChannel = 1; } return NULL; }
char *GetTrackerIdByUser(char *nickname) { char szWhoisCmd[100]; if(GettingUserTID) { if(Getting_user_tracker_error) { Getting_user_tracker_error = 0; GettingUserTID = 0; return (char *)-1; } if(*User_req_tracker_id) { GettingUserTID = 0; return User_req_tracker_id; } } else { strncpy(Getting_user_tracker_info_for, nickname, sizeof(Getting_user_tracker_info_for)-1); snprintf(szWhoisCmd, SSIZE(szWhoisCmd), NOX("/WHOIS %s"), nickname); User_req_tracker_id[0] = '\0'; SendChatString(szWhoisCmd,1); GettingUserTID = 1; } return NULL; }
// Call this to set/join a channel. Since we can't be sure that we will be // able to join that channel, check it for completion // You can't be in more than one channel at a time with this API, so you // leave the current channel before trying to join // a new one. Because of this if the join fails, make sure you try to join // another channel, or the user won't be able to chat //-1 Failed to join // 0 joining // 1 successfully joined int SetNewChatChannel(char *channel) { char partstr[100]; if(!Socket_connected) return -1; partstr[sizeof(partstr)-1] = '\0'; if(Joining_channel==1) { if(Joined_channel==1) { //We made it in! Joining_channel = 0; return 1; } else if(Joined_channel==-1) { //Error -- we got a message that the channel was invite only, or we were banned or something Joining_channel = 0; strcpy_s(szChat_channel, ""); return -1; } } else { if(szChat_channel[0]) { snprintf(partstr, SSIZE(partstr), NOX("/PART %s"), szChat_channel); SendChatString(partstr,1); } strncpy(szChat_channel, channel, sizeof(szChat_channel)-1); snprintf(partstr, SSIZE(partstr), NOX("/JOIN %s"), szChat_channel); SendChatString(partstr,1); Joining_channel = 1; Joined_channel = 0; } return 0; }
uint32 CreatureTextMgr::SendChat(Creature* source, uint8 textGroup, uint64 whisperGuid /*= 0*/, ChatMsg msgType /*= CHAT_MSG_ADDON*/, Language language /*= LANG_ADDON*/, TextRange range /*= TEXT_RANGE_NORMAL*/, uint32 sound /*= 0*/, Team team /*= TEAM_OTHER*/, bool gmOnly /*= false*/, Player* srcPlr /*= NULL*/) { if (!source) return 0; CreatureTextMap::const_iterator sList = mTextMap.find(source->GetEntry()); if (sList == mTextMap.end()) { sLog->outErrorDb("CreatureTextMgr: Could not find Text for Creature(%s) Entry %u in 'creature_text' table. Ignoring.", source->GetName(), source->GetEntry()); return 0; } CreatureTextHolder TextHolder = (*sList).second; CreatureTextHolder::const_iterator itr = TextHolder.find(textGroup); if (itr == TextHolder.end()) { sLog->outErrorDb("CreatureTextMgr: Could not find TextGroup %u for Creature(%s) GuidLow %u Entry %u. Ignoring.", uint32(textGroup), source->GetName(), source->GetGUIDLow(), source->GetEntry()); return 0; } CreatureTextGroup TextGroup = (*itr).second;//has all texts in the group CreatureTextRepeatIds repeatGroup = GetRepeatGroup(source, textGroup);//has all textIDs from the group that were already said CreatureTextGroup tempGroup;//will use this to talk after sorting repeatGroup for (CreatureTextGroup::const_iterator giter = TextGroup.begin(); giter != TextGroup.end(); ++giter) { if (std::find(repeatGroup.begin(), repeatGroup.end(), (*giter).id) == repeatGroup.end()) tempGroup.push_back((*giter)); } if (tempGroup.empty()) { CreatureTextRepeatMap::iterator mapItr = mTextRepeatMap.find(source->GetGUID()); if (mapItr != mTextRepeatMap.end()) { CreatureTextRepeatGroup::iterator groupItr = (*mapItr).second.find(textGroup); (*groupItr).second.clear(); } tempGroup = TextGroup; } uint8 count = 0; float lastChance = -1; bool isEqualChanced = true; float totalChance = 0; for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter) { if (lastChance >= 0 && lastChance != (*iter).probability) isEqualChanced = false; lastChance = (*iter).probability; totalChance += (*iter).probability; count++; } int32 offset = -1; if (!isEqualChanced) { for (CreatureTextGroup::const_iterator iter = tempGroup.begin(); iter != tempGroup.end(); ++iter) { uint32 chance = uint32((*iter).probability); uint32 r = urand(0, 100); offset++; if (r <= chance) break; } } uint32 pos = 0; if (isEqualChanced || offset < 0) pos = urand(0, count - 1); else if (offset >= 0) pos = offset; CreatureTextGroup::const_iterator iter = tempGroup.begin() + pos; ChatMsg finalType = (msgType == CHAT_MSG_ADDON) ? (*iter).type : msgType; Language finalLang = (language == LANG_ADDON) ? (*iter).lang : language; uint32 finalSound = sound ? sound : (*iter).sound; if (finalSound) SendSound(source, finalSound, finalType, whisperGuid, range, team, gmOnly); if ((*iter).emote) SendEmote(srcPlr ? srcPlr->ToUnit() : source, (*iter).emote); SendChatString(srcPlr ? srcPlr->ToUnit() : source, (*iter).text.c_str(), finalType, finalLang, whisperGuid, range, team, gmOnly); if (isEqualChanced || (!isEqualChanced && totalChance == 100.0f)) SetRepeatId(source, textGroup, (*iter).id); return (*iter).duration; }
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; }
// Return codes: //-2 Already connected //-1 Failed to connect // 0 Connecting // 1 Connected // Call it once with the server IP address, and it will return immediately // with 0. Keep calling it until it returns something other than 0 // note: the nickname may be changed if someone with that name already // exists (Scourge1 for instance) int ConnectToChatServer(char *serveraddr, char *nickname, char *trackerid) { short chat_port; char chat_server[50]; char *p; unsigned long argp = 1; char signon_str[100]; if(!Socket_connecting) { unsigned long iaddr; strncpy(Nick_name, nickname, sizeof(Nick_name)-1); strncpy(Orignial_nick_name, nickname, sizeof(Orignial_nick_name)-1); strncpy(Chat_tracker_id, trackerid, sizeof(Chat_tracker_id)-1); Firstuser = NULL; Firstcommand = NULL; Chat_server_connected = 0; FlushChatCommandQueue(); p = strchr(serveraddr,':'); if(NULL==p) { return -1; } memset(chat_server, 0, sizeof(chat_server)); strncpy(chat_server,serveraddr,(p-serveraddr)); chat_server[p-serveraddr] = '\0'; chat_port = (short)atoi(p+1); if(0==chat_port) { return -1; } Chatsock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if(INVALID_SOCKET == Chatsock) { return -1; } memset( &Chataddr, 0, sizeof(SOCKADDR_IN) ); Chataddr.sin_family = AF_INET; Chataddr.sin_addr.s_addr = INADDR_ANY; Chataddr.sin_port = 0; if (SOCKET_ERROR==bind(Chatsock, (SOCKADDR*)&Chataddr, sizeof (sockaddr))) { return -1; } ioctlsocket(Chatsock, FIONBIO, &argp); // first try and resolve by name iaddr = inet_addr( chat_server ); if ( iaddr == INADDR_NONE ) { HOSTENT *he; he = gethostbyname(chat_server); if(!he) { return 0; } memcpy(&iaddr, he->h_addr_list[0],4); } memcpy(&Chataddr.sin_addr.s_addr, &iaddr,4); Chataddr.sin_port = htons( chat_port ); if(SOCKET_ERROR == connect(Chatsock,(SOCKADDR *)&Chataddr,sizeof(SOCKADDR_IN))) { if(WSAEWOULDBLOCK == WSAGetLastError()) { Socket_connecting = 1; return 0; } } else { //This should never happen, connect should always return WSAEWOULDBLOCK Socket_connecting = 1; Socket_connected = 1; return 1; } } else { if(Chat_server_connected) { return 1; } if(!Socket_connected) { //Do a few select to check for an error, or to see if we are writeable (connected) fd_set write_fds,error_fds; struct timeval timeout; timeout.tv_sec=0; timeout.tv_usec=0; FD_ZERO(&write_fds); FD_SET(Chatsock, &write_fds); //Writable -- that means it's connected if (select(Chatsock+1, NULL, &write_fds, NULL, &timeout) > 0) { // make sure that we don't have any connect() errors (since it's non-blocking) int err_val = 0; size_t err_val_size = sizeof(err_val); getsockopt(Chatsock, SOL_SOCKET, SO_ERROR, (char*)&err_val, (socklen_t*)&err_val_size); if (err_val) { if (err_val != WSAEWOULDBLOCK) { return -1; } return 0; } Socket_connected = 1; memset(signon_str, 0, sizeof(signon_str)); snprintf(signon_str, SSIZE(signon_str), NOX("/USER %s %s %s :%s"), NOX("user"), NOX("user"), NOX("user"), Chat_tracker_id); SendChatString(signon_str, 1); snprintf(signon_str, SSIZE(signon_str), NOX("/NICK %s"), Nick_name); SendChatString(signon_str,1); return 0; //Now we are waiting for Chat_server_connected } FD_ZERO(&error_fds); FD_SET(Chatsock,&error_fds); //error -- that means it's not going to connect if ( select(Chatsock+1, NULL, NULL, &error_fds, &timeout) ) { return -1; } return 0; } } return 0; }