Feature #264 ยป 0023-Improve-connecthand.-ch-coding-style.patch
server/connecthand.c | ||
---|---|---|
/**********************************************************************//**
|
||
This is used when a new player joins a server, before the game
|
||
has started. If pconn is NULL, is an AI, else a client.
|
||
has started. If pconn is nullptr, is an AI, else a client.
|
||
N.B. this only attachs a connection to a player if
|
||
N.B. this only attachs a connection to a player if
|
||
pconn->username == player->username
|
||
Here we send initial packets:
|
||
... | ... | |
pconn->server.status = AS_ESTABLISHED;
|
||
pconn->server.delegation.status = FALSE;
|
||
pconn->server.delegation.playing = NULL;
|
||
pconn->server.delegation.playing = nullptr;
|
||
pconn->server.delegation.observer = FALSE;
|
||
pconn->server.settings_sent = FALSE;
|
||
... | ... | |
/* Introduce the server to the connection */
|
||
if (fc_gethostname(hostname, sizeof(hostname)) == 0) {
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_any,
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
|
||
_("Welcome to the %s Server running at %s port %d."),
|
||
freeciv_name_version(), hostname, srvarg.port);
|
||
} else {
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_any,
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
|
||
_("Welcome to the %s Server at port %d."),
|
||
freeciv_name_version(), srvarg.port);
|
||
}
|
||
/* FIXME: this (getting messages about others logging on) should be a
|
||
* message option for the client with event */
|
||
/* FIXME: this (getting messages about others logging on) should be
|
||
* a message option for the client with event */
|
||
/* Notify the console that you're here. */
|
||
log_normal(_("%s has connected from %s."), pconn->username, pconn->addr);
|
||
... | ... | |
/* Reassert our control over the player. */
|
||
struct connection *pdelegate;
|
||
fc_assert_ret(player_delegation_get(pplayer) != NULL);
|
||
fc_assert_ret(player_delegation_get(pplayer) != nullptr);
|
||
pdelegate = conn_by_user(player_delegation_get(pplayer));
|
||
if (pdelegate && connection_delegate_restore(pdelegate)) {
|
||
/* Delegate now detached from our player. We will restore control
|
||
* over them as normal below. */
|
||
notify_conn(pconn->self, NULL, E_CONNECTION, ftc_server,
|
||
notify_conn(pconn->self, nullptr, E_CONNECTION, ftc_server,
|
||
_("Your delegate %s was controlling your player '%s'; "
|
||
"now detached."), pdelegate->username,
|
||
player_name(pplayer));
|
||
notify_conn(pdelegate->self, NULL, E_CONNECTION, ftc_server,
|
||
notify_conn(pdelegate->self, nullptr, E_CONNECTION, ftc_server,
|
||
_("%s reconnected, ending your delegated control of "
|
||
"player '%s'."), pconn->username, player_name(pplayer));
|
||
} else {
|
||
... | ... | |
log_error("Failed to revoke delegate %s's control of %s, so owner %s "
|
||
"can't regain control.", pdelegate->username,
|
||
player_name(pplayer), pconn->username);
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_server,
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
|
||
_("Couldn't get control of '%s' from delegation to %s."),
|
||
player_name(pplayer), pdelegate->username);
|
||
delegation_error = TRUE;
|
||
pplayer = NULL;
|
||
pplayer = nullptr;
|
||
}
|
||
}
|
||
... | ... | |
/* A player has already been created for this user, reconnect */
|
||
if (S_S_INITIAL == server_state()) {
|
||
send_player_info_c(NULL, dest);
|
||
send_player_info_c(nullptr, dest);
|
||
}
|
||
} else {
|
||
int total_free_weight = 0;
|
||
... | ... | |
log_normal("Trying to attach %s to %s",
|
||
pconn->username, wplayer->name);
|
||
if (!connection_attach_real(pconn, wplayer, FALSE, TRUE)) {
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_server,
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
|
||
_("Couldn't attach your connection to a scenario player."));
|
||
log_verbose("%s is not attached to a player", pconn->username);
|
||
}
|
||
... | ... | |
}
|
||
} players_iterate_end;
|
||
} else if (!game_was_started()) {
|
||
if (connection_attach_real(pconn, NULL, FALSE, TRUE)) {
|
||
if (connection_attach_real(pconn, nullptr, FALSE, TRUE)) {
|
||
pplayer = conn_get_player(pconn);
|
||
fc_assert(pplayer != NULL);
|
||
fc_assert(pplayer != nullptr);
|
||
} else {
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_server,
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
|
||
_("Couldn't attach your connection to new player."));
|
||
log_verbose("%s is not attached to a player", pconn->username);
|
||
}
|
||
}
|
||
send_player_info_c(NULL, dest);
|
||
send_player_info_c(nullptr, dest);
|
||
}
|
||
}
|
||
send_conn_info(game.est_connections, dest);
|
||
if (NULL == pplayer) {
|
||
if (pplayer == nullptr) {
|
||
/* Else this has already been done in connection_attach_real(). */
|
||
send_pending_events(pconn, TRUE);
|
||
send_running_votes(pconn, FALSE);
|
||
restore_access_level(pconn);
|
||
send_conn_info(dest, game.est_connections);
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_server,
|
||
_("You are logged in as '%s' connected to no player."),
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
|
||
_("You are logged in as '%s' connected to no player."),
|
||
pconn->username);
|
||
} else {
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_server,
|
||
_("You are logged in as '%s' connected to %s."),
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_server,
|
||
_("You are logged in as '%s' connected to %s."),
|
||
pconn->username,
|
||
player_name(pconn->playing));
|
||
}
|
||
... | ... | |
* connection_attach()), otherwise pconn will receive it too. */
|
||
if (conn_controls_player(pconn)) {
|
||
if (game.server.ip_hide) {
|
||
package_event(&connect_info, NULL, E_CONNECTION, ftc_server,
|
||
package_event(&connect_info, nullptr, E_CONNECTION, ftc_server,
|
||
_("%s has connected (player %s)."),
|
||
pconn->username,
|
||
player_name(conn_get_player(pconn)));
|
||
} else {
|
||
package_event(&connect_info, NULL, E_CONNECTION, ftc_server,
|
||
package_event(&connect_info, nullptr, E_CONNECTION, ftc_server,
|
||
_("%s has connected from %s (player %s)."),
|
||
pconn->username, pconn->addr,
|
||
player_name(conn_get_player(pconn)));
|
||
}
|
||
} else {
|
||
if (game.server.ip_hide) {
|
||
package_event(&connect_info, NULL, E_CONNECTION, ftc_server,
|
||
package_event(&connect_info, nullptr, E_CONNECTION, ftc_server,
|
||
_("%s has connected."),
|
||
pconn->username);
|
||
} else {
|
||
package_event(&connect_info, NULL, E_CONNECTION, ftc_server,
|
||
package_event(&connect_info, nullptr, E_CONNECTION, ftc_server,
|
||
_("%s has connected from %s."),
|
||
pconn->username, pconn->addr);
|
||
}
|
||
... | ... | |
} conn_list_iterate_end;
|
||
event_cache_add_for_all(&connect_info);
|
||
/* if need be, tell who we're waiting on to end the game.info.turn */
|
||
/* If need be, tell who we're waiting on to end the game.info.turn */
|
||
if (S_S_RUNNING == server_state() && game.server.turnblock) {
|
||
players_iterate_alive(cplayer) {
|
||
if (is_human(cplayer)
|
||
&& !cplayer->phase_done
|
||
&& cplayer != pconn->playing) { /* skip current player */
|
||
notify_conn(dest, NULL, E_CONNECTION, ftc_any,
|
||
_("Turn-blocking game play: "
|
||
"waiting on %s to finish turn..."),
|
||
notify_conn(dest, nullptr, E_CONNECTION, ftc_any,
|
||
_("Turn-blocking game play: "
|
||
"waiting on %s to finish turn..."),
|
||
player_name(cplayer));
|
||
}
|
||
} players_iterate_alive_end;
|
||
}
|
||
if (game.info.is_edit_mode) {
|
||
notify_conn(dest, NULL, E_SETTING, ftc_editor,
|
||
notify_conn(dest, nullptr, E_SETTING, ftc_editor,
|
||
_(" *** Server is in edit mode. *** "));
|
||
}
|
||
if (NULL != pplayer) {
|
||
if (pplayer != nullptr) {
|
||
/* Else, no need to do anything. */
|
||
reset_all_start_commands(TRUE);
|
||
(void) send_server_info_to_metaserver(META_INFO);
|
||
... | ... | |
{
|
||
struct packet_server_join_reply packet;
|
||
/* zero out the password */
|
||
/* Zero out the password */
|
||
memset(pconn->server.password, 0, sizeof(pconn->server.password));
|
||
packet.you_can_join = FALSE;
|
||
... | ... | |
Returns FALSE if the clients gets rejected and the connection should be
|
||
closed. Returns TRUE if the client get accepted.
|
||
**************************************************************************/
|
||
bool handle_login_request(struct connection *pconn,
|
||
bool handle_login_request(struct connection *pconn,
|
||
struct packet_server_join_req *req)
|
||
{
|
||
char msg[MAX_LEN_MSG];
|
||
... | ... | |
log_normal(_("Connection request from %s from %s"),
|
||
req->username, pconn->addr);
|
||
/* print server and client capabilities to console */
|
||
/* Print server and client capabilities to console */
|
||
log_normal(_("%s has client version %d.%d.%d%s"),
|
||
pconn->username, req->major_version, req->minor_version,
|
||
req->patch_version, req->version_label);
|
||
... | ... | |
return FALSE;
|
||
}
|
||
/* don't allow duplicate logins */
|
||
/* Don't allow duplicate logins */
|
||
conn_list_iterate(game.all_connections, aconn) {
|
||
if (fc_strcasecmp(req->username, aconn->username) == 0) {
|
||
fc_snprintf(msg, sizeof(msg), _("'%s' already connected."),
|
||
if (fc_strcasecmp(req->username, aconn->username) == 0) {
|
||
fc_snprintf(msg, sizeof(msg), _("'%s' already connected."),
|
||
req->username);
|
||
reject_new_connection(msg, pconn);
|
||
log_normal(_("%s was rejected: Duplicate login name [%s]."),
|
||
... | ... | |
log_normal(_("Lost connection: %s."), desc);
|
||
/* Special color (white on black) for player loss */
|
||
notify_conn(game.est_connections, NULL, E_CONNECTION,
|
||
notify_conn(game.est_connections, nullptr, E_CONNECTION,
|
||
conn_controls_player(pconn) ? ftc_player_lost : ftc_server,
|
||
_("Lost connection: %s."), desc);
|
||
... | ... | |
packet->id = pconn->id;
|
||
packet->used = pconn->used;
|
||
packet->established = pconn->established;
|
||
packet->player_num = (NULL != pconn->playing)
|
||
packet->player_num = (pconn->playing != nullptr)
|
||
? player_number(pconn->playing)
|
||
: player_slot_count();
|
||
packet->observer = pconn->observer;
|
||
... | ... | |
}
|
||
} players_iterate_end;
|
||
return NULL;
|
||
return nullptr;
|
||
}
|
||
/**********************************************************************//**
|
||
... | ... | |
Updates pconn->playing, pplayer->connections, pplayer->is_connected
|
||
and pconn->observer.
|
||
- If pplayer is NULL and observing is FALSE: take the next available
|
||
- If pplayer is nullptr and observing is FALSE: take the next available
|
||
player that is not connected.
|
||
- If pplayer is NULL and observing is TRUE: attach this connection to
|
||
- If pplayer is nullptr and observing is TRUE: attach this connection to
|
||
the game as global observer.
|
||
- If pplayer is not NULL and observing is FALSE: take this player.
|
||
- If pplayer is not NULL and observing is TRUE: observe this player.
|
||
- If pplayer is not nullptr and observing is FALSE: take this player.
|
||
- If pplayer is not nullptr and observing is TRUE: observe this player.
|
||
Note take_command() needs to know if this function will success before
|
||
it's time to call this. Keep take_command() checks in sync when
|
||
... | ... | |
struct player *pplayer,
|
||
bool observing, bool connecting)
|
||
{
|
||
fc_assert_ret_val(pconn != NULL, FALSE);
|
||
fc_assert_ret_val_msg(!pconn->observer && pconn->playing == NULL, FALSE,
|
||
fc_assert_ret_val(pconn != nullptr, FALSE);
|
||
fc_assert_ret_val_msg(!pconn->observer && pconn->playing == nullptr, FALSE,
|
||
"connections must be detached with "
|
||
"connection_detach() before calling this!");
|
||
if (!observing) {
|
||
if (NULL == pplayer) {
|
||
/* search for uncontrolled player */
|
||
if (pplayer == nullptr) {
|
||
/* Search for uncontrolled player */
|
||
pplayer = find_uncontrolled_player();
|
||
if (NULL == pplayer) {
|
||
/* no uncontrolled player found */
|
||
if (pplayer == nullptr) {
|
||
/* No uncontrolled player found */
|
||
if (player_count() >= game.server.max_players
|
||
|| normal_player_count() >= server.playable_nations) {
|
||
return FALSE;
|
||
}
|
||
/* add new player, or not */
|
||
/* Add new player, or not */
|
||
/* Should only be called in such a way as to create a new player
|
||
* in the pregame */
|
||
fc_assert_ret_val(!game_was_started(), FALSE);
|
||
pplayer = server_create_player(-1, default_ai_type_name(),
|
||
NULL, FALSE);
|
||
nullptr, FALSE);
|
||
/* Pregame => no need to assign_player_colors() */
|
||
if (!pplayer) {
|
||
return FALSE;
|
||
... | ... | |
sz_strlcpy(pplayer->username, pconn->username);
|
||
pplayer->unassigned_user = FALSE;
|
||
pplayer->user_turns = 0; /* reset for a new user */
|
||
pplayer->user_turns = 0; /* Reset for a new user */
|
||
pplayer->is_connected = TRUE;
|
||
if (!game_was_started()) {
|
||
if (!pplayer->was_created && NULL == pplayer->nation) {
|
||
if (!pplayer->was_created && pplayer->nation == nullptr) {
|
||
/* Temporarily set player_name() to username. */
|
||
server_player_set_name(pplayer, pconn->username);
|
||
}
|
||
... | ... | |
}
|
||
if (game.server.auto_ai_toggle && !is_human(pplayer)) {
|
||
toggle_ai_player_direct(NULL, pplayer);
|
||
toggle_ai_player_direct(nullptr, pplayer);
|
||
}
|
||
send_player_info_c(pplayer, game.est_connections);
|
||
/* Remove from global observers list, if was there */
|
||
conn_list_remove(game.glob_observers, pconn);
|
||
} else if (pplayer == NULL) {
|
||
} else if (pplayer == nullptr) {
|
||
/* Global observer */
|
||
bool already = FALSE;
|
||
... | ... | |
&& !fc_strncmp(aplayer->username, pconn->username, MAX_LEN_NAME)) {
|
||
sz_strlcpy(aplayer->username, _(ANON_USER_NAME));
|
||
aplayer->unassigned_user = TRUE;
|
||
send_player_info_c(aplayer, NULL);
|
||
send_player_info_c(aplayer, nullptr);
|
||
}
|
||
} players_iterate_end;
|
||
... | ... | |
break;
|
||
}
|
||
send_updated_vote_totals(NULL);
|
||
send_updated_vote_totals(nullptr);
|
||
return TRUE;
|
||
}
|
||
... | ... | |
{
|
||
struct player *pplayer;
|
||
fc_assert_ret(pconn != NULL);
|
||
fc_assert_ret(pconn != nullptr);
|
||
if (NULL != (pplayer = pconn->playing)) {
|
||
if ((pplayer = pconn->playing) != nullptr) {
|
||
bool was_connected = pplayer->is_connected;
|
||
send_remove_team_votes(pconn);
|
||
conn_list_remove(pplayer->connections, pconn);
|
||
pconn->playing = NULL;
|
||
pconn->playing = nullptr;
|
||
pconn->observer = FALSE;
|
||
restore_access_level(pconn);
|
||
cancel_connection_votes(pconn);
|
||
send_updated_vote_totals(NULL);
|
||
send_updated_vote_totals(nullptr);
|
||
send_conn_info(pconn->self, game.est_connections);
|
||
/* If any other (non-observing) conn is attached to this player, the
|
||
... | ... | |
conn_list_iterate(pplayer->connections, aconn) {
|
||
/* Detach all. */
|
||
fc_assert_action(aconn != pconn, continue);
|
||
notify_conn(aconn->self, NULL, E_CONNECTION, ftc_server,
|
||
notify_conn(aconn->self, nullptr, E_CONNECTION, ftc_server,
|
||
_("Detaching from %s."), player_name(pplayer));
|
||
/* Recursive... but shouldn't be a problem, as this can only
|
||
* be a non-controlling connection so can't get back here. */
|
||
... | ... | |
} else {
|
||
/* Aitoggle the player if no longer connected. */
|
||
if (game.server.auto_ai_toggle && is_human(pplayer)) {
|
||
toggle_ai_player_direct(NULL, pplayer);
|
||
toggle_ai_player_direct(nullptr, pplayer);
|
||
/* send_player_info_c() was formerly updated by
|
||
* toggle_ai_player_direct(), so it must be safe to send here now?
|
||
*
|
||
... | ... | |
* See establish_new_connection().
|
||
*/
|
||
log_verbose("connection_detach() calls send_player_info_c()");
|
||
send_player_info_c(pplayer, NULL);
|
||
send_player_info_c(pplayer, nullptr);
|
||
reset_all_start_commands(TRUE);
|
||
}
|
||
... | ... | |
sz_strlcpy(dplayer->server.orig_username, dplayer->username);
|
||
/* Detach the current connection. */
|
||
if (NULL != pconn->playing || pconn->observer) {
|
||
if (pconn->playing != nullptr || pconn->observer) {
|
||
connection_detach(pconn, FALSE);
|
||
}
|
||
... | ... | |
/* Reset all changes done above. */
|
||
pconn->server.delegation.status = FALSE;
|
||
pconn->server.delegation.playing = NULL;
|
||
pconn->server.delegation.playing = nullptr;
|
||
pconn->server.delegation.observer = FALSE;
|
||
if (conn_controls_player(pconn)) {
|
||
struct player *oplayer = conn_get_player(pconn);
|
||
... | ... | |
fc_assert_ret_val(dplayer, FALSE);
|
||
/* Detach the current (delegate) connection from the delegated player. */
|
||
if (NULL != pconn->playing || pconn->observer) {
|
||
if (pconn->playing != nullptr || pconn->observer) {
|
||
connection_detach(pconn, FALSE);
|
||
}
|
||
/* Try to attach to the delegate's original player */
|
||
if ((NULL != pconn->server.delegation.playing
|
||
if ((pconn->server.delegation.playing != nullptr
|
||
|| pconn->server.delegation.observer)
|
||
&& !connection_attach(pconn, pconn->server.delegation.playing,
|
||
pconn->server.delegation.observer)) {
|
||
... | ... | |
/* Reset data. */
|
||
pconn->server.delegation.status = FALSE;
|
||
pconn->server.delegation.playing = NULL;
|
||
pconn->server.delegation.playing = nullptr;
|
||
pconn->server.delegation.observer = FALSE;
|
||
if (conn_controls_player(pconn) && conn_get_player(pconn) != NULL) {
|
||
if (conn_controls_player(pconn) && conn_get_player(pconn) != nullptr) {
|
||
/* Remove flag that we had 'put aside' our original player. */
|
||
struct player *oplayer = conn_get_player(pconn);
|
||
fc_assert_ret_val(oplayer != dplayer, FALSE);
|
||
oplayer->server.orig_username[0] = '\0';
|
||
}
|
||
... | ... | |
sz_strlcpy(dplayer->username, dplayer->server.orig_username);
|
||
dplayer->server.orig_username[0] = '\0';
|
||
/* Send updated username to all connections. */
|
||
send_player_info_c(dplayer, NULL);
|
||
send_player_info_c(dplayer, nullptr);
|
||
return TRUE;
|
||
}
|
server/connecthand.h | ||
---|---|---|
/**********************************************************************
|
||
/***********************************************************************
|
||
Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
|
||
This program is free software; you can redistribute it and/or modify
|
||
it under the terms of the GNU General Public License as published by
|
||
... | ... | |
#ifndef FC__CONNECTHAND_H
|
||
#define FC__CONNECTHAND_H
|
||
/* utility */
|
||
#include "support.h" /* bool type */
|
||
/* common */
|
||
#include "fc_types.h"
|
||
struct connection;
|