static void NET_SV_ParseSYN(net_packet_t *packet, net_client_t *client, net_addr_t *addr) { unsigned int magic; unsigned int cl_gamemode, cl_gamemission; unsigned int cl_recording_lowres; unsigned int cl_drone; unsigned int is_freedoom; md5_digest_t deh_md5sum, wad_md5sum; char *player_name; char *client_version; int i; // read the magic number if (!NET_ReadInt32(packet, &magic)) { return; } if (magic != NET_MAGIC_NUMBER) { // invalid magic number return; } // Check the client version is the same as the server client_version = NET_ReadString(packet); if (client_version == NULL) { return; } if (strcmp(client_version, PACKAGE_STRING) != 0) { //! // @category net // // When running a netgame server, ignore version mismatches between // the server and the client. Using this option may cause game // desyncs to occur, or differences in protocol may mean the netgame // will simply not function at all. // if (M_CheckParm("-ignoreversion") == 0) { NET_SV_SendReject(addr, "Version mismatch: server version is: " PACKAGE_STRING); return; } } // read the game mode and mission if (!NET_ReadInt16(packet, &cl_gamemode) || !NET_ReadInt16(packet, &cl_gamemission) || !NET_ReadInt8(packet, &cl_recording_lowres) || !NET_ReadInt8(packet, &cl_drone) || !NET_ReadMD5Sum(packet, wad_md5sum) || !NET_ReadMD5Sum(packet, deh_md5sum) || !NET_ReadInt8(packet, &is_freedoom)) { return; } if (!NET_ValidGameMode(cl_gamemode, cl_gamemission)) { return; } // read the player's name player_name = NET_ReadString(packet); if (player_name == NULL) { return; } // received a valid SYN // not accepting new connections? if (server_state != SERVER_WAITING_START) { NET_SV_SendReject(addr, "Server is not currently accepting connections"); return; } // allocate a client slot if there isn't one already if (client == NULL) { // find a slot, or return if none found for (i=0; i<MAXNETNODES; ++i) { if (!clients[i].active) { client = &clients[i]; break; } } if (client == NULL) { return; } } else { // If this is a recently-disconnected client, deactivate // to allow immediate reconnection if (client->connection.state == NET_CONN_STATE_DISCONNECTED) { client->active = false; } } // New client? if (!client->active) { int num_players; // Before accepting a new client, check that there is a slot // free NET_SV_AssignPlayers(); num_players = NET_SV_NumPlayers(); if ((!cl_drone && num_players >= MAXPLAYERS) || NET_SV_NumClients() >= MAXNETNODES) { NET_SV_SendReject(addr, "Server is full!"); return; } // TODO: Add server option to allow rejecting clients which // set lowres_turn. This is potentially desirable as the // presence of such clients affects turning resolution. // Adopt the game mode and mission of the first connecting client if (num_players == 0 && !cl_drone) { sv_gamemode = cl_gamemode; sv_gamemission = cl_gamemission; } // Save the MD5 checksums memcpy(client->wad_md5sum, wad_md5sum, sizeof(md5_digest_t)); memcpy(client->deh_md5sum, deh_md5sum, sizeof(md5_digest_t)); client->is_freedoom = is_freedoom; // Check the connecting client is playing the same game as all // the other clients if (cl_gamemode != sv_gamemode || cl_gamemission != sv_gamemission) { NET_SV_SendReject(addr, "You are playing the wrong game!"); return; } // Activate, initialize connection NET_SV_InitNewClient(client, addr, player_name); client->recording_lowres = cl_recording_lowres; client->drone = cl_drone; } if (client->connection.state == NET_CONN_STATE_WAITING_ACK) { // force an acknowledgement client->connection.last_send_time = -1; } }
static void NET_CL_ParseWaitingData(net_packet_t *packet) { unsigned int num_players; unsigned int num_drones; unsigned int is_controller; signed int player_number; char *player_names[MAXPLAYERS]; char *player_addr[MAXPLAYERS]; md5_digest_t wad_md5sum, deh_md5sum; unsigned int server_is_freedoom; size_t i; if (!NET_ReadInt8(packet, &num_players) || !NET_ReadInt8(packet, &num_drones) || !NET_ReadInt8(packet, &is_controller) || !NET_ReadSInt8(packet, &player_number)) { // invalid packet return; } if (num_players > MAXPLAYERS) { // insane data return; } if ((player_number >= 0 && drone) || (player_number < 0 && !drone) || (player_number >= (signed int) num_players)) { // Invalid player number return; } // Read the player names for (i=0; i<num_players; ++i) { player_names[i] = NET_ReadString(packet); player_addr[i] = NET_ReadString(packet); if (player_names[i] == NULL || player_addr[i] == NULL) { return; } } if (!NET_ReadMD5Sum(packet, wad_md5sum) || !NET_ReadMD5Sum(packet, deh_md5sum) || !NET_ReadInt8(packet, &server_is_freedoom)) { return; } net_clients_in_game = num_players; net_drones_in_game = num_drones; net_client_controller = is_controller != 0; net_player_number = player_number; for (i=0; i<num_players; ++i) { strncpy(net_player_names[i], player_names[i], MAXPLAYERNAME); net_player_names[i][MAXPLAYERNAME-1] = '\0'; strncpy(net_player_addresses[i], player_addr[i], MAXPLAYERNAME); net_player_addresses[i][MAXPLAYERNAME-1] = '\0'; } memcpy(net_server_wad_md5sum, wad_md5sum, sizeof(md5_digest_t)); memcpy(net_server_deh_md5sum, deh_md5sum, sizeof(md5_digest_t)); net_server_is_freedoom = server_is_freedoom; net_client_received_wait_data = true; }