Overwriting problem with IRC bot

Ok, so this is kinda complicated and I'm completely stumped.

I'm writing a bot for IRC that will play blackjack. I used a skeleton for a bot that I found online (since I'm not familiar with sockets and whatnot) and I've been modifying it for my needs.

In the beginning, there is this:
1
2
3
4
5
6
...
int playerNumber = 0;
char * playerName1;
char * playerName2;
char * playerName3;
...



The bot listens to chat and waits for commands. The command I'm having trouble with is the ?join command that is used to join the game. Within the ?join command I have:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
...
else if (playerNumber == 1) {
  if (sMessage->cUserNick != playerName1) {
    sockPRINT(strSocket, "\r\nPRIVMSG %s :%c13,0%s has joined the table.\r\n", sMessage->cTarget, 3, sMessage->cUserNick);
    playerName2 = sMessage->cUserNick;
    ++playerNumber;
  } else sockPRINT(strSocket, "\r\nPRIVMSG %s :%c4,0%s has already joined the table!\r\n", sMessage->cTarget, 3, sMessage->cUserNick);
}

else if (playerNumber == 0) {
  sockPRINT(strSocket, "\r\nPRIVMSG %s :%c13,0%s has joined the table.\r\n", sMessage->cTarget, 3, sMessage->cUserNick);
  playerName1 = sMessage->cUserNick;
  ++playerNumber;
}
...


So, the first player does ?join and his name (sMessage->cUserNick) is stored in playerName1. Then, when another player does ?join, the program checks to make sure that he's not already playing (sMessage->cUserNick != playerName1) and then stores his name into playerName2.

The problem is that when I actually run the program, the first player joins fine, but the second player gets the "already joined" error. Upon further inspection, I found that when the second player does ?join, his name is overwritten in playerName1 before the program even gets to this part of the code! There is no other place in the entire program where I have playerName1 = sMessage->cUserNick;
and the program shouldn't be able to overwrite playerName1 since playerNumber == 2 when the second player tries to join!

I think this might be a problem with pointers that I'm not aware of. If you could offer any help, I'd really appreciate it! Thanks in advance!!



Last edited on
closed account (S6k9GNh0)
I would suggest you make a vector since the number of players are unspecified and then work through vector iterations instead of hardcoding the player numbers.
Thanks for the suggestion, but I don't think that would solve my playerName problem. ;)
Oh yes it would.
http://cplusplus.com/reference/stl/vector/push_back/

-Albatross

