void disconnectPlayer(int p) { int socket = connection[p].socket; connection[p].echo = 0; playerLeave(p); close(connection[p].socket); FD_CLR(connection[p].socket, &master); connection[p].socket = 0; connection[p].bot = 0; printf("socket %d closed\n", socket); }
void stepNetwork(void) { int i, k, pi, pi2, nbytes, newfd; char remoteIP[INET6_ADDRSTRLEN]; struct sockaddr_storage remoteaddr; socklen_t addrlen; struct timeval tv; if(getDeathMessage(sendbuf)) { for(k = 0; k < conf.maxPlayers; ++k) { if(connection[k].socket && !connection[k].bot) { snd(connection[k].socket, "\r\n"); snd(connection[k].socket, sendbuf); snd(connection[k].socket, "\r\n> "); } } } tv.tv_sec = 0; tv.tv_usec = 1; readfds = master; if(select(fdmax + 1, &readfds, NULL, NULL, &tv) == -1) { print_error("select"); exit(5); } for(i = 0; i <= fdmax; ++i) { if(FD_ISSET(i, &readfds)) { if(i == listener) { addrlen = sizeof remoteaddr; newfd = accept(listener, (struct sockaddr *)&remoteaddr, &addrlen); if(newfd == -1) { print_error("accept"); } else { getnameinfo((struct sockaddr *)&remoteaddr, addrlen, remoteIP, sizeof remoteIP, NULL, 0, NI_NUMERICHOST | NI_NUMERICSERV); for(k = 0; k < conf.maxPlayers; ++k) { if(connection[k].socket == 0) { connection[k].socket = newfd; strncpy(connection[k].remoteIP,remoteIP,INET6_ADDRSTRLEN); playerJoin(k); updateName(k, "Anonymous"); allSendPlayerPos(k); break; } } if(k == conf.maxPlayers) { close(newfd); printf("new connection from %s on socket %d refused: max connections\n", remoteIP, newfd); } else { FD_SET(newfd, &master); if(newfd > fdmax) { fdmax = newfd; } printf("new connection from %s on socket %d accepted\n", remoteIP, newfd); snd(newfd, WELCOME); } } } else { if((nbytes = recv(i, buf, sizeof buf, 0)) <= 0) { if(nbytes == 0) { printf("socket %d hung up\n", i); } else { print_error("recv"); } for(k = 0; k < conf.maxPlayers; ++k) { if(connection[k].socket == i) { connection[k].socket = 0; connection[k].echo = 0; connection[k].bot = 0; playerLeave(k); allSendPlayerLeave(k); break; } } close(i); FD_CLR(i, &master); } else { pi = -1; for(k = 0; k < conf.maxPlayers; ++k) { if(connection[k].socket == i) { pi = k; break; } } for(k = 0; k < nbytes && pi >= 0; ++k) { unsigned char c = buf[k]; if(c != '\r' && c != '\n') { if(isprint(c) && connection[pi].msgbufindex < 128 - 2) { connection[pi].msgbuf[connection[pi].msgbufindex++] = c; } } else { if(connection[pi].msgbufindex == 0) { continue; } connection[pi].msgbuf[connection[pi].msgbufindex] = '\0'; connection[pi].msgbuf[connection[pi].msgbufindex + 1] = '\0'; connection[pi].msgbufindex = 0; if(connection[pi].echo) { snd(i, connection[pi].msgbuf); snd(i, "\r\n"); } if(!overdrive)printf("%16s (%d): \"%s\"\n", getPlayer(pi)->name, pi, connection[pi].msgbuf); switch(connection[pi].msgbuf[0]) { case 'n': { updateName(pi, connection[pi].msgbuf + 2); break; } case 't': { if(is_from_localhost(connection[pi])) { tankEnergy(atoi(connection[pi].msgbuf + 2)); } break; } case 'v': { updateVelocity(pi, atof(connection[pi].msgbuf + 2)); break; } case 'w': { toggleWatch(pi); break; } case 'z': { updateZoom(atof(connection[pi].msgbuf + 2)); break; } case 'T': { if(is_from_localhost(connection[pi])) { double throttle = atof(connection[pi].msgbuf + 2); conf.throttle.tv_sec= throttle; conf.throttle.tv_nsec=(throttle - conf.throttle.tv_sec) * 1000000000; } break; } case 'D': { if(is_from_localhost(connection[pi])) { conf.debug = atoi(connection[pi].msgbuf + 2); } break; } case 'c': { clearTraces(pi); break; } case 'o': { if(is_from_localhost(connection[pi])) { overdrive = !overdrive; } break; } case 'b': { connection[pi].bot = !connection[pi].bot; if(connection[pi].bot) { sendOwnId(i, pi); for(pi2 = 0; pi2 < conf.maxPlayers; ++pi2) { if(connection[pi2].socket) { sendPlayerPos(i, pi2); } } } break; } case 'f': { toggleFps(); break; } case 'i': { if(strcmp("init", connection[pi].msgbuf) == 0) { reinitialize(); } break; } case 'x': { if(strcmp("xit", connection[pi].msgbuf) == 0) { exit(0); } break; } case 'e': { connection[pi].echo = !connection[pi].echo; break; } case 'r': { validateOld(pi); break; } default: { updateAngle(pi, atof(connection[pi].msgbuf)); break; } } if(!connection[pi].bot) { snd(i, "> "); } } } } } } } for(k = 0; k < conf.maxPlayers; ++k) { if(getPlayer(k)->active && getPlayer(k)->timeoutcnt > 2) { connection[k].echo = 0; playerLeave(k); close(connection[k].socket); FD_CLR(connection[k].socket, &master); connection[k].socket = 0; connection[k].bot = 0; allSendPlayerLeave(k); } } }