Beispiel #1
0
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;
}