Changeset - r16256:b1e0699fee93
[Not reviewed]
master
0 7 0
rubidium - 14 years ago 2010-10-17 17:36:23
rubidium@openttd.org
(svn r20967) -Add: infrastructure to send information to remote admins at specific intervals (dihedral)
7 files changed with 123 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/date.cpp
Show inline comments
 
@@ -247,12 +247,13 @@ static void OnNewMonth()
 
 * Runs various procedures that have to be done daily
 
 */
 
static void OnNewDay()
 
{
 
#ifdef ENABLE_NETWORK
 
	NetworkChatMessageDailyLoop();
 
	if (_network_server) NetworkServerDailyLoop();
 
#endif /* ENABLE_NETWORK */
 

	
 
	DisasterDailyLoop();
 
	IndustryDailyLoop();
 

	
 
	SetWindowWidgetDirty(WC_STATUS_BAR, 0, 0);
src/network/core/tcp_admin.cpp
Show inline comments
 
@@ -49,12 +49,14 @@ NetworkRecvStatus NetworkAdminSocketHand
 
{
 
	PacketAdminType type = (PacketAdminType)p->Recv_uint8();
 

	
 
	switch (this->HasClientQuit() ? INVALID_ADMIN_PACKET : type) {
 
		ADMIN_COMMAND(ADMIN_PACKET_ADMIN_JOIN)
 
		ADMIN_COMMAND(ADMIN_PACKET_ADMIN_QUIT)
 
		ADMIN_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
 
		ADMIN_COMMAND(ADMIN_PACKET_ADMIN_POLL)
 

	
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_FULL)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_BANNED)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_ERROR)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_PROTOCOL)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_WELCOME)
 
@@ -104,12 +106,14 @@ NetworkRecvStatus NetworkAdminSocketHand
 
			type, this->admin_name, this->admin_version); \
 
	return NETWORK_RECV_STATUS_MALFORMED_PACKET; \
 
}
 

	
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_JOIN)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_QUIT)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL)
 

	
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_FULL)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_BANNED)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_ERROR)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_PROTOCOL)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_WELCOME)
src/network/core/tcp_admin.h
Show inline comments
 
@@ -25,12 +25,14 @@
 
 * Enum with types of TCP packets specific to the admin network.
 
 * This protocol may only be extended to ensure stability.
 
 */
 
enum PacketAdminType {
 
	ADMIN_PACKET_ADMIN_JOIN,             ///< The admin announces and authenticates itself to the server.
 
	ADMIN_PACKET_ADMIN_QUIT,             ///< The admin tells the server that it is quitting.
 
	ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY, ///< The admin tells the server the update frequency of a particular piece of information.
 
	ADMIN_PACKET_ADMIN_POLL,             ///< The admin explicitly polls for a piece of information.
 

	
 
	ADMIN_PACKET_SERVER_FULL = 100,      ///< The server tells the admin it cannot accept the admin.
 
	ADMIN_PACKET_SERVER_BANNED,          ///< The server tells the admin it is banned.
 
	ADMIN_PACKET_SERVER_ERROR,           ///< The server tells the admin an error has occurred.
 
	ADMIN_PACKET_SERVER_PROTOCOL,        ///< The server tells the admin its protocol version.
 
