summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/date.cpp1
-rw-r--r--src/network/core/tcp_admin.cpp4
-rw-r--r--src/network/core/tcp_admin.h33
-rw-r--r--src/network/network_admin.cpp66
-rw-r--r--src/network/network_admin.h5
-rw-r--r--src/network/network_func.h1
-rw-r--r--src/network/network_server.cpp13
7 files changed, 123 insertions, 0 deletions
diff --git a/src/date.cpp b/src/date.cpp
index d8d2cc5ef..4ef16aed7 100644
--- a/src/date.cpp
+++ b/src/date.cpp
@@ -250,6 +250,7 @@ static void OnNewDay()
{
#ifdef ENABLE_NETWORK
NetworkChatMessageDailyLoop();
+ if (_network_server) NetworkServerDailyLoop();
#endif /* ENABLE_NETWORK */
DisasterDailyLoop();
diff --git a/src/network/core/tcp_admin.cpp b/src/network/core/tcp_admin.cpp
index 2d68fc68b..60ccfd064 100644
--- a/src/network/core/tcp_admin.cpp
+++ b/src/network/core/tcp_admin.cpp
@@ -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)
diff --git a/src/network/core/tcp_admin.h b/src/network/core/tcp_admin.h
index dae41c5f5..3ed444257 100644
--- a/src/network/core/tcp_admin.h
+++ b/src/network/core/tcp_admin.h
@@ -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)
@@ -71,6 +90,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).
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_FULL);
diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp
index b03f9422e..11b8d8ade 100644
--- a/src/network/network_admin.cpp
+++ b/src/network/network_admin.cpp
@@ -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 */
diff --git a/src/network/network_admin.h b/src/network/network_admin.h
index 1e0a3f2b6..c958f876f 100644
--- a/src/network/network_admin.h
+++ b/src/network/network_admin.h
@@ -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 */
diff --git a/src/network/network_func.h b/src/network/network_func.h
index da9499e81..00db245e3 100644
--- a/src/network/network_func.h
+++ b/src/network/network_func.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();
diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp
index ab2bd1632..ca446dfed 100644
--- a/src/network/network_server.cpp
+++ b/src/network/network_server.cpp
@@ -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)