EDIT: 14 posts, and counting.
Last edited on
That still doesn't explain why this code doesn't work. Regardless if I store the player names as char * or in a vector, I'd still have this problem, wouldn't I?
Unless I'm missing something about the fundamental structure of your code, no. push_back() shouldn't ever overwrite anything, and you said you have an overwrite problem (and I'm also assuming this program is never run client-side). As to why you have this error, I need to pop down to the grocery store for some more high-test caffeine.

-Albatross
Last edited on
Right, the problem is the overwrite thing.

When I did my test, this is what happened:

Before player 1 joins, playerNumber = 0 (correct) playerName1 = (null) (correct) and playerName2 = (null) (correct)

After player 1 joins, playerNumber = 1 (correct) playerName1 = player 1 (correct) and playerName2 = (null) (correct)

After player 2 joins, playerNumber = 1 (INCORRECT) playerName1 = player 2 (INCORRECT) and playerName2 = (null) (INCORRECT)

So, like I said, somehow player 2's name is getting stored in playerName1, but there's no place in the code where this could happen. I still think it might be a pointer problem... Thanks for the help, though!
So, I went back, rewrote some things with vectors to make it simpler, eliminated everything but the ?join command that is giving me problems, and still have the same problem. Here's the code, compile it with Winsock v.2 if you want, but I'd really like to know what's going on!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
#include <winsock.h>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <vector>

#define SERVER "irc.SERVERNAMEHERE.com"
#define PORT 6667
#define TIMEOUT 10
#define NICK "NICKHERE"
#define CHAN "#CHANNELHERE"

using namespace std;


vector<char*> playerName;

// UNCHANGED BOT PROGRAM
typedef struct {
    char *cUserNick;                 // Nickname of user (eg: Tux)
    char *cUserHost;                 // Userhost of user (eg: lenience.com)
    char *cUserName;                 // Username of user (eg: root)
    char *cTarget;                   // Pointer to channel or private chat nick...
    char *cMessage;                  // Message sent by user
} Message_Struct;

bool arrayShift(char *cBuffer);
int socketConnect(SOCKET *connection, char *HName, int Port);
int sockPRINT(SOCKET *strSocket, char* cMessage, ...);
int parseARGS(char **args, char *line);
int parseMessage(SOCKET *strSocket, Message_Struct *sMessage);

int main(int argc, char *argv[]) {
    char cBuffer[512];
    char cOutBuffer[512];
    char *lineSPLIT[512];
    char *args[10];
    int bRecv;
    SOCKET strSocket;
    Message_Struct sMessage;

    int tries;
    for(tries=1; socketConnect(&strSocket, SERVER, PORT)!=0; tries++) {
        printf("Failed attempt: %d\r\n",tries);
        Sleep(TIMEOUT*1000);
    }

    sockPRINT(&strSocket, "USER %s \"\" \"127.0.0.1\" :%s\r\n", NICK, NICK);
    sockPRINT(&strSocket, "NICK %s\r\n", NICK);
    Sleep(100);

    sockPRINT(&strSocket, "JOIN %s\r\n", CHAN);
    printf("Success!\n");

    while(1) {
        memset(cBuffer, 0, 512);
        memset(cOutBuffer, 0, 512);

        bRecv = recv(strSocket, cBuffer, 512, 0);
        if( (bRecv == 0) || (bRecv == SOCKET_ERROR) ) break;

        if(cBuffer[0]!=':') {
            strcpy(cOutBuffer, "PONG :");
            sockPRINT(&strSocket, cOutBuffer);
        } else {
            sMessage.cUserNick = strtok(cBuffer, "!");
            arrayShift(sMessage.cUserNick);
            sMessage.cUserName = strtok(NULL, "@");
            sMessage.cUserHost = strtok(NULL, " "); //THE SENDER IP
            strtok(NULL, " "); //THE PRIVMSG
            sMessage.cTarget = strtok(NULL, " "); //RECEIVED IN CHAT ON CHANNEL / NICK
            sMessage.cMessage = strtok(NULL, "\r\n"); //THE MESSAGE WITH A :

            parseMessage(&strSocket, &sMessage);
        }  
    }
    closesocket(strSocket);
    return (1);
}

bool arrayShift(char *cBuffer) {
    for(int i=0; i<strlen(cBuffer); i++) cBuffer[i]=cBuffer[i+1];
    cBuffer[strlen(cBuffer)]='\0';
    return (1);
}

int socketConnect(SOCKET *connection, char *HName, int Port) {
    SOCKADDR_IN serverInfo;
    WSADATA wsaData;
    LPHOSTENT hostEntry;
    if (WSAStartup(MAKEWORD(1, 1), &wsaData) == -1) return (-1);
    if (!(hostEntry = gethostbyname(HName))) {
        WSACleanup();
        return (-1);
    }
    if ((*connection = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) {
        WSACleanup();
        return (-1);
    }
    serverInfo.sin_family = AF_INET;
    serverInfo.sin_addr = *((LPIN_ADDR)*hostEntry->h_addr_list);
    serverInfo.sin_port = htons(Port);
    if (connect(*connection, (LPSOCKADDR)&serverInfo, sizeof(struct sockaddr)) == SOCKET_ERROR) {
        WSACleanup();
        return (-1);
    }
    return (0);
}

int sockPRINT(SOCKET *strSocket, char* cMessage, ...) {
    char cBuffer[512];
    int iError;
    va_list va;
    va_start(va, cMessage);
    vsprintf(cBuffer, cMessage, va);
    va_end(va);
    send(*strSocket, cBuffer, strlen(cBuffer), 0);
    return 1;
}

int parseARGS(char **args, char *line){
int tmp=0;
args[tmp] = strtok( line, "|" );
while ( (args[++tmp] = strtok(NULL, "|" ) ) != NULL );
return tmp - 1;
}
//END UNCHANGED BOT PROGRAM

int parseMessage(SOCKET *strSocket, Message_Struct *sMessage) {
    char *argv[512];
    int argc = parseARGS(argv, sMessage->cMessage);
    
    //JOIN ROUTINE
    else if (argv[0]!= NULL && !strcmp(argv[0], ":?join")) {
         
         int i;
         bool joinError = FALSE;
         
         for (i=0; i<playerName.size(); ++i) {
             if (playerName[i] == sMessage->cUserNick) joinError = TRUE; //  checks to see if player is already in game
         }
         
         if (joinError == FALSE) {
             sockPRINT(strSocket, "\r\nPRIVMSG %s :%c4,0%s has joined the table!\r\n", sMessage->cTarget, 3, sMessage->cUserNick);
             playerName.push_back(sMessage->cUserNick);
         } else sockPRINT(strSocket, "\r\nPRIVMSG %s :%c4,0%s has already joined the table!.\r\n", sMessage->cTarget, 3, sMessage->cUserNick);
    }
    return 0;
}


Please, any ideas!?
Last edited on
You can't compare C strings with ==, since they're just char pointers. == will compare whether both pointers point to the same string, not if the strings pointed to are equal.
If I were you, I would look for a C++ bot skeleton. This code is purely C, with all the ugliness that comes with it.
Thanks for the suggestion. I tried using strcmp() instead of == and I still got the same error. I'll try rewriting the bot skeleton in C++ and see if that helps.
Found the problem. It was trying to copy the cUserNick (a char*) to playerName (also a char*) which are both pointers. So the playerName was changing everytime cUserNick changed. DUH! XD

Thanks everyone.
Topic archived. No new replies allowed.