Crossfire Server, Trunk
Login, player creation

The core connection structure is socket_struct.

The init_sockets array, length contained in Socket_Info::allocated_sockets, contains starting at indice 0 the listening sockets for the server, initialized through init_server(). These sockets are always in use. For all listening sockets init_sockets[i].listen is non-NULL, for client connections it is NULL.

When a client connects, a socket from init_sockets is reused or reallocated in do_server(). During the first connection phase, the client can issue any command in the client_commands array - mostly, commands to negociate the connection, request faces and various game-related information -, 'add_me' and 'reply' commands, processed by add_me_cmd() and reply_cmd() respectively.

When the client sends the 'add_me' command (handled through add_me_cmd()), the socket is copied from the init_sockets array to the player.socket field, in add_player(), and the socket in init_sockets is marked as reusable.

The function add_player() is responsible from initializing the player structure, and putting the player in the first map.

The player then enters the ST_GET_NAME mode (as defined in player.state field), to get the name, then password and such.

The main socket handling function is do_server(), which is responsible for reading data from sockets, both init_sockets and players's, and also accepting new connections. It will also close connection to dropped clients, and check for banned hosts trying to connect.

The life-cycle of a connection is thus:

  • do_server() receives a new connection, and allocates a socket in init_sockets
  • handle_client() processes data from the socket, with a pl argument NULL - thus the client can only request information
  • the client sends add_me_cmd(). A player structure gets created in add_player(), the new player's mode is set to ST_GET_NAME. Socket in init_sockets is marked a reusable for future connections
  • from now on and until the player is totally logged on, client will mostly reply through reply_cmd() commands
  • player enters her name, and switches to ST_GET_PASSWORD mode
  • player enters her password, check_login() is called.
    • if the name and password match an existing player, player is loaded from disk and inserted at the last savebed, with state ST_PLAYING. If there is a logged on player with same name and password, she will get disconnected, thus enabling reconnection if connection was dropped.
    • if the password is wrong, the player is asked again for her name, returning to ST_GET_NAME state
    • if player doesn't exist, the player is asked for password confirmation, switching to ST_CONFIRM_PASSWORD
  • when player applies a bed of reality or dies, state switches to ST_PLAY_AGAIN through a call to play_again()
  • if player issues the quit command, state is set to ST_CONFIRM_QUIT through command_quit()

The main player creation routine is reply_cmd(), one of the few the player can issue while not playing. Creation cycle is:

Function responsibilities: