// Run like this: simple_client address port // Results in argv ["./simple_client", "address", "port"] #include #include #include #include #include #include #include #include #include #include using namespace std; struct game_header { unsigned char mtype; uint16_t points, stat_limit, description_length; } __attribute__((packed)); struct character { uint8_t type; char name[32]; uint8_t flags; uint16_t attack; uint16_t defense; uint16_t regen; int16_t health; uint16_t gold; uint16_t room; uint16_t dlen; string description; } __attribute__((packed)); struct room { // or connection, they're the same except for the type uint8_t type; uint16_t number; char name[32]; uint16_t dlen; string description; } __attribute__((packed)); int main(int args, char ** argv){ struct sockaddr_in sad; sad.sin_port = htons(atoi(argv[2])); sad.sin_family = AF_INET; int skt = socket(AF_INET, SOCK_STREAM, 0); struct hostent* entry = gethostbyname(argv[1]); struct in_addr **addr_list = (struct in_addr**)entry->h_addr_list; struct in_addr* c_addr = addr_list[0]; char* ip_string = inet_ntoa(*c_addr); sad.sin_addr = *c_addr; printf("Connecting to: %s\n", ip_string); connect(skt, (struct sockaddr*)&sad, sizeof(struct sockaddr_in)); unsigned char stuff[3]; read(skt, &stuff, 3); uint16_t extension_length; read(skt, &extension_length, sizeof(uint16_t)); printf("Message Type: %u\n", stuff[0]); printf("Version: %u.%u\n", stuff[1], stuff[2]); printf("Extension Length: %u\n", extension_length); // We'll use a struct this time, for variety struct game_header gh; recv(skt, &gh, sizeof(gh), MSG_WAITALL); printf("Type: %u\nInitial Points: %u\nStat Limit: %u\nDescription Length: %u\n", gh.mtype, gh.points, gh.stat_limit, gh.description_length); char description[gh.description_length + 1]; recv(skt, description, gh.description_length, 0); description[gh.description_length] = 0; printf("Description: %s\n", description); struct character us; us.type = 10; strcpy(us.name, "Class Bot"); us.flags = 0xff; us.attack = gh.points; us.defense = 0; us.regen = 0; us.health = 0; // server will make these up anyway us.room = 0; us.gold = 0; us.description = "This is a person pretending to be a bot\n"; us.dlen = us.description.length(); write(skt, &us, 48); write(skt, us.description.c_str(), us.dlen); char type; type = 6; write(skt, &type, 1); // sends a start for(;;){ read(skt, &type, 1); if(type == 8){ printf("Server sent an accept\n"); read(skt, &type, 1); printf("It accepted a type %d\n", type); } else if(type == 7){ printf("The server doesn't like us because it's mean\n"); read(skt, &type, 1); printf("Error code was %d\n", type); uint16_t errorlen; read(skt, &errorlen, 2); char error[errorlen]; recv(skt, error, errorlen, MSG_WAITALL); printf("Got error message %s\n", error); } else if(type == 10){ struct character whatwegot; whatwegot.type = 10; recv(skt, 1 + (char*)&whatwegot, 47, MSG_WAITALL); char description[whatwegot.dlen + 1]; recv(skt, description, whatwegot.dlen, MSG_WAITALL); description[whatwegot.dlen] = 0; whatwegot.description = description; // copy the C string into a C++ string printf("Character %s : %s\n", whatwegot.name, whatwegot.description.c_str()); } else if(type == 13 || type == 9){ struct room rm; rm.type = 13; recv(skt, 1 + (char*)&rm, 36, MSG_WAITALL); char description[rm.dlen + 1]; recv(skt, description, rm.dlen, MSG_WAITALL); description[rm.dlen] = 0; rm.description = description; // copy the C string into a C++ string if(type == 9){ printf("We're in room %d (%s)\n", rm.number, rm.name); continue; } // Let's go to that connection! printf("Let's go to room %d (%s) : %s\n", rm.number, rm.name, rm.description.c_str()); type = 2; write(skt, &type, 1); write(skt, &rm.number, 2); } else if(type == 1){ char name[32]; uint16_t len; read(skt, &len, 2); recv(skt, name, 32, MSG_WAITALL); printf("Message from %s ", name); recv(skt, name, 32, MSG_WAITALL); printf(" to %s:", name); char message[len]; recv(skt, message, len, MSG_WAITALL); printf("%s\n", message); } } close(skt); return 0; }