(svn r20967) -Add: infrastructure to send information to remote admins at specific intervals (dihedral)

pull/155/head
rubidium 14 years ago
parent 7d42a44556
commit 72c85d1cdb

@ -250,6 +250,7 @@ static void OnNewDay()
{
#ifdef ENABLE_NETWORK
NetworkChatMessageDailyLoop();
if (_network_server) NetworkServerDailyLoop();
#endif /* ENABLE_NETWORK */
DisasterDailyLoop();

@ -52,6 +52,8 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
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)
@ -107,6 +109,8 @@ NetworkRecvStatus NetworkAdminSocketHandler::NetworkPacketReceive_## type ##_com
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)

@ -28,6 +28,8 @@
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.
@ -47,6 +49,23 @@ enum AdminStatus {
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)
@ -70,6 +89,20 @@ protected:
*/
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).
*/

@ -37,6 +37,12 @@ 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.
@ -115,6 +121,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendProtocol()
/* 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);
@ -193,6 +205,41 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_QUIT)
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
*/
@ -208,4 +255,23 @@ void ServerNetworkAdminSocketHandler::WelcomeAll()
}
}
/**
* 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 */

@ -27,9 +27,12 @@ class ServerNetworkAdminSocketHandler : public NetworkAdminSocketPool::PoolItem<
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.
@ -59,5 +62,7 @@ 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 */

@ -59,6 +59,7 @@ void NetworkPrintClients();
void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode);
/*** Commands ran by the server ***/
void NetworkServerDailyLoop();
void NetworkServerMonthlyLoop();
void NetworkServerYearlyLoop();
void NetworkServerSendConfigUpdate();

@ -15,6 +15,7 @@
#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"
@ -1702,14 +1703,26 @@ void NetworkServer_Tick(bool send_frame)
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)

Loading…
Cancel
Save