	ADMIN_PACKET_SERVER_WELCOME,         ///< The server welcomes the admin to a game.
 
@@ -44,12 +46,29 @@ enum PacketAdminType {
 
enum AdminStatus {
 
	ADMIN_STATUS_INACTIVE,      ///< The admin is not connected nor active.
 
	ADMIN_STATUS_ACTIVE,        ///< The admin is active.
 
	ADMIN_STATUS_END            ///< Must ALWAYS be on the end of this list!! (period)
 
};
 

	
 
/** Update types an admin can register a frequency for */
 
enum AdminUpdateType {
 
	ADMIN_UPDATE_END              ///< Must ALWAYS be on the end of this list!! (period)
 
};
 

	
 
/** Update frequencies an admin can register. */
 
enum AdminUpdateFrequency {
 
	ADMIN_FREQUENCY_POLL      = 0x01, ///< The admin can poll this.
 
	ADMIN_FREQUENCY_DAILY     = 0x02, ///< The admin gets information about this on a daily basis.
 
	ADMIN_FREQUENCY_WEEKLY    = 0x04, ///< The admin gets information about this on a weekly basis.
 
	ADMIN_FREQUENCY_MONTHLY   = 0x08, ///< The admin gets information about this on a monthly basis.
 
	ADMIN_FREQUENCY_QUARTERLY = 0x10, ///< The admin gets information about this on a quarterly basis.
 
	ADMIN_FREQUENCY_ANUALLY   = 0x20, ///< The admin gets information about this on a yearly basis.
 
	ADMIN_FREQUENCY_AUTOMATIC = 0x40, ///< The admin gets information about this when it changes.
 
};
 
DECLARE_ENUM_AS_BIT_SET(AdminUpdateFrequency);
 

	
 
#define DECLARE_ADMIN_RECEIVE_COMMAND(type) virtual NetworkRecvStatus NetworkPacketReceive_## type ##_command(Packet *p)
 
#define DEF_ADMIN_RECEIVE_COMMAND(cls, type) NetworkRecvStatus cls ##NetworkAdminSocketHandler::NetworkPacketReceive_ ## type ## _command(Packet *p)
 

	
 
/** Main socket handler for admin related connections. */
 
class NetworkAdminSocketHandler : public NetworkTCPSocketHandler {
 
protected:
 
@@ -68,12 +87,26 @@ protected:
 
	/**
 
	 * Notification to the server that this admin is quitting.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_QUIT);
 

	
 
	/**
 
	 * Register updates to be sent at certain frequencies (as announced in the PROTOCOL packet):
 
	 * uint16  Update type (see #AdminUpdateType).
 
	 * uint16  Update frequency (see #AdminUpdateFrequency), setting #ADMIN_FREQUENCY_POLL is always ignored.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY);
 

	
 
	/**
 
	 * 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.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL);
 

	
 
	/**
 
	 * The server is full (connection gets closed).
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_FULL);
 

	
 
	/**
 
	 * The source IP address is banned (connection gets closed).
src/network/network_admin.cpp
Show inline comments
 
@@ -34,12 +34,18 @@ byte _network_admins_connected = 0;
 
NetworkAdminSocketPool _networkadminsocket_pool("NetworkAdminSocket");
 
INSTANTIATE_POOL_METHODS(NetworkAdminSocket)
 

	
 
/** The timeout for authorisation of the client. */
 
static const int ADMIN_AUTHORISATION_TIMEOUT = 10000;
 

	
 

	
 
/** Frequencies, which may be registered for a certain update type. */
 
static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
 
};
 
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
 

	
 
/**
 
 * Create a new socket for the server side of the admin network.
 
 * @param s The socket to connect with.
 
 */
 
ServerNetworkAdminSocketHandler::ServerNetworkAdminSocketHandler(SOCKET s) : NetworkAdminSocketHandler(s)
 
{
 
@@ -112,12 +118,18 @@ NetworkRecvStatus ServerNetworkAdminSock
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_PROTOCOL);
 

	
 
	/* announce the protocol version */
 
	p->Send_uint8(NETWORK_GAME_ADMIN_VERSION);
 

	
 
	for (int i = 0; i < ADMIN_UPDATE_END; i++) {
 
		p->Send_bool  (true);
 
		p->Send_uint16(i);
 
		p->Send_uint16(_admin_update_type_frequencies[i]);
 
	}
 

	
 
	p->Send_bool(false);
 
	this->Send_Packet(p);
 

	
 
	return this->SendWelcome();
 
}
 

	
 
@@ -190,12 +202,47 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_
 
DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_QUIT)
 
{
 
	/* The admin is leaving nothing else to do */
 
	return this->CloseConnection();
 
}
 

	
 
DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
 
{
 
	if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
 

	
 
	AdminUpdateType type = (AdminUpdateType)p->Recv_uint16();
 
	AdminUpdateFrequency freq = (AdminUpdateFrequency)p->Recv_uint16();
 

	
 
	if (type >= ADMIN_UPDATE_END || (_admin_update_type_frequencies[type] & freq) != freq) {
 
		/* The server does not know of this UpdateType. */
 
		DEBUG(net, 3, "[admin] Not supported update frequency %d (%d) from '%s' (%s).", type, freq, this->admin_name, this->admin_version);
 
		return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
 
	}
 

	
 
	this->update_frequency[type] = freq;
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_POLL)
 
{
 
	if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
 

	
 
	AdminUpdateType type = (AdminUpdateType)p->Recv_uint8();
 
	uint32 d1 = p->Recv_uint32();
 

	
 
	switch (type) {
 
		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);
 
			return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
 
	}
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
/*
 
 * Useful wrapper functions
 
 */
 

	
 
