Crossfire Server, Trunk  R22047
loop.c File Reference
#include "global.h"
#include <arpa/inet.h>
#include <assert.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <netdb.h>
#include "image.h"
#include "newserver.h"
#include "sockproto.h"
#include "sproto.h"
+ Include dependency graph for loop.c:

Go to the source code of this file.

Data Structures

struct  client_cmd_mapping
struct  player_cmd_mapping


typedef void(* func_uint8_int_ns) (char *, int, socket_struct *)
typedef void(* func_uint8_int_pl) (char *, int, player *)


static void block_until_new_connection (void)
bool connection_alive (socket_struct socket)
void do_server (void)
bool handle_client (socket_struct *ns, player *pl)
static int handle_cmd (socket_struct *ns, player *pl, char *cmd, char *data, int len)
static int is_fd_valid (int fd)
static void new_connection (int listen_fd)
void request_info_cmd (char *buf, int len, socket_struct *ns)
static void send_updates (player *pl)
void update_players ()


static const struct client_cmd_mapping client_commands []
static const struct player_cmd_mapping player_commands []
unsigned long todtick

Detailed Description

Main client/server loops.


Mainly deals with initialization and higher level socket maintenance (checking for lost connections and if data has arrived.) The reading of data is handled in lowlevel.c

Definition in file loop.c.

Typedef Documentation

◆ func_uint8_int_ns

typedef void(* func_uint8_int_ns) (char *, int, socket_struct *)

Prototype for functions the client sends without player interaction.

Definition at line 61 of file loop.c.

◆ func_uint8_int_pl

typedef void(* func_uint8_int_pl) (char *, int, player *)

Prototype for functions used to handle player actions.

Definition at line 70 of file loop.c.

Function Documentation

◆ block_until_new_connection()

static void block_until_new_connection ( void  )

Waits for new connection when there is no one connected.

Definition at line 342 of file loop.c.

References Socket_Info::allocated_sockets, Settings::fastclock, flush_old_maps(), init_sockets, socket_struct::listen, llevInfo, LOG(), Socket_Info::max_filedescriptor, metaserver_update(), Ns_Add, reset_sleep(), settings, socket_info, tick_the_clock(), and watchdog().

Referenced by do_server().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ connection_alive()

bool connection_alive ( socket_struct  socket)

Check whether the given socket's connection is alive or not.

True if connection is active, false if not.

Definition at line 489 of file loop.c.

References BEAT_INTERVAL, socket_struct::heartbeat, socket_struct::last_tick, and tick_length().

Referenced by update_players().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ do_server()

void do_server ( void  )

This checks the sockets for input and exceptions, does the right thing.

A bit of this code is grabbed out of socket.c There are 2 lists we need to look through - init_sockets is a list

Definition at line 536 of file loop.c.

References Socket_Info::allocated_sockets, block_until_new_connection(), socket_struct::fd, final_free_player(), first_player, free_newsocket(), get_sleep_remaining(), handle_client(), socket_struct::host, init_listening_socket(), init_sockets, is_fd_valid(), jump_time(), leave(), llevError, llevInfo, LOG(), Socket_Info::max_filedescriptor, new_connection(), pl::next, Ns_Add, Ns_Avail, Ns_Dead, pl::ob, save_player(), send_updates(), pl::socket, socket_info, socket_struct::status, and Socket_Info::timeout.

Referenced by server_main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handle_client()

