void cl_network_disconnect(void) { if( client.connected ) { printf("Disconnecting\n"); net_close_connection(server); client.connected = 0; client.health = 0; } else /* Not connected (shouldn't be allowed to happen) */ printf("Not Connected!\n"); if( client.demo == DEMO_PLAY ) { /* Put things back after demo */ printf("Restoring.....\n"); strncpy(client.map, "ai_test.map", NETMSG_STRLEN ); client.demo = DEMO_NONE; client.view_w = client.desired_w; client.view_h = client.desired_h; client.x_tiles = client.view_w / TILE_W; client.y_tiles = client.view_h / TILE_H; } }
/* Add the client that's been accept()-ed onto fd */ static void sv_net_add_client(int fd) { netconnection_t *nc; client_t *cl; if( (nc = net_new_connection(fd)) == NULL ) { printf("Error creating new net connection.\n"); return; } if( (cl = (client_t *)malloc(sizeof(client_t))) == NULL ) { perror("malloc"); sv_netmsg_send_rejection(nc, "server memory error"); net_close_connection(nc); return; } /* Add client to the list */ if( cl_root == NULL ) cl_root = cl; if( cl_tail != NULL ) cl_tail->next = cl; cl->prev = cl_tail; cl->next = NULL; cl_tail = cl; cl->nc = nc; strncpy(cl->name, "Connecting Client", NETMSG_STRLEN); cl->status = CONNECTING; /* Waiting for join message */ cl->bad = 0; cl->ent = NULL; cl->keypress = 0; printf("Client joining from \"%s\"\n", nc->remote_address); }
void sv_net_remove_client(client_t *cl) { char buf[TEXTMESSAGE_STRLEN]; net_close_connection(cl->nc); if( cl->status >= JOINING ) server.clients--; snprintf(buf, TEXTMESSAGE_STRLEN, "%s disconnected (%d clients remain)", cl->name, server.clients); sv_net_send_text_to_all(buf); if( server.clients <= 0 && server.exit_when_empty ) { printf("Closing Empty Server.\n"); server.quit = 1; } if( cl->ent ) { entity_delete( cl->ent ); } /* Make sure that root & Tail will still point at the right spot after cl is deleted */ if( cl_root == cl ) cl_root = cl->next; if( cl_tail == cl ) cl_tail = cl->prev; if( cl->prev ) cl->prev->next = cl->next; if( cl->next ) cl->next->prev = cl->prev; free(cl); }
/* * nuke * * Usage: nuke user * * This command disconnects the user from the server. The user is informed * that she/he has been nuked by the admin named and a comment is * automatically placed in the user's files (if she/he is a registered * user, of course). */ int com_nuke(int p, param_list param) { struct player *pp = &player_globals.parray[p]; int p1, fd; if ((p1 = player_find_part_login(param[0].val.word)) < 0) { pprintf(p, "%s isn't logged in.\n", param[0].val.word); return COM_OK; } if (!check_admin2(p, p1)) { pprintf(p, "You need a higher adminlevel to nuke %s!\n", param[0].val.word); return COM_OK; } pprintf(p, "Nuking: %s\n", param[0].val.word); pprintf(p, "Please leave a comment explaining why %s was nuked.\n", player_globals.parray[p1].name); pprintf(p1, "\n\n**** You have been kicked out by %s! ****\n\n", pp->name); if (CheckPFlag(p1, PFLAG_REG)) pcommand(p, "addcomment %s Nuked\n", player_globals.parray[p1].name); /* addcomment doesnt work on guests */ fd = player_globals.parray[p1].socket; process_disconnection(fd); net_close_connection(fd); return COM_OK; }
static void sv_net_update(void) { char buf[32]; struct timeval tv; struct sockaddr_in naddr; client_t *cl; netconnection_t *nc; fd_set read_fds; int newsock; int maxfd; /* Highest fd + 1 needed for select() */ int addrlen; /* addrlen is passed to accept() and is changed to be the length of the new address */ FD_ZERO(&read_fds); /* If status of sock changes, then we have a new client wishing to join the server */ FD_SET(sock, &read_fds); maxfd = sock; /* The fd's change status when there is new client data to be read */ for( cl = cl_root ; cl != NULL ; cl = cl->next ) { FD_SET(cl->nc->fd, &read_fds); if( cl->nc->fd > maxfd ) maxfd = cl->nc->fd; } tv.tv_sec = 0; tv.tv_usec = M_SEC / 20; select(maxfd + 1, &read_fds, 0, 0, &tv); if( FD_ISSET(sock, &read_fds) ) { if( server.with_ggz ) { if( xtuxggz_is_sock_set(&newsock) != 1 ) newsock=-1; else fprintf(stderr,"-----NEW PLAYER----\n"); } else { addrlen = sizeof(naddr); newsock = accept(sock,(struct sockaddr *)&naddr,(socklen_t *)&addrlen); } if( newsock < 0 ) { perror("accept"); } else { if( server.clients < server.max_clients ) { fcntl( newsock, F_SETFL, O_NONBLOCK); /* Set to non blocking */ sv_net_add_client(newsock); } else { /* Too many clients, send rejection */ snprintf(buf, 32, "Server full (max=%d)", server.max_clients); if( (nc = net_new_connection(newsock)) ) { sv_netmsg_send_rejection(nc, buf); net_close_connection(nc); } } } } /* Read data from each ACTIVE client if it's fd status has changed */ for( cl = cl_root ; cl != NULL ; cl = cl->next ) if( FD_ISSET(cl->nc->fd, &read_fds) ) cl->nc->incoming = 1; }