/**
 
 * Send a Welcome packet to all connected admins
 
@@ -205,7 +252,26 @@ void ServerNetworkAdminSocketHandler::We
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		as->SendWelcome();
 
	}
 
}
 

	
 
/**
 
 * Send (push) updates to the admin network as they have registered for these updates.
 
 * @param freq the frequency to be processd.
 
 */
 
void NetworkAdminUpdate(AdminUpdateFrequency freq)
 
{
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		for (int i = 0; i < ADMIN_UPDATE_END; i++) {
 
			if (as->update_frequency[i] & freq) {
 
				/* Update the admin for the required details */
 
				switch (i) {
 
					default: NOT_REACHED();
 
				}
 
			}
 
		}
 
	}
 
}
 

	
 
#endif /* ENABLE_NETWORK */
src/network/network_admin.h
Show inline comments
 
@@ -24,15 +24,18 @@ extern NetworkAdminSocketPool _networkad
 

	
 
/** Class for handling the server side of the game connection. */
 
class ServerNetworkAdminSocketHandler : public NetworkAdminSocketPool::PoolItem<&_networkadminsocket_pool>, public NetworkAdminSocketHandler, public TCPListenHandler<ServerNetworkAdminSocketHandler, ADMIN_PACKET_SERVER_FULL, ADMIN_PACKET_SERVER_BANNED> {
 
protected:
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_JOIN);
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_QUIT);
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY);
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL);
 

	
 
	NetworkRecvStatus SendProtocol();
 
public:
 
	AdminUpdateFrequency update_frequency[ADMIN_UPDATE_END]; ///< Admin requested update intervals.
 
	uint32 realtime_connect;                                 ///< Time of connection.
 
	NetworkAddress address;                                  ///< Address of the admin.
 

	
 
	ServerNetworkAdminSocketHandler(SOCKET s);
 
	~ServerNetworkAdminSocketHandler();
 

	
 
@@ -56,8 +59,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 NetworkAdminUpdate(AdminUpdateFrequency freq);
 

	
 
#endif /* ENABLE_NETWORK */
 
#endif /* NETWORK_ADMIN_H */
src/network/network_func.h
Show inline comments
 
@@ -56,12 +56,13 @@ bool NetworkCompanyIsPassworded(CompanyI
 
bool NetworkMaxCompaniesReached();
 
bool NetworkMaxSpectatorsReached();
 
void NetworkPrintClients();
 
void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode);
 

	
 
/*** Commands ran by the server ***/
 
void NetworkServerDailyLoop();
 
void NetworkServerMonthlyLoop();
 
void NetworkServerYearlyLoop();
 
void NetworkServerSendConfigUpdate();
 
void NetworkServerShowStatusToConsole();
 
bool NetworkServerStart();
 
void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded);
src/network/network_server.cpp
Show inline comments
 
@@ -12,12 +12,13 @@
 
#ifdef ENABLE_NETWORK
 

	
 
#include "../stdafx.h"
 
#include "../debug.h"
 
#include "../strings_func.h"
 
#include "../date_func.h"
 
#include "network_admin.h"
 
#include "network_server.h"
 
#include "network_udp.h"
 
#include "network.h"
 
#include "network_base.h"
 
#include "../console_func.h"
 
#include "../company_base.h"
 
@@ -1699,20 +1700,32 @@ void NetworkServer_Tick(bool send_frame)
 
	}
 

	
 
	/* See if we need to advertise */
 
	NetworkUDPAdvertise();
 
}
 

	
 
/** Yearly "callback". Called whenever the year changes. */
 
void NetworkServerYearlyLoop()
 
{
 
	NetworkCheckRestartMap();
 
	NetworkAdminUpdate(ADMIN_FREQUENCY_ANUALLY);
 
}
 

	
 
/** Monthly "callback". Called whenever the month changes. */
 
void NetworkServerMonthlyLoop()
 
{
 
	NetworkAutoCleanCompanies();
 
	NetworkAdminUpdate(ADMIN_FREQUENCY_MONTHLY);
 
	if ((_cur_month % 3) == 0) NetworkAdminUpdate(ADMIN_FREQUENCY_QUARTERLY);
 
}
 

	
 
/** Daily "callback". Called whenever the date changes. */
 
void NetworkServerDailyLoop()
 
{
 
	NetworkAdminUpdate(ADMIN_FREQUENCY_DAILY);
 
	if ((_date % 7) == 3) NetworkAdminUpdate(ADMIN_FREQUENCY_WEEKLY);
 
}
 

	
 
const char *GetClientIP(NetworkClientInfo *ci)
 
{
 
	return ci->client_address.GetHostname();
 
}
0 comments (0 inline, 0 general)