Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * socket demonstrations:
- * This is the server side of an "internet domain" socket connection, for
- * communicating over the network.
- *
- * In this case we are willing to wait either for chatter from the client
- * _or_ for a new connection.
- */
- #include <stdio.h>
- #include <unistd.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <time.h>
- #ifndef PORT
- #define PORT 28700
- #endif
- struct client {
- int fd;
- struct in_addr ipaddr;
- struct client *next;
- char name[40];
- struct client *fightingwith;
- int hitpoints;
- int powermoves;
- struct client * fightedwith[3];
- int histurn;
- char keypressed;
- };
- static struct client *addclient(struct client *top, int fd, struct in_addr addr);
- static struct client *removeclient(struct client *top, int fd);
- static void broadcast(struct client *top, char *s, int size);
- int handleclient(struct client *p, struct client *top);
- int bindandlisten(void);
- int main(void) {
- int clientfd, maxfd, nready;
- struct client *p;
- struct client *head = NULL;
- socklen_t len;
- struct sockaddr_in q;
- struct timeval tv;
- fd_set allset;
- fd_set rset;
- int i;
- // time_t t;
- // srand((unsigned) time(&t));
- int listenfd = bindandlisten();
- // initialize allset and add listenfd to the
- // set of file descriptors passed into select
- FD_ZERO(&allset);
- FD_SET(listenfd, &allset);
- // maxfd identifies how far into the set to search
- maxfd = listenfd;
- while (1) {
- // make a copy of the set before we pass it into select
- rset = allset;
- /* timeout in seconds (You may not need to use a timeout for
- * your assignment)*/
- tv.tv_sec = 10;
- tv.tv_usec = 0; /* and microseconds */
- nready = select(maxfd + 1, &rset, NULL, NULL, &tv);
- if (nready == 0) {
- printf("DEBUG MESSAGE:No response from clients in %ld seconds\n",
- tv.tv_sec);
- continue;
- }
- if (nready == -1) {
- perror("select");
- continue;
- }
- if (FD_ISSET(listenfd, &rset)) {
- printf("DEBUG MESSAGE:a new player is joining the arena\n");
- len = sizeof(q);
- if ((clientfd = accept(listenfd, (struct sockaddr *) &q, &len))
- < 0) {
- perror("accept");
- exit(1);
- }
- FD_SET(clientfd, &allset);
- if (clientfd > maxfd) {
- maxfd = clientfd;
- }
- printf("DEBUG MESSAGE:connection from %s\n", inet_ntoa(q.sin_addr));
- head = addclient(head, clientfd, q.sin_addr);
- char s[512];
- sprintf(s, "What is your name?\r\n");
- write(clientfd, s, strlen(s));
- }
- for (i = 0; i <= maxfd; i++) {
- if (FD_ISSET(i, &rset)) {
- for (p = head; p != NULL; p = p->next) {
- if (p->fd == i) {
- int result = handleclient(p, head);
- if (result == -1) {
- int tmp_fd = p->fd;
- head = removeclient(head, p->fd);
- FD_CLR(tmp_fd, &allset);
- close(tmp_fd);
- }
- break;
- }
- }
- }
- }
- }
- return 0;
- }
- int handleclient(struct client *p, struct client *top) {
- int inbuf = 0;
- int where;
- char buf[256];
- int len;
- int room = sizeof(buf);
- char *after;
- after = buf;
- while ((len = read(p->fd, after, room)) > 0){
- inbuf += len;
- where = find_network_newline(buf, inbuf);
- if (where >= 0){ // we have a full line
- *(buf + where) = '\n';
- *(buf + where + 1) = '\0';
- //inbuf = inbuf - (where +2);
- //memmove(buf, buf + where + 2, sizeof(buf));
- }
- //room = room - len + where + 2;
- after = buf + inbuf;
- }
- //char buf[256];
- char outbuf[512];
- //int len = read(p->fd, buf, sizeof(buf) - 1);
- if (buf[0] != 'a' && buf[0]!= 'p' && buf[0] != 's'){
- char welcomestring[512];
- sprintf(welcomestring, "Welcome, %s! Awaiting opponent...\r\n",
- buf);
- write(p->fd, welcomestring, strlen(welcomestring));
- char entersarenastring[512];
- sprintf(entersarenastring, "**%s enters the arena**\r\n", buf);
- broadcast(top, entersarenastring, strlen(entersarenastring));
- }
- if (len > 0) {
- buf[len] = '\0';
- if (p->name[0] == 0) {
- strncpy(p->name, buf, strlen(buf));
- p->name[len] = '\0';
- p->name[len - 1] = '\0';
- p->fightedwith[0] = NULL;
- p->fightedwith[1] = NULL;
- p->fightedwith[2] = NULL;
- }
- if (p->fightingwith == NULL) {
- struct client *d;
- for (d = top; d; d = d->next) {
- int didfightwith = 0;
- if (d->fightingwith == NULL && d != p && !didfightwith) {
- d->fightingwith = p;
- p->fightingwith = d;
- d->histurn = 1;
- p->histurn = 0;
- p->hitpoints = (rand() % (30 - 20 + 1) + 20);
- p->powermoves = (rand() % (6 - 2 + 1) + 2);
- d->hitpoints = (rand() % (30 - 20 + 1) + 20);
- d->powermoves = (rand() % (6 - 2 + 1) + 2);
- char youengagestring[512];
- sprintf(youengagestring, "You engage %s!\r\n", d->name);
- write(p->fd, youengagestring, strlen(youengagestring));
- sprintf(youengagestring, "You engage %s!\r\n", p->name);
- write(p->fightingwith->fd, youengagestring,
- strlen(youengagestring));
- char s1[256], s2[256], s3[256], s4[256], s5[256];
- sprintf(s1, "Your hitpoints: %d\n", p->hitpoints);
- write(p->fd, s1, strlen(s1));
- sprintf(s2, "Your powermoves: %d\n", p->powermoves);
- write(p->fd, s2, strlen(s2));
- sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
- p->fightingwith->hitpoints);
- write(p->fd, s3, strlen(s3));
- sprintf(s1, "Your hitpoints: %d\n",
- p->fightingwith->hitpoints);
- write(p->fightingwith->fd, s1, strlen(s1));
- sprintf(s2, "Your powermoves: %d\n",
- p->fightingwith->powermoves);
- write(p->fightingwith->fd, s2, strlen(s2));
- sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
- write(p->fightingwith->fd, s3, strlen(s3));
- if (p->histurn) {
- sprintf(s4,
- "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fd, s4, strlen(s4));
- sprintf(s5, "Waiting for %s to strike...\r\n",
- p->fightingwith->name);
- write(p->fightingwith->fd, s5, strlen(s5));
- } else {
- sprintf(s4,
- "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fightingwith->fd, s4, strlen(s4));
- sprintf(s5, "Waiting for %s to strike...\r\n",
- p->fightingwith->name);
- write(p->fd, s5, strlen(s5));
- }
- }
- }
- } else {
- if (buf[0] == 'a' || buf[0] == 'A'){
- char s9[256];
- char s1[256], s2[256], s3[256];
- int amt = (rand() % (6 - 2 + 1) + 2);
- p->fightingwith->hitpoints -= amt;
- sprintf(outbuf, "You hit %s for %d damage!\r\n",
- p->fightingwith->name, amt);
- write(p->fd, outbuf, strlen(outbuf));
- sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
- p->fightingwith->hitpoints);
- write(p->fd, s3, strlen(s3));
- sprintf(outbuf, "%s hits you for %d damage!\r\n", p->name,
- amt);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- sprintf(s1, "Your hitpoints: %d\n",
- p->fightingwith->hitpoints);
- write(p->fightingwith->fd, s1, strlen(s1));
- sprintf(s2, "Your powermoves: %d\n",
- p->fightingwith->powermoves);
- write(p->fightingwith->fd, s2, strlen(s2));
- sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
- write(p->fightingwith->fd, s3, strlen(s3));
- sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fightingwith->fd, s9, strlen(s9));
- p->histurn = 0;
- p->fightingwith->histurn = 1;
- p->keypressed = '0';
- }
- if (buf[0]== 's' || buf[0]== 'S') {
- read(p->fd, buf, sizeof(buf) - 1);
- sprintf(outbuf, "%s takes a break to tell you:\r\n%s\r\n",
- p->name, buf);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- p->histurn = 1;
- p->fightingwith->histurn = 0;
- p->keypressed = '0';
- }
- if (buf[0] == 'p' || buf[0] == 'P'){
- char s9[256];
- char s1[256], s2[256], s3[256];
- int amt = 3 * (rand() % (6 - 2 + 1) + 2);
- if ((rand() % 10) > 4) {
- p->fightingwith->hitpoints -= amt;
- p->powermoves -= 1;
- sprintf(outbuf, "You hit %s for %d damage!\r\n",
- p->fightingwith->name, amt);
- write(p->fd, outbuf, strlen(outbuf));
- sprintf(outbuf, "%s hits you for %d damage!\r\n",
- p->name, amt);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- //sprintf(s8,
- //"(a)ttack\n(p)owermove\n(s)peak something\r\n");
- //write(p->fightingwith->fd, s8, strlen(s8));
- sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
- p->fightingwith->hitpoints);
- write(p->fd, s3, strlen(s3));
- sprintf(s1, "Your hitpoints: %d\n",
- p->fightingwith->hitpoints);
- write(p->fightingwith->fd, s1, strlen(s1));
- sprintf(s2, "Your powermoves: %d\n",
- p->fightingwith->powermoves);
- write(p->fightingwith->fd, s2, strlen(s2));
- sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
- write(p->fightingwith->fd, s3, strlen(s3));
- sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fightingwith->fd, s9, strlen(s9));
- p->histurn = 0;
- p->fightingwith->histurn = 1;
- p->keypressed = '0';
- //
- } else {
- p->powermoves -= 1;
- sprintf(outbuf, "Your attack missed!\r\n");
- write(p->fd, outbuf, strlen(outbuf));
- sprintf(outbuf, "%s's attack missed!\r\n", p->name);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- sprintf(s3, "%s's hitpoints: %d\n", p->fightingwith->name,
- p->fightingwith->hitpoints);
- write(p->fd, s3, strlen(s3));
- sprintf(s1, "Your hitpoints: %d\n",
- p->fightingwith->hitpoints);
- write(p->fightingwith->fd, s1, strlen(s1));
- sprintf(s2, "Your powermoves: %d\n",
- p->fightingwith->powermoves);
- write(p->fightingwith->fd, s2, strlen(s2));
- sprintf(s3, "%s's hitpoints: %d\n", p->name, p->hitpoints);
- write(p->fightingwith->fd, s3, strlen(s3));
- sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fightingwith->fd, s9, strlen(s9));
- p->histurn = 0;
- p->fightingwith->histurn = 1;
- p->keypressed = '0';
- }
- }
- // Arda's shit
- if (!(p->hitpoints > 0)) {
- char nomatchstring[512];
- sprintf(nomatchstring,
- "You are no match for %s. You scurry away...\r\n",
- p->fightingwith->name);
- write(p->fd, nomatchstring, strlen(nomatchstring));
- char givesupstring[512];
- sprintf(givesupstring, "%s gives up. You win!\r\n", p->name);
- write(p->fightingwith->fd, givesupstring,
- strlen(givesupstring));
- p->hitpoints = (rand() % (30 - 20 + 1) + 20);
- p->powermoves = (rand() % (6 - 2 + 1) + 2);
- p->fightingwith->hitpoints = (rand() % (30 - 20 + 1) + 20);
- p->fightingwith->powermoves = (rand() % (6 - 2 + 1) + 2);
- p->fightingwith = NULL;
- p->fightingwith->fightingwith = NULL;
- } else {
- if ((p->keypressed == 'a' || p->keypressed == 'A')
- && p->histurn) {
- char s9[256];
- int amt = (rand() % (6 - 2 + 1) + 2);
- p->fightingwith->hitpoints -= amt;
- sprintf(outbuf, "You hit %s for %d damage!\r\n",
- p->fightingwith->name, amt);
- write(p->fd, outbuf, strlen(outbuf));
- sprintf(outbuf, "%s hits you for %d damage!\r\n", p->name,
- amt);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- sprintf(s9, "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fightingwith->fd, s9, strlen(s9));
- p->histurn = 0;
- p->fightingwith->histurn = 1;
- p->keypressed = '0';
- }
- if ((p->keypressed == 's' || p->keypressed == 'S')
- && p->histurn) {
- read(p->fd, buf, sizeof(buf) - 1);
- sprintf(outbuf, "%s takes a break to tell you:\r\n%s\r\n",
- p->name, buf);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- p->histurn = 1;
- p->fightingwith->histurn = 0;
- p->keypressed = '0';
- }
- if ((p->keypressed == 'p' || p->keypressed == 'P')
- && p->histurn) {
- int amt = 3 * (rand() % (6 - 2 + 1) + 2);
- if ((rand() % 10) > 4) {
- char s8[256];
- p->fightingwith->hitpoints -= amt;
- p->powermoves -= 1;
- sprintf(outbuf, "You hit %s for %d damage!\r\n",
- p->fightingwith->name, amt);
- write(p->fd, outbuf, strlen(outbuf));
- sprintf(outbuf, "%s hits you for %d damage!\r\n",
- p->name, amt);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- sprintf(s8,
- "(a)ttack\n(p)owermove\n(s)peak something\r\n");
- write(p->fightingwith->fd, s8, strlen(s8));
- p->histurn = 0;
- p->fightingwith->histurn = 1;
- } else {
- p->powermoves -= 1;
- sprintf(outbuf, "Your attack missed!\r\n");
- write(p->fd, outbuf, strlen(outbuf));
- sprintf(outbuf, "%s's attack missed!\r\n", p->name);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- p->histurn = 0;
- p->fightingwith->histurn = 1;
- }
- }
- if (!(p->keypressed == 's' || p->keypressed == 'S')
- && !p->histurn) {
- char s5[256];
- sprintf(s5, "Waiting for %s to strike...\r\n",
- p->fightingwith->name);
- write(p->fd, s5, strlen(s5));
- p->keypressed = '0';
- }
- }
- }
- printf("DEBUG MESSAGE:Received %d bytes: %s", len, buf);
- return 0;
- } else if (len == 0) {
- // socket is closed
- printf("DEBUG MESSAGE:Disconnect from %s\n", inet_ntoa(p->ipaddr));
- if (p->fightingwith) {
- sprintf(outbuf, "--%s dropped. You win!\r\n", p->name);
- write(p->fightingwith->fd, outbuf, strlen(outbuf));
- p->fightingwith->fightingwith = NULL;
- }
- sprintf(outbuf, "**%s leaves**\r\n", p->name);
- broadcast(top, outbuf, strlen(outbuf));
- return -1;
- } else { // shouldn't happen
- perror("read");
- return -1;
- }
- }
- /* bind and listen, abort on error
- * returns FD of listening socket
- */
- int bindandlisten(void) {
- struct sockaddr_in r;
- int listenfd;
- if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("socket");
- exit(1);
- }
- int yes = 1;
- if ((setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)))
- == -1) {
- perror("setsockopt");
- }
- memset(&r, '\0', sizeof(r));
- r.sin_family = AF_INET;
- r.sin_addr.s_addr = INADDR_ANY;
- r.sin_port = htons(PORT);
- if (bind(listenfd, (struct sockaddr *) &r, sizeof r)) {
- perror("bind");
- exit(1);
- }
- if (listen(listenfd, 5)) {
- perror("listen");
- exit(1);
- }
- return listenfd;
- }
- static struct client *addclient(struct client *top, int fd, struct in_addr addr) {
- struct client *p = malloc(sizeof(struct client));
- if (!p) {
- perror("malloc");
- exit(1);
- }
- //printf("Adding client %s\n", inet_ntoa(addr));
- p->fd = fd;
- p->ipaddr = addr;
- p->next = top;
- p->name[0] = 0;
- p->fightingwith = NULL;
- top = p;
- return top;
- }
- static struct client *removeclient(struct client *top, int fd) {
- struct client **p;
- for (p = ⊤ *p && (*p)->fd != fd; p = &(*p)->next)
- ;
- // Now, p points to (1) top, or (2) a pointer to another client
- // This avoids a special case for removing the head of the list
- if (*p) {
- struct client *t = (*p)->next;
- printf("Removing client %d %s\n", fd, inet_ntoa((*p)->ipaddr));
- free(*p);
- *p = t;
- } else {
- fprintf(stderr, "Trying to remove fd %d, but I don't know about it\n",
- fd);
- }
- return top;
- }
- static void broadcast(struct client *top, char *s, int size) {
- struct client *p;
- for (p = top; p; p = p->next) {
- write(p->fd, s, size);
- }
- /* should probably check write() return value and perhaps remove client */
- }
- int find_network_newline(char *buf, int inbuf) {
- // Step 1: write this function
- int i;
- for (i = 0; i < inbuf; i++){
- if (buf[i] == '\r'){
- return i;
- }
- }
- return -1; // return the location of '\r' if found
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement