(svn r20973) -Add: chat sending and receiving support for remote admins (dihedral)

pull/155/head
rubidium 14 years ago
parent de8feb0d01
commit 28832b68f5

@ -54,6 +54,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_QUIT)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_POLL)
ADMIN_COMMAND(ADMIN_PACKET_ADMIN_CHAT)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_FULL)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_BANNED)
@ -75,6 +76,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_REMOVE)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_ECONOMY)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_STATS)
ADMIN_COMMAND(ADMIN_PACKET_SERVER_CHAT)
default:
if (this->HasClientQuit()) {
@ -124,6 +126,7 @@ 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_ADMIN_CHAT)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_FULL)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_BANNED)
@ -145,5 +148,6 @@ DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_UPDATE)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_REMOVE)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_ECONOMY)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_STATS)
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CHAT)
#endif /* ENABLE_NETWORK */

@ -30,6 +30,7 @@ enum PacketAdminType {
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_ADMIN_CHAT, ///< The admin sends a chat message to be distributed.
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.
@ -51,6 +52,7 @@ enum PacketAdminType {
ADMIN_PACKET_SERVER_COMPANY_REMOVE, ///< The server tells the admin that a company was removed.
ADMIN_PACKET_SERVER_COMPANY_ECONOMY, ///< The server gives the admin some economy related company information.
ADMIN_PACKET_SERVER_COMPANY_STATS, ///< The server gives the admin some statistics about a company.
ADMIN_PACKET_SERVER_CHAT, ///< The server received a chat message and relays it.
INVALID_ADMIN_PACKET = 0xFF, ///< An invalid marker for admin packets.
};
@ -69,6 +71,7 @@ enum AdminUpdateType {
ADMIN_UPDATE_COMPANY_INFO, ///< Updates about the generic information of companies.
ADMIN_UPDATE_COMPANY_ECONOMY, ///< Updates about the economy of companies.
ADMIN_UPDATE_COMPANY_STATS, ///< Updates about the statistics of companies.
ADMIN_UPDATE_CHAT, ///< The admin would like to have chat messages.
ADMIN_UPDATE_END ///< Must ALWAYS be on the end of this list!! (period)
};
@ -130,6 +133,15 @@ protected:
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL);
/**
* Send chat as the server:
* uint8 Action such as NETWORK_ACTION_CHAT_CLIENT (see #NetworkAction).
* uint8 Destination type such as DESTTYPE_BROADCAST (see #DestType).
* uint32 ID of the destination such as company or client id.
* string Message.
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_CHAT);
/**
* The server is full (connection gets closed).
*/
@ -294,6 +306,16 @@ protected:
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_STATS);
/**
* Send chat from the game into the admin network:
* uint8 Action such as NETWORK_ACTION_CHAT_CLIENT (see #NetworkAction).
* uint8 Destination type such as DESTTYPE_BROADCAST (see #DestType).
* uint32 ID of the client who sent this message.
* string Message.
* uint64 Money (only when it is a 'give money' action).
*/
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CHAT);
NetworkRecvStatus HandlePacket(Packet *p);
public:
NetworkRecvStatus CloseConnection(bool error = true);

@ -45,6 +45,7 @@ static const AdminUpdateFrequency _admin_update_type_frequencies[] = {
ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_COMPANY_INFO
ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_COMPANY_ECONOMY
ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_WEEKLY | ADMIN_FREQUENCY_MONTHLY | ADMIN_FREQUENCY_QUARTERLY | ADMIN_FREQUENCY_ANUALLY, ///< ADMIN_UPDATE_COMPANY_STATS
ADMIN_FREQUENCY_AUTOMATIC, ///< ADMIN_UPDATE_CHAT
};
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
@ -384,6 +385,20 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats()
return NETWORK_RECV_STATUS_OKAY;
}
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data)
{
Packet *p = new Packet(ADMIN_PACKET_SERVER_CHAT);
p->Send_uint8 (action);
p->Send_uint8 (desttype);
p->Send_uint32(client_id);
p->Send_string(msg);
p->Send_uint64(data);
this->Send_Packet(p);
return NETWORK_RECV_STATUS_OKAY;
}
/***********
* Receiving functions
************/
@ -496,6 +511,33 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_POLL)
return NETWORK_RECV_STATUS_OKAY;
}
DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_PACKET_ADMIN_CHAT)
{
if (this->status == ADMIN_STATUS_INACTIVE) return this->SendError(NETWORK_ERROR_NOT_EXPECTED);
NetworkAction action = (NetworkAction)p->Recv_uint8();
DestType desttype = (DestType)p->Recv_uint8();
int dest = p->Recv_uint32();
char msg[NETWORK_CHAT_LENGTH];
p->Recv_string(msg, NETWORK_CHAT_LENGTH);
switch (action) {
case NETWORK_ACTION_CHAT:
case NETWORK_ACTION_CHAT_CLIENT:
case NETWORK_ACTION_CHAT_COMPANY:
case NETWORK_ACTION_SERVER_MESSAGE:
NetworkServerSendChat(action, desttype, dest, msg, _network_own_client_id, 0, true);
break;
default:
DEBUG(net, 3, "[admin] Invalid chat action %d from admin '%s' (%s).", action, this->admin_name, this->admin_version);
return this->SendError(NETWORK_ERROR_ILLEGAL_PACKET);
}
return NETWORK_RECV_STATUS_OKAY;
}
/*
* Useful wrapper functions
*/
@ -613,6 +655,22 @@ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bc
}
}
/**
* Send chat to the admin network (if they did opt in for the respective update).
*/
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data, bool from_admin)
{
if (from_admin) return;
ServerNetworkAdminSocketHandler *as;
FOR_ALL_ADMIN_SOCKETS(as) {
if (as->update_frequency[ADMIN_UPDATE_CHAT] & ADMIN_FREQUENCY_AUTOMATIC) {
as->SendChat(action, desttype, client_id, msg, data);
}
}
}
/**
* Send a Welcome packet to all connected admins
*/

@ -29,6 +29,7 @@ protected:
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);
DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_CHAT);
NetworkRecvStatus SendProtocol();
public:
@ -43,6 +44,7 @@ public:
NetworkRecvStatus SendWelcome();
NetworkRecvStatus SendNewGame();
NetworkRecvStatus SendShutdown();
NetworkRecvStatus SendDate();
NetworkRecvStatus SendClientJoin(ClientID client_id);
NetworkRecvStatus SendClientInfo(const NetworkClientInfo *ci);
@ -56,6 +58,8 @@ public:
NetworkRecvStatus SendCompanyEconomy();
NetworkRecvStatus SendCompanyStats();
NetworkRecvStatus SendChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data);
static void Send();
static void AcceptConnection(SOCKET s, const NetworkAddress &address);
static bool AllowConnection();
@ -81,6 +85,8 @@ void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code);
void NetworkAdminCompanyInfo(const Company *company, bool new_company);
void NetworkAdminCompanyUpdate(const Company *company);
void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr);
void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_id, const char *msg, int64 data = 0, bool from_admin = false);
void NetworkAdminUpdate(AdminUpdateFrequency freq);
#endif /* ENABLE_NETWORK */

@ -73,7 +73,7 @@ const char *GetClientIP(NetworkClientInfo *ci);
void NetworkServerDoMove(ClientID client_id, CompanyID company_id);
void NetworkServerSendRcon(ClientID client_id, ConsoleColour colour_code, const char *string);
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, int64 data = 0);
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, int64 data = 0, bool from_admin = false);
void NetworkServerKickClient(ClientID client_id);
uint NetworkServerKickOrBanIP(const char *ip, bool ban);

@ -1159,7 +1159,7 @@ DEF_GAME_RECEIVE_COMMAND(Server, PACKET_CLIENT_ACK)
void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data)
void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin)
{
NetworkClientSocket *cs;
const NetworkClientInfo *ci, *ci_own, *ci_to;
@ -1172,6 +1172,10 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
/* Display the text locally, and that is it */
if (ci != NULL) {
NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);
if (_settings_client.network.server_admin_chat) {
NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
}
}
} else {
/* Else find the client to send the message to */
@ -1215,6 +1219,11 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
}
}
/* if the server can read it, let the admin network read it, too. */
if (_local_company == (CompanyID)dest && _settings_client.network.server_admin_chat) {
NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
}
ci = NetworkFindClientInfoFromClientID(from_id);
ci_own = NetworkFindClientInfoFromClientID(CLIENT_ID_SERVER);
if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) {
@ -1251,6 +1260,9 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co
FOR_ALL_CLIENT_SOCKETS(cs) {
cs->SendChat(action, from_id, false, msg, data);
}
NetworkAdminChat(action, desttype, from_id, msg, data, from_admin);
ci = NetworkFindClientInfoFromClientID(from_id);
if (ci != NULL) {
NetworkTextMessage(action, (ConsoleColour)GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data);

@ -134,6 +134,7 @@ struct NetworkSettings {
bool pause_on_join; ///< pause the game when people join
uint16 server_port; ///< port the server listens on
uint16 server_admin_port; ///< port the server listens on for the admin network
bool server_admin_chat; ///< allow private chat for the server to be distributed to the admin network
char server_name[NETWORK_NAME_LENGTH]; ///< name of the server
char server_password[NETWORK_PASSWORD_LENGTH]; ///< password for joining this server
char rcon_password[NETWORK_PASSWORD_LENGTH]; ///< password for rconsole (server side)

@ -632,6 +632,7 @@ const SettingDesc _settings[] = {
SDTC_BOOL(network.pause_on_join, S, NO, true, STR_NULL, NULL),
SDTC_VAR(network.server_port, SLE_UINT16, S, NO,NETWORK_DEFAULT_PORT,0,65535,0,STR_NULL, NULL),
SDTC_VAR(network.server_admin_port, SLE_UINT16, S, NO, NETWORK_ADMIN_PORT,0,65535,0,STR_NULL, NULL),
SDTC_BOOL(network.server_admin_chat, S, NO, true, STR_NULL, NULL),
SDTC_BOOL(network.server_advertise, S, NO, false, STR_NULL, NULL),
SDTC_VAR(network.lan_internet, SLE_UINT8, S, NO, 0, 0, 1, 0, STR_NULL, NULL),
SDTC_STR(network.client_name, SLE_STRB, S, 0, NULL, STR_NULL, UpdateClientName),

Loading…
Cancel
Save