From 69fa0b36d3bb043858621ac0b32d451674ed2719 Mon Sep 17 00:00:00 2001 From: rubidium Date: Wed, 18 Aug 2010 17:06:45 +0000 Subject: [PATCH] (svn r20542) -Codechange: generalise the setting of "p2" to the ClientID. --- src/command.cpp | 12 ++++++++- src/command_type.h | 1 + src/company_cmd.cpp | 49 +++++++++++----------------------- src/console_cmds.cpp | 10 +++---- src/network/network_server.cpp | 14 +++------- 5 files changed, 36 insertions(+), 50 deletions(-) diff --git a/src/command.cpp b/src/command.cpp index f95e2577b5..a931cca03a 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -14,6 +14,7 @@ #include "landscape.h" #include "gui.h" #include "command_func.h" +#include "network/network_type.h" #include "network/network.h" #include "genworld.h" #include "newgrf_storage.h" @@ -283,7 +284,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdMoneyCheat, CMD_OFFLINE), // CMD_MONEY_CHEAT DEF_CMD(CmdBuildCanal, CMD_AUTO), // CMD_BUILD_CANAL - DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR), // CMD_COMPANY_CTRL + DEF_CMD(CmdCompanyCtrl, CMD_SPECTATOR | CMD_CLIENT_ID), // CMD_COMPANY_CTRL DEF_CMD(CmdLevelLand, CMD_ALL_TILES | CMD_NO_TEST | CMD_AUTO), // CMD_LEVEL_LAND; test run might clear tiles multiple times, in execution that only happens once @@ -499,6 +500,10 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac int x = TileX(tile) * TILE_SIZE; int y = TileY(tile) * TILE_SIZE; +#ifdef ENABLE_NETWORK + if (only_sending && GetCommandFlags(cmd) & CMD_CLIENT_ID) p2 = CLIENT_ID_SERVER; +#endif + CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only); if (res.Failed()) { /* Only show the error when it's for us. */ @@ -568,6 +573,11 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, /* Flags get send to the DoCommand */ DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags); +#ifdef ENABLE_NETWORK + /* Make sure p2 is properly set to a ClientID. */ + assert(!(cmd_flags & CMD_CLIENT_ID) || p2 != 0); +#endif + /* Do not even think about executing out-of-bounds tile-commands */ if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return_dcpi(CMD_ERROR, false); diff --git a/src/command_type.h b/src/command_type.h index 35e2b665ac..5d2d892fef 100644 --- a/src/command_type.h +++ b/src/command_type.h @@ -332,6 +332,7 @@ enum CommandFlags { CMD_ALL_TILES = 0x10, ///< allow this command also on MP_VOID tiles CMD_NO_TEST = 0x20, ///< the command's output may differ between test and execute due to town rating changes etc. CMD_NO_WATER = 0x40, ///< set the DC_NO_WATER flag on this command + CMD_CLIENT_ID = 0x80, ///< set p2 with the ClientID of the sending client. }; /** diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 1ac0c4eb78..b21d32279a 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.cpp @@ -572,7 +572,7 @@ static void MaybeStartNewCompany() if (n < (uint)_settings_game.difficulty.max_no_competitors) { /* Send a command to all clients to start up a new AI. * Works fine for Multiplayer and Singleplayer */ - DoCommandP(0, 1, INVALID_COMPANY, CMD_COMPANY_CTRL); + DoCommandP(0, 1 | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL); } } #endif /* ENABLE_AI */ @@ -745,46 +745,30 @@ void CompanyNewsInformation::FillData(const Company *c, const Company *other) * @param tile unused * @param flags operation to perform * @param p1 various functionality - * - p1 = 0 - create a new company, Which company (network) it will be is in p2 - * - p1 = 1 - create a new AI company - * - p1 = 2 - delete a company. Company is identified by p2 - * @param p2 various functionality, dictated by p1 - * - p1 = 0 - ClientID of the newly created client - * - p1 = 1 - CompanyID to start AI (INVALID_COMPANY for first available) - * - p1 = 2 - CompanyID of the that is getting deleted + * - bits 0..15: + * = 0 - create a new company + * = 1 - create a new AI company + * = 2 - delete a company + * - bits 16..24: CompanyID + * @param p2 ClientID * @param text unused * @return the cost of this operation or an error - * - * @todo In the case of p1=0, create new company, the clientID of the new client is in parameter - * p2. This parameter is passed in at function DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) - * on the server itself. First of all this is unbelievably ugly; second of all, well, - * it IS ugly! Someone fix this up :) So where to fix?@n - * @arg - network_server.c:838 DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND)@n - * @arg - network_client.c:536 DEF_CLIENT_RECEIVE_COMMAND(PACKET_SERVER_MAP) from where the map has been received */ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { InvalidateWindowData(WC_COMPANY_LEAGUE, 0, 0); + CompanyID company_id = (CompanyID)GB(p1, 16, 8); + ClientID client_id = (ClientID)p2; - switch (p1) { + switch (GB(p1, 0, 16)) { case 0: { // Create a new company /* This command is only executed in a multiplayer game */ if (!_networking) return CMD_ERROR; #ifdef ENABLE_NETWORK - - /* Joining Client: - * _local_company: COMPANY_SPECTATOR - * cid = clientid - * - * Other client(s)/server: - * _local_company: what they play as - * cid = requested company/company of joining client */ - ClientID cid = (ClientID)p2; - /* Has the network client a correct ClientIndex? */ if (!(flags & DC_EXEC)) return CommandCost(); - NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(cid); + NetworkClientInfo *ci = NetworkFindClientInfoFromClientID(client_id); if (ci == NULL) return CommandCost(); /* Delete multiplayer progress bar */ @@ -802,7 +786,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } /* This is the client (or non-dedicated server) who wants a new company */ - if (cid == _network_own_client_id) { + if (client_id == _network_own_client_id) { assert(_local_company == COMPANY_SPECTATOR); SetLocalCompany(c->index); if (!StrEmpty(_settings_client.network.default_company_pass)) { @@ -817,9 +801,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } if (_network_server) { - /* XXX - UGLY! p2 (pid) is mis-used to fetch the client-id, done at - * server side in network_server.c:838, function - * DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) */ CompanyID old_playas = ci->client_playas; ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); @@ -855,12 +836,12 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case 1: // Make a new AI company if (!(flags & DC_EXEC)) return CommandCost(); - if (p2 != INVALID_COMPANY && (p2 >= MAX_COMPANIES || Company::IsValidID(p2))) return CMD_ERROR; - DoStartupNewCompany(true, (CompanyID)p2); + if (company_id != INVALID_COMPANY && (company_id >= MAX_COMPANIES || Company::IsValidID(company_id))) return CMD_ERROR; + DoStartupNewCompany(true, company_id); break; case 2: { // Delete a company - Company *c = Company::GetIfValid(p2); + Company *c = Company::GetIfValid(company_id); if (c == NULL) return CMD_ERROR; if (!(flags & DC_EXEC)) return CommandCost(); diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index cd65461506..1c276ffb59 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.cpp @@ -761,7 +761,7 @@ DEF_CONSOLE_CMD(ConResetCompany) } /* It is safe to remove this company */ - DoCommandP(0, 2, index, CMD_COMPANY_CTRL); + DoCommandP(0, 2 | index << 16, 0, CMD_COMPANY_CTRL); IConsolePrint(CC_DEFAULT, "Company deleted."); return true; @@ -1067,7 +1067,7 @@ DEF_CONSOLE_CMD(ConStartAI) } /* Start a new AI company */ - DoCommandP(0, 1, INVALID_COMPANY, CMD_COMPANY_CTRL); + DoCommandP(0, 1 | INVALID_COMPANY << 16, 0, CMD_COMPANY_CTRL); return true; } @@ -1102,8 +1102,8 @@ DEF_CONSOLE_CMD(ConReloadAI) } /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(0, 2, company_id, CMD_COMPANY_CTRL); - DoCommandP(0, 1, company_id, CMD_COMPANY_CTRL); + DoCommandP(0, 2 | company_id << 16, 0, CMD_COMPANY_CTRL); + DoCommandP(0, 1 | company_id << 16, 0, CMD_COMPANY_CTRL); IConsolePrint(CC_DEFAULT, "AI reloaded."); return true; @@ -1139,7 +1139,7 @@ DEF_CONSOLE_CMD(ConStopAI) } /* Now kill the company of the AI. */ - DoCommandP(0, 2, company_id, CMD_COMPANY_CTRL); + DoCommandP(0, 2 | company_id << 16, 0, CMD_COMPANY_CTRL); IConsolePrint(CC_DEFAULT, "AI stopped, company deleted."); return true; diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index d2f3ce3aba..a363c2058a 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.cpp @@ -933,12 +933,6 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_COMPANY_MISMATCH); } - /** - * @todo CMD_COMPANY_CTRL with p1 = 0 announces a new company to the server. To give the - * company the correct ID, the server injects p2 and executes the command. Any other p1 - * is prohibited. Pretty ugly and should be redone together with its function. - * @see CmdCompanyCtrl() - */ if (cp.cmd == CMD_COMPANY_CTRL) { if (cp.p1 != 0 || cp.company != COMPANY_SPECTATOR) { return SEND_COMMAND(PACKET_SERVER_ERROR)(cs, NETWORK_ERROR_CHEATER); @@ -949,10 +943,10 @@ DEF_SERVER_RECEIVE_COMMAND(PACKET_CLIENT_COMMAND) NetworkServerSendChat(NETWORK_ACTION_SERVER_MESSAGE, DESTTYPE_CLIENT, ci->client_id, "cannot create new company, server full", CLIENT_ID_SERVER); return NETWORK_RECV_STATUS_OKAY; } - - cp.p2 = cs->client_id; } + if (GetCommandFlags(cp.cmd) & CMD_CLIENT_ID) cp.p2 = cs->client_id; + /* The frame can be executed in the same frame as the next frame-packet * That frame just before that frame is saved in _frame_counter_max */ cp.frame = _frame_counter_max + 1; @@ -1505,7 +1499,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ 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, CMD_COMPANY_CTRL); + DoCommandP(0, 2 | c->index << 16, 0, CMD_COMPANY_CTRL); 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? */ @@ -1519,7 +1513,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ 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, CMD_COMPANY_CTRL); + DoCommandP(0, 2 | c->index << 16, 0, CMD_COMPANY_CTRL); IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1); } } else {