bool handle_client ( socket_struct ns,
player pl 

Handle commands from a client. This function should only be called when the socket is readable. If an error occurs, the socket status will be set to Ns_Dead; it is up to the caller to clean it up.

nsSocket sending the command
plPlayer associated with this socket, or NULL
If the main loop should continue processing this client.

Definition at line 242 of file loop.c.

References SockList::buf, socket_struct::faces_sent, socket_struct::fd, handle_cmd(), socket_struct::inbuf, socket_struct::last_tick, SockList::len, Ns_Dead, pl::ob, SockList_NullTerminate(), SockList_ReadPacket(), SockList_ResetRead(), ST_PLAYING, pl::state, socket_struct::status, strtok_r, todtick, and watchdog().

Referenced by do_server().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ handle_cmd()

static int handle_cmd ( socket_struct ns,
player pl,
char *  cmd,
char *  data,
int  len 

Definition at line 194 of file loop.c.

References client_cmd_mapping::cmdname, player_cmd_mapping::cmdname, client_cmd_mapping::cmdproc, player_cmd_mapping::cmdproc, player_cmd_mapping::flag, socket_struct::host, llevDebug, LOG(), ST_PLAYING, and pl::state.

Referenced by handle_client().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ is_fd_valid()

static int is_fd_valid ( int  fd)

Checks if file descriptor is valid.

fdfile descriptor to check.
1 if fd is valid, 0 else.

Definition at line 404 of file loop.c.

Referenced by do_server().

+ Here is the caller graph for this function:

◆ new_connection()

static void new_connection ( int  listen_fd)

Handle a new connection from a client.

listen_fdfile descriptor the request came from.

Definition at line 416 of file loop.c.

References Socket_Info::allocated_sockets, buf, checkbanned(), socket_struct::faces_sent, socket_struct::faces_sent_len, fatal(), socket_struct::fd, get_faces_count(), init_connection(), init_sockets, socket_struct::listen, llevDebug, llevError, llevInfo, LOG(), MAX_BUF, Ns_Avail, OUT_OF_MEMORY, SEE_LAST_ERROR, snprintf, socket_info, socklen_t, and socket_struct::status.

Referenced by do_server().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ request_info_cmd()

void request_info_cmd ( char *  buf,
int  len,
socket_struct ns 

request_info_cmd is sort of a meta command. There is some specific request of information, but we call other functions to provide that information.

bufbuffer containing the information requested.
lenlength of buf, ignored.
nssocket to write data to.

Definition at line 132 of file loop.c.

References socket_struct::host, knowledge_send_info(), llevDebug, LOG(), send_class_info(), send_class_list(), send_exp_table(), send_file(), send_image_info(), send_image_sums(), send_map_info(), send_new_char_info(), send_race_info(), send_race_list(), send_skill_info(), send_spell_paths(), Send_With_Handling(), SockList_AddString(), SockList_Init(), and SockList_Term().

+ Here is the call graph for this function:

◆ send_updates()

static void send_updates ( player pl)

Send updated stats, map, look, and inventory to the player.

Definition at line 506 of file loop.c.

References draw_client_map(), esrv_draw_look(), esrv_send_inventory(), esrv_update_item(), esrv_update_stats(), pl::last_weight, llevError, LOG(), pl::ob, pl::socket, UPD_WEIGHT, socket_struct::update_inventory, socket_struct::update_look, and WEIGHT.

Referenced by do_server(), and update_players().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ update_players()

void update_players ( void  )

Send updates to players. Called once per tick.

Definition at line 677 of file loop.c.

References connection_alive(), first_player, socket_struct::last_tick, llevDebug, LOG(), pl::next, send_tick(), send_updates(), pl::socket, ST_PLAYING, pl::state, and socket_struct::tick.

Referenced by server_main().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ client_commands

const struct client_cmd_mapping client_commands[]
Initial value:
= {
{ "addme", add_me_cmd },
{ "askface", send_face_cmd },
{ "beat", NULL },
{ "requestinfo", request_info_cmd },
{ "setup", set_up_cmd },
{ "version", version_cmd },
{ "asksmooth", ask_smooth_cmd },
{ "accountlogin", account_login_cmd },
{ "accountnew", account_new_cmd },
{ "accountaddplayer", account_add_player_cmd },
{ "accountplay", account_play_cmd },
{ "accountpw", account_password },
{ "createplayer", create_player_cmd },
void account_login_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:2077
void version_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:583
void account_password(char *buf, int len, socket_struct *ns)
Definition: request.c:2956
void account_new_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:2204
void set_up_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:93
void request_info_cmd(char *buf, int len, socket_struct *ns)
Definition: loop.c:132
void ask_smooth_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:425
void account_add_player_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:2318
void add_me_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:347
void send_face_cmd(char *buff, int len, socket_struct *ns)
Definition: image.c:44
void create_player_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:2540
void account_play_cmd(char *buf, int len, socket_struct *ns)
Definition: request.c:2447

Commands sent directly by client, when connecting or when needed.

Definition at line 107 of file loop.c.

◆ player_commands

const struct player_cmd_mapping player_commands[]
Initial value:
= {
{ "examine", examine_cmd, 1 },
{ "apply", apply_cmd, 1 },
{ "move", move_cmd, 1 },
{ "reply", reply_cmd, 0 },
{ "lookat", look_at_cmd, 1 },
{ "inscribe", inscribe_scroll_cmd, 0 },
{ NULL, NULL, 0 }
void mark_item_cmd(uint8_t *data, int len, player *pl)
Definition: item.c:732
void look_at_cmd(char *buf, int len, player *pl)
Definition: item.c:828
void new_player_cmd(uint8_t *buf, int len, player *pl)
Definition: request.c:449
void inscribe_scroll_cmd(char *buf, int len, player *pl)
Definition: item.c:917
void lock_item_cmd(uint8_t *data, int len, player *pl)
Definition: item.c:673
void(* func_uint8_int_pl)(char *, int, player *)
Definition: loop.c:70
void examine_cmd(char *buf, int len, player *pl)
Definition: item.c:614
void apply_cmd(char *buf, int len, player *pl)
Definition: item.c:633
void reply_cmd(char *buf, int len, player *pl)
Definition: request.c:511
void move_cmd(char *buf, int len, player *pl)
Definition: request.c:639

Dispatch tables for the server.

CmdMapping is the dispatch table for the server, used in handle_client, which gets called when the client has input. All commands called here use the same parameter form (char *data, int len, int clientnum. We do implicit casts, because the data that is being passed is unsigned (pretty much needs to be for binary data), however, most of these treat it only as strings, so it makes things easier to cast it here instead of a bunch of times in the function itself. flag is 1 if the player must be in the playing state to issue the command, 0 if they can issue it at any time.Commands sent by the client reacting to player's actions.

Definition at line 93 of file loop.c.

◆ todtick

unsigned long todtick

Ingame time

Definition at line 417 of file init.c.

Referenced by handle_client(), init_clocks(), and write_todclock().