Changeset - r16259:4ee91980c70f
[Not reviewed]
master
0 8 0
rubidium - 14 years ago 2010-10-17 17:37:45
rubidium@openttd.org
(svn r20970) -Add: company change notification to remote admins (dihedral)
8 files changed with 246 insertions and 0 deletions:
0 comments (0 inline, 0 general)
src/company_cmd.cpp
Show inline comments
 
@@ -21,6 +21,7 @@
 
#include "network/network.h"
 
#include "network/network_func.h"
 
#include "network/network_base.h"
 
#include "network/network_admin.h"
 
#include "ai/ai.hpp"
 
#include "company_manager_face.h"
 
#include "window_func.h"
 
@@ -740,6 +741,28 @@ void CompanyNewsInformation::FillData(co
 
}
 

	
 
/**
 
 * Called whenever company related information changes in order to notify admins.
 
 * @param company The company data changed of.
 
 */
 
void CompanyAdminUpdate(const Company *company)
 
{
 
#ifdef ENABLE_NETWORK
 
	if (_network_server) NetworkAdminCompanyUpdate(company);
 
#endif /* ENABLE_NETWORK */
 
}
 

	
 
/**
 
 * Called whenever a company goes bankrupt in order to notify admins.
 
 * @param company_id The company that went bankrupt.
 
 */
 
void CompanyAdminBankrupt(CompanyID company_id)
 
{
 
#ifdef ENABLE_NETWORK
 
	if (_network_server) NetworkAdminCompanyRemove(company_id, ADMIN_CRR_BANKRUPT);
 
#endif /* ENABLE_NETWORK */
 
}
 

	
 
/**
 
 * Control the companies: add, delete, etc.
 
 * @param tile unused
 
 * @param flags operation to perform
 
@@ -827,6 +850,7 @@ CommandCost CmdCompanyCtrl(TileIndex til
 

	
 
				/* Announce new company on network, if the client was a SPECTATOR before */
 
				if (old_playas == COMPANY_SPECTATOR) {
 
					NetworkAdminCompanyInfo(c, true);
 
					NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, ci->client_playas + 1);
 
				}
 
			}
 
@@ -865,6 +889,7 @@ CommandCost CmdCompanyCtrl(TileIndex til
 
			CompanyID c_index = c->index;
 
			delete c;
 
			AI::BroadcastNewEvent(new AIEventCompanyBankrupt(c_index));
 
			CompanyAdminBankrupt(c_index);
 
			break;
 
		}
 

	
 
@@ -935,6 +960,7 @@ CommandCost CmdSetCompanyColour(TileInde
 
				if (scheme == LS_DEFAULT) {
 
					_company_colours[_current_company] = colour;
 
					c->colour = colour;
 
					CompanyAdminUpdate(c);
 
				}
 
				break;
 

	
 
@@ -1032,6 +1058,7 @@ CommandCost CmdRenameCompany(TileIndex t
 
		free(c->name);
 
		c->name = reset ? NULL : strdup(text);
 
		MarkWholeScreenDirty();
 
		CompanyAdminUpdate(c);
 
	}
 

	
 
	return CommandCost();
 
@@ -1089,6 +1116,7 @@ CommandCost CmdRenamePresident(TileIndex
 
		}
 

	
 
		MarkWholeScreenDirty();
 
		CompanyAdminUpdate(c);
 
	}
 

	
 
	return CommandCost();
src/company_func.h
Show inline comments
 
@@ -21,6 +21,8 @@ void ChangeOwnershipOfCompanyItems(Owner
 
void GetNameOfOwner(Owner owner, TileIndex tile);
 
void SetLocalCompany(CompanyID new_company);
 
void ShowBuyCompanyDialog(CompanyID company);
 
void CompanyAdminUpdate(const Company *company);
 
void CompanyAdminBankrupt(CompanyID company_id);
 

	
 
extern CompanyByte _local_company;
 
extern CompanyByte _current_company;
src/economy.cpp
Show inline comments
 
@@ -534,6 +534,7 @@ static void CompanyCheckBankrupt(Company
 
			CompanyID c_index = c->index;
 
			delete c;
 
			AI::BroadcastNewEvent(new AIEventCompanyBankrupt(c_index));
 
			CompanyAdminBankrupt(c_index);
 
	}
 
}
 

	
 
@@ -1534,6 +1535,7 @@ CommandCost CmdBuyShareInCompany(TileInd
 
			}
 
		}
 
		SetWindowDirty(WC_COMPANY, target_company);
 
		CompanyAdminUpdate(c);
 
	}
 
	return cost;
 
}
 
@@ -1568,6 +1570,7 @@ CommandCost CmdSellShareInCompany(TileIn
 
		while (*b != _current_company) b++; // share owners is guaranteed to contain company
 
		*b = COMPANY_SPECTATOR;
 
		SetWindowDirty(WC_COMPANY, target_company);
 
		CompanyAdminUpdate(c);
 
	}
 
	return CommandCost(EXPENSES_OTHER, cost);
 
}
src/network/core/tcp_admin.cpp
Show inline comments
 
@@ -69,6 +69,10 @@ NetworkRecvStatus NetworkAdminSocketHand
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_UPDATE)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_QUIT)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_CLIENT_ERROR)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_NEW)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_INFO)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_UPDATE)
 
		ADMIN_COMMAND(ADMIN_PACKET_SERVER_COMPANY_REMOVE)
 

	
 
		default:
 
			if (this->HasClientQuit()) {
 
@@ -133,5 +137,9 @@ DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND
 
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)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_NEW)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_INFO)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_UPDATE)
 
DEFINE_UNAVAILABLE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_REMOVE)
 

	
 
#endif /* ENABLE_NETWORK */
src/network/core/tcp_admin.h
Show inline comments
 
@@ -45,6 +45,10 @@ enum PacketAdminType {
 
	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.
 
	ADMIN_PACKET_SERVER_COMPANY_NEW,     ///< The server tells the admin that a new company has started.
 
	ADMIN_PACKET_SERVER_COMPANY_INFO,    ///< The server gives the admin information about a company.
 
	ADMIN_PACKET_SERVER_COMPANY_UPDATE,  ///< The server gives the admin an information update on a company.
 
	ADMIN_PACKET_SERVER_COMPANY_REMOVE,  ///< The server tells the admin that a company was removed.
 

	
 
	INVALID_ADMIN_PACKET = 0xFF,         ///< An invalid marker for admin packets.
 
};
 
@@ -60,6 +64,7 @@ enum AdminStatus {
 
enum AdminUpdateType {
 
	ADMIN_UPDATE_DATE,            ///< Updates about the date of the game.
 
	ADMIN_UPDATE_CLIENT_INFO,     ///< Updates about the information of clients.
 
	ADMIN_UPDATE_COMPANY_INFO,    ///< Updates about the generic information of companies.
 
	ADMIN_UPDATE_END              ///< Must ALWAYS be on the end of this list!! (period)
 
};
 

	
 
@@ -75,6 +80,13 @@ enum AdminUpdateFrequency {
 
};
 
DECLARE_ENUM_AS_BIT_SET(AdminUpdateFrequency);
 

	
 
/** Reasons for removing a company - communicated to admins. */
 
enum AdminCompanyRemoveReason {
 
	ADMIN_CRR_MANUAL,    ///< The company is manually removed.
 
	ADMIN_CRR_AUTOCLEAN, ///< The company is removed due to autoclean.
 
	ADMIN_CRR_BANKRUPT   ///< The company went belly-up.
 
};
 

	
 
#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)
 

	
 
@@ -110,6 +122,7 @@ protected:
 
	 * 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, e.g.
 
	 *          - the client ID for #ADMIN_UPDATE_CLIENT_INFO. Use UINT32_MAX to show all clients.
 
	 *          - the company ID for #ADMIN_UPDATE_COMPANY_INFO. Use UINT32_MAX to show all companies.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_ADMIN_POLL);
 

	
 
@@ -206,6 +219,46 @@ protected:
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_CLIENT_ERROR);
 

	
 
	/**
 
	 * Notification of a new company:
 
	 * uint8   ID of the new company.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_NEW);
 

	
 
	/**
 
	 * Company information on a specific company:
 
	 * uint8   ID of the company.
 
	 * string  Name of the company.
 
	 * string  Name of the companies manager.
 
	 * uint8   Main company colour.
 
	 * bool    Company is password protected.
 
	 * uint32  Year the company was inaugurated.
 
	 * bool    Company is an AI.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_INFO);
 

	
 
	/**
 
	 * Company information of a specific company:
 
	 * uint8   ID of the company.
 
	 * string  Name of the company.
 
	 * string  Name of the companies manager.
 
	 * uint8   Main company colour.
 
	 * bool    Company is password protected.
 
	 * uint8   Quarters of bankruptcy.
 
	 * uint8   Owner of share 1.
 
	 * uint8   Owner of share 2.
 
	 * uint8   Owner of share 3.
 
	 * uint8   Owner of share 4.
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_UPDATE);
 

	
 
	/**
 
	 * Notification about a removed company (e.g. due to banrkuptcy).
 
	 * uint8   ID of the company.
 
	 * uint8   Reason for being removed (see #AdminCompanyRemoveReason).
 
	 */
 
	DECLARE_ADMIN_RECEIVE_COMMAND(ADMIN_PACKET_SERVER_COMPANY_REMOVE);
 

	
 
	NetworkRecvStatus HandlePacket(Packet *p);
 
public:
 
	NetworkRecvStatus CloseConnection(bool error = true);
src/network/network_admin.cpp
Show inline comments
 
@@ -42,6 +42,7 @@ static const int ADMIN_AUTHORISATION_TIM
 
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
 
	ADMIN_FREQUENCY_POLL | ADMIN_FREQUENCY_AUTOMATIC,                                                                                                      ///< ADMIN_UPDATE_COMPANY_INFO
 
};
 
assert_compile(lengthof(_admin_update_type_frequencies) == ADMIN_UPDATE_END);
 

	
 
@@ -241,6 +242,83 @@ NetworkRecvStatus ServerNetworkAdminSock
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyNew(CompanyID company_id)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_NEW);
 
	p->Send_uint8(company_id);
 

	
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyInfo(const Company *c)
 
{
 
	char company_name[NETWORK_COMPANY_NAME_LENGTH];
 
	char manager_name[NETWORK_COMPANY_NAME_LENGTH];
 

	
 
	SetDParam(0, c->index);
 
	GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
 

	
 
	SetDParam(0, c->index);
 
	GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
 

	
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_INFO);
 

	
 
	p->Send_uint8 (c->index);
 
	p->Send_string(company_name);
 
	p->Send_string(manager_name);
 
	p->Send_uint8 (c->colour);
 
	p->Send_bool  (NetworkCompanyIsPassworded(c->index));
 
	p->Send_uint32(c->inaugurated_year);
 
	p->Send_bool  (c->is_ai);
 

	
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyUpdate(const Company *c)
 
{
 
	char company_name[NETWORK_COMPANY_NAME_LENGTH];
 
	char manager_name[NETWORK_COMPANY_NAME_LENGTH];
 

	
 
	SetDParam(0, c->index);
 
	GetString(company_name, STR_COMPANY_NAME, lastof(company_name));
 

	
 
	SetDParam(0, c->index);
 
	GetString(manager_name, STR_PRESIDENT_NAME, lastof(manager_name));
 

	
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_UPDATE);
 

	
 
	p->Send_uint8 (c->index);
 
	p->Send_string(company_name);
 
	p->Send_string(manager_name);
 
	p->Send_uint8 (c->colour);
 
	p->Send_bool  (NetworkCompanyIsPassworded(c->index));
 
	p->Send_uint8 (c->quarters_of_bankruptcy);
 

	
 
	for (size_t i = 0; i < lengthof(c->share_owners); i++) {
 
		p->Send_uint8(c->share_owners[i]);
 
	}
 

	
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason acrr)
 
{
 
	Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_REMOVE);
 

	
 
	p->Send_uint8(company_id);
 
	p->Send_uint8(acrr);
 

	
 
	this->Send_Packet(p);
 

	
 
	return NETWORK_RECV_STATUS_OKAY;
 
}
 

	
 
/***********
 
 * Receiving functions
 
 ************/
 
@@ -321,6 +399,19 @@ DEF_ADMIN_RECEIVE_COMMAND(Server, ADMIN_
 
			}
 
			break;
 

	
 
		case ADMIN_UPDATE_COMPANY_INFO:
 
			/* The admin is asking for company info. */
 
			const Company *company;
 
			if (d1 == UINT32_MAX) {
 
				FOR_ALL_COMPANIES(company) {
 
					this->SendCompanyInfo(company);
 
				}
 
			} else {
 
				company = Company::GetIfValid(d1);
 
				if (company != NULL) this->SendCompanyInfo(company);
 
			}
 
			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);
 
@@ -396,6 +487,58 @@ void NetworkAdminClientError(ClientID cl
 
}
 

	
 
/**
 
 * Notify the admin network of company details.
 
 * @param company the company of which details will be sent into the admin network.
 
 * @param new_company whether this is a new company or not.
 
 */
 
void NetworkAdminCompanyInfo(const Company *company, bool new_company)
 
{
 
	if (company == NULL) {
 
		DEBUG(net, 1, "[admin] Empty company given for update");
 
		return;
 
	}
 

	
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
 

	
 
		as->SendCompanyInfo(company);
 
		if (new_company) {
 
			as->SendCompanyNew(company->index);
 
		}
 
	}
 
}
 

	
 
/**
 
 * Notify the admin network of company updates.
 
 * @param company company of which updates are going to be sent into the admin network.
 
 */
 
void NetworkAdminCompanyUpdate(const Company *company)
 
{
 
	if (company == NULL) return;
 

	
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue;
 

	
 
		as->SendCompanyUpdate(company);
 
	}
 
}
 

	
 
/**
 
 * Notify the admin network of a company to be removed (including the reason why).
 
 * @param company_id ID of the company that got removed.
 
 * @param bcrr the reason why the company got removed (e.g. bankruptcy).
 
 */
 
void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr)
 
{
 
	ServerNetworkAdminSocketHandler *as;
 
	FOR_ALL_ADMIN_SOCKETS(as) {
 
		as->SendCompanyRemove(company_id, bcrr);
 
	}
 
}
 

	
 
/**
 
 * Send a Welcome packet to all connected admins
 
 */
 
void ServerNetworkAdminSocketHandler::WelcomeAll()
src/network/network_admin.h
Show inline comments
 
@@ -49,6 +49,10 @@ public:
 
	NetworkRecvStatus SendClientUpdate(const NetworkClientInfo *ci);
 
	NetworkRecvStatus SendClientQuit(ClientID client_id);
 
	NetworkRecvStatus SendClientError(ClientID client_id, NetworkErrorCode error);
 
	NetworkRecvStatus SendCompanyNew(CompanyID company_id);
 
	NetworkRecvStatus SendCompanyInfo(const Company *c);
 
	NetworkRecvStatus SendCompanyUpdate(const Company *c);
 
	NetworkRecvStatus SendCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr);
 

	
 
	static void Send();
 
	static void AcceptConnection(SOCKET s, const NetworkAddress &address);
 
@@ -72,6 +76,9 @@ void NetworkAdminClientInfo(const Networ
 
void NetworkAdminClientUpdate(const NetworkClientInfo *ci);
 
void NetworkAdminClientQuit(ClientID client_id);
 
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 NetworkAdminUpdate(AdminUpdateFrequency freq);
 

	
 
#endif /* ENABLE_NETWORK */
src/network/network_server.cpp
Show inline comments
 
@@ -1544,6 +1544,7 @@ static void NetworkAutoCleanCompanies()
 
			if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) {
 
				/* Shut the company down */
 
				DoCommandP(0, 2 | c->index << 16, 0, CMD_COMPANY_CTRL);
 
				NetworkAdminCompanyRemove(c->index, ADMIN_CRR_AUTOCLEAN);
 
				IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1);
 
			}
 
			/* Is the company empty for autoclean_protected-months, and there is a protection? */
 
@@ -1558,6 +1559,7 @@ static void NetworkAutoCleanCompanies()
 
			if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) {
 
				/* Shut the company down */
 
				DoCommandP(0, 2 | c->index << 16, 0, CMD_COMPANY_CTRL);
 
				NetworkAdminCompanyRemove(c->index, ADMIN_CRR_AUTOCLEAN);
 
				IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1);
 
			}
 
		} else {
0 comments (0 inline, 0 general)