Changeset - r16258:7148460f4b1c
[Not reviewed]
master
0 5 0
rubidium - 14 years ago 2010-10-17 17:37:26
rubidium@openttd.org
(svn r20969) -Add: client info change notification to remote admins (dihedral)
5 files changed with 210 insertions and 1 deletions:
0 comments (0 inline, 0 general)
src/network/core/tcp_admin.cpp
Show inline comments
 
@@ -64,6 +64,11 @@ NetworkRecvStatus NetworkAdminSocketHand
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_SHUTDOWN)
 

	
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_DATE)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_JOIN)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_INFO)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_UPDATE)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_QUIT)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_ERROR)
 

	
 
		default:
 
			if (this->HasClientQuit()) {
 
@@ -123,5 +128,10 @@ DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_SHUTDOWN)
 

	
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_DATE)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_JOIN)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_INFO)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_UPDATE)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_QUIT)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_ERROR)
 

	
 
#endif /* ENABLE_NETWORK */
src/network/core/tcp_admin.h
Show inline comments
 
@@ -40,6 +40,11 @@ enum PacketAdminType {
 
	ADMIN_PACKET_SERVER_SHUTDOWN,        ///< The server tells the admin its shutting down.
 

	
 
	ADMIN_PACKET_SERVER_DATE,            ///< The server tells the admin what the current game date is.
 
	ADMIN_PACKET_SERVER_CLIENT_JOIN,     ///< The server tells the admin that a client has joined.
 
	ADMIN_PACKET_SERVER_CLIENT_INFO,     ///< The server gives the admin information about a client.
 
	ADMIN_PACKET_SERVER_CLIENT_UPDATE,   ///< The server gives the admin an information update on a client.
 
	ADMIN_PACKET_SERVER_CLIENT_QUIT,     ///< The server tells the admin that a client quit.
 
	ADMIN_PACKET_SERVER_CLIENT_ERROR,    ///< The server tells the admin that a client caused an error.
 

	
 
	INVALID_ADMIN_PACKET = 0xFF,         ///< An invalid marker for admin packets.
 
};
 
@@ -54,6 +59,7 @@ enum AdminStatus {
 
/** Update types an admin can register a frequency for */
 
enum AdminUpdateType {
 
	ADMIN_UPDATE_DATE,            ///< Updates about the date of the game.
 
	ADMIN_UPDATE_CLIENT_INFO,     ///< Updates about the information of clients.
 
	ADMIN_UPDATE_END              ///< Must ALWAYS be on the end of this list!! (period)
 
};
 

	
 
@@ -102,7 +108,8 @@ protected:
 
	/**
 
	 * Poll the server for certain updates, an invalid poll (e.g. not existent id) gets silently dropped:
 
	 * uint8   #AdminUpdateType the server should answer for, only if #AdminUpdateFrequency #ADMIN_FREQUENCY_POLL is advertised in the PROTOCOL packet.
 
	 * uint32  ID relevant to the packet type.
 
	 * uint32  ID relevant to the packet type, e.g.
 
	 *          - the client ID for #ADMIN_UPDATE_CLIENT_INFO. Use UINT32_MAX to show all clients.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL);
 

	
 
@@ -161,6 +168,44 @@ protected:
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_DATE);
 

	
 
	/**
 
	 * Notification of a new client:
 
	 * uint32  ID of the new client.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_JOIN);
 

	
 
	/**
 
	 * Client information of a specific client:
 
	 * uint32  ID of the client.
 
	 * string  Network address of the client.
 
	 * string  Name of the client.
 
	 * uint8   Language of the client.
 
	 * uint32  Date the client joined the game.
 
	 * uint8   ID of the company the client is playing as (255 for spectators).
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_INFO);
 

	
 
	/**
 
	 * Client update details on a specific client (e.g. after rename or move):
 
	 * uint32  ID of the client.
 
	 * string  Name of the client.
 
	 * uint8   ID of the company the client is playing as (255 for spectators).
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_UPDATE);
 

	
 
	/**
 
	 * Notification about a client leaving the game.
 
	 * uint32  ID of the client that just left.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_QUIT);
 

	
 
	/**
 
	 * Notification about a client error (and thus the clients disconnection).
 
	 * uint32  ID of the client that made the error.
 
	 * uint8   Error the client made (see NetworkErrorCode).
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_ERROR);
 

	
 
	NetworkRecvStatus HandlePacket(Packet *p);
 
public:
 
	NetworkRecvStatus CloseConnection(bool error = true);
src/network/network_admin.cpp
Show inline comments
 
@@ -41,6 +41,7 @@ static const int ADMIN_AUTHORISATION_TIM
 
/** Frequencies, which may be registered for a certain update type. */
 
static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
 
	ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_DAILY | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_DATE
 
	ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      ///< ADMIN_UPDATE_CLIENT_INFO
 
};
 
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
 

	
 
@@ -180,6 +181,66 @@ NetworkRecvStatus ServerNetworkAdminSock
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientJoin(ClientID client_id)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_JOIN);
 

	
 
	p->Send_uint32(client_id);
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkClientInfo *ci)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_INFO);
 

	
 
	p->Send_uint32(ci->client_id);
 
	p->Send_string(const_cast<NetworkAddress &>(ci->client_address).GetHostname());
 
	p->Send_string(ci->client_name);
 
	p->Send_uint8 (ci->client_lang);
 
	p->Send_uint32(ci->join_date);
 
	p->Send_uint8 (ci->client_playas);
 

	
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientUpdate(const NetworkClientInfo *ci)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_UPDATE);
 

	
 
	p->Send_uint32(ci->client_id);
 
	p->Send_string(ci->client_name);
 
	p->Send_uint8 (ci->client_playas);
 

	
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientQuit(ClientID client_id)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_QUIT);
 

	
 
	p->Send_uint32(client_id);
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientError(ClientID client_id, NetworkErrorCode error)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_ERROR);
 

	
 
	p->Send_uint32(client_id);
 
	p->Send_uint8 (error);
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
/***********
 
 * Receiving functions
 
 ************/
 
@@ -247,6 +308,19 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_
 
			this->SendDate();
 
			break;
 

	
 
		case ADMIN_UPDATE_CLIENT_INFO:
 
			/* The admin is requesting client info. */
 
			const NetworkClientInfo *ci;
 
			if (d1 == UINT32_MAX) {
 
				FOR_ALL_CLIENT_INFOS(ci) {
 
					this->SendClientInfo(ci);
 
				}
 
			} else {
 
				ci = NetworkFindClientInfoFromClientID((ClientID)d1);
 
				if (ci != NULL) this->SendClientInfo(ci);
 
			}
 
			break;
 

	
 
		default:
 
			/* An unsupported "poll" update type. */
 
			DEBUG(net, 3, "[admin] Not supported poll %d (%d) from '%s' (%s).", type, d1, this->admin_name, this->admin_version);
 
@@ -261,6 +335,67 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_
 
 */
 

	
 
/**
 
 * Notify the admin network of a new client (if they did opt in for the respective update).
 
 * @param ci the client info.
 
 * @param new_client if this is a new client, send the respective packet too.
 
 */
 
void NetworkAdminClientInfo(const NetworkClientInfo *ci, bool new_client)
 
{
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
 
			as->SendClientInfo(ci);
 
			if (new_client) {
 
				as->SendClientJoin(ci->client_id);
 
			}
 
		}
 
	}
 
}
 

	
 
/**
 
 * Notify the admin network of a client update (if they did opt in for the respective update).
 
 * @param ci the client info.
 
 */
 
void NetworkAdminClientUpdate(const NetworkClientInfo *ci)
 
{
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
 
			as->SendClientUpdate(ci);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Notify the admin network that a client quit (if they have opt in for the respective update).
 
 * @param client_id of the client that quit.
 
 */
 
void NetworkAdminClientQuit(ClientID client_id)
 
{
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
 
			as->SendClientQuit(client_id);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Notify the admin network of a client error (if they have opt in for the respective update).
 
 * @param client_id the client that made the error.
 
 * @param error_code the error that was caused.
 
 */
 
void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code)
 
{
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) {
 
			as->SendClientError(client_id, error_code);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Send a Welcome packet to all connected admins
 
 */
 
void ServerNetworkAdminSocketHandler::WelcomeAll()
src/network/network_admin.h
Show inline comments
 
@@ -44,6 +44,11 @@ public:
 
	NetworkRecvStatus SendNewGame();
 
	NetworkRecvStatus SendShutdown();
 
	NetworkRecvStatus SendDate();
 
	NetworkRecvStatus SendClientJoin(ClientID client_id);
 
	NetworkRecvStatus SendClientInfo(const NetworkClientInfo *ci);
 
	NetworkRecvStatus SendClientUpdate(const NetworkClientInfo *ci);
 
	NetworkRecvStatus SendClientQuit(ClientID client_id);
 
	NetworkRecvStatus SendClientError(ClientID client_id, NetworkErrorCode error);
 

	
 
	static void Send();
 
	static void AcceptConnection(SOCKET s, const NetworkAddress &address);
 
@@ -63,6 +68,10 @@ public:
 
#define FOR_ALL_ADMIN_SOCKETS_FROM(var, start) FOR_ALL_ITEMS_FROM(ServerNetworkAdminSocketHandler, adminsocket_index, var, start)
 
#define FOR_ALL_ADMIN_SOCKETS(var) FOR_ALL_ADMIN_SOCKETS_FROM(var, 0)
 

	
 
void NetworkAdminClientInfo(const NetworkClientInfo *ci, bool new_client = false);
 
void NetworkAdminClientUpdate(const NetworkClientInfo *ci);
 
void NetworkAdminClientQuit(ClientID client_id);
 
void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code);
 
void NetworkAdminUpdate(AdminUpdateFrequency freq);
 

	
 
#endif /* ENABLE_NETWORK */
src/network/network_server.cpp
Show inline comments
 
@@ -284,6 +284,8 @@ NetworkRecvStatus ServerNetworkGameSocke
 
				new_cs->SendErrorQuit(this->client_id, error);
 
			}
 
		}
 

	
 
		NetworkAdminClientError(this->client_id, error);
 
	} else {
 
		DEBUG(net, 1, "Client %d made an error and has been disconnected. Reason: '%s'", this->client_id, str);
 
	}
 
@@ -985,6 +987,8 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_
 
			}
 
		}
 

	
 
		NetworkAdminClientInfo(this->GetInfo(), true);
 

	
 
		/* also update the new client with our max values */
 
		this->SendConfigUpdate();
 

	
 
@@ -1093,6 +1097,8 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_
 
		}
 
	}
 

	
 
	NetworkAdminClientError(this->client_id, errorno);
 

	
 
	return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
 
}
 

	
 
@@ -1118,6 +1124,8 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_
 
		}
 
	}
 

	
 
	NetworkAdminClientQuit(this->client_id);
 

	
 
	return this->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST);
 
}
 

	
 
@@ -1473,6 +1481,8 @@ void NetworkUpdateClientInfo(ClientID cl
 
	FOR_ALL_CLIENT_SOCKETS(cs) {
 
		cs->SendClientInfo(ci);
 
	}
 

	
 
	NetworkAdminClientUpdate(ci);
 
}
 

	
 
/* Check if we want to restart the map */
0 comments (0 inline, 0 general)