Codechange: Untangle command code, flags and error string for DoCommand*.

This commit is contained in:
Michael Lutz
2021-10-03 21:13:32 +02:00
parent 549caca39c
commit a38bbefe1b
47 changed files with 354 additions and 345 deletions

View File

@@ -1064,7 +1064,7 @@ void NetworkGameLoop()
while (f != nullptr && !feof(f)) {
if (_date == next_date && _date_fract == next_date_fract) {
if (cp != nullptr) {
NetworkSendCommand(cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->company, cp->tile, cp->p1, cp->p2, cp->text);
NetworkSendCommand(cp->cmd, cp->err_msg, nullptr, cp->company, cp->tile, cp->p1, cp->p2, cp->text);
Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:06x}; {:08x}; {:08x}; {:08x}; \"{}\" ({})", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd));
delete cp;
cp = nullptr;
@@ -1103,14 +1103,16 @@ void NetworkGameLoop()
if (*p == ' ') p++;
cp = new CommandPacket();
int company;
uint cmd;
char buffer[128];
int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; \"%127[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cp->cmd, buffer);
int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %x; %x; \"%127[^\"]\"", &next_date, &next_date_fract, &company, &cp->tile, &cp->p1, &cp->p2, &cmd, &cp->err_msg, buffer);
cp->text = buffer;
/* There are 8 pieces of data to read, however the last is a
* string that might or might not exist. Ignore it if that
* string misses because in 99% of the time it's not used. */
assert(ret == 8 || ret == 7);
assert(ret == 9 || ret == 8);
cp->company = (CompanyID)company;
cp->cmd = (Commands)cmd;
} else if (strncmp(p, "join: ", 6) == 0) {
/* Manually insert a pause when joining; this way the client can join at the exact right time. */
int ret = sscanf(p + 6, "%x; %x", &next_date, &next_date_fract);

View File

@@ -593,8 +593,8 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdNames()
{
Packet *p = new Packet(ADMIN_PACKET_SERVER_CMD_NAMES);
for (uint i = 0; i < CMD_END; i++) {
const char *cmdname = GetCommandName(i);
for (uint16 i = 0; i < CMD_END; i++) {
const char *cmdname = GetCommandName(static_cast<Commands>(i));
/* Should COMPAT_MTU be exceeded, start a new packet
* (magic 5: 1 bool "more data" and one uint16 "command id", one
@@ -629,7 +629,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCmdLogging(ClientID clien
p->Send_uint32(client_id);
p->Send_uint8 (cp->company);
p->Send_uint16(cp->cmd & CMD_ID_MASK);
p->Send_uint16(cp->cmd);
p->Send_uint32(cp->p1);
p->Send_uint32(cp->p2);
p->Send_uint32(cp->tile);

View File

@@ -839,7 +839,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
* the server will give us a client-id and let us in */
_network_join_status = NETWORK_JOIN_STATUS_REGISTERING;
ShowJoinStatusWindow();
NetworkSendCommand(CMD_COMPANY_CTRL, nullptr, _local_company, 0, CCA_NEW, 0, {});
NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {});
}
} else {
/* take control over an existing company */

View File

@@ -126,6 +126,7 @@ static CommandQueue _local_execution_queue;
/**
* Prepare a DoCommand to be send over the network
* @param cmd The command to execute (a CMD_* value)
* @param err_message Message prefix to show on error
* @param callback A callback function to call after the command is finished
* @param company The company that wants to send the command
* @param tile The tile to perform a command on (see #CommandProc)
@@ -133,16 +134,15 @@ static CommandQueue _local_execution_queue;
* @param p2 Additional data for the command (see #CommandProc)
* @param text The text to pass
*/
void NetworkSendCommand(uint32 cmd, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
void NetworkSendCommand(Commands cmd, StringID err_message, CommandCallback *callback, CompanyID company, TileIndex tile, uint32 p1, uint32 p2, const std::string &text)
{
assert((cmd & CMD_FLAGS_MASK) == 0);
CommandPacket c;
c.company = company;
c.tile = tile;
c.p1 = p1;
c.p2 = p2;
c.cmd = cmd;
c.err_msg = err_message;
c.callback = callback;
c.text = text;
@@ -207,8 +207,7 @@ void NetworkExecuteLocalCommandQueue()
/* We can execute this command */
_current_company = cp->company;
cp->cmd |= CMD_NETWORK_COMMAND;
DoCommandP(cp, cp->my_cmd);
DoCommandP(cp, cp->my_cmd, true);
queue.Pop();
delete cp;
@@ -295,10 +294,10 @@ void NetworkDistributeCommands()
const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *cp)
{
cp->company = (CompanyID)p->Recv_uint8();
cp->cmd = p->Recv_uint32();
cp->cmd = static_cast<Commands>(p->Recv_uint16());
if (!IsValidCommand(cp->cmd)) return "invalid command";
if (GetCommandFlags(cp->cmd) & CMD_OFFLINE) return "single-player only command";
if ((cp->cmd & CMD_FLAGS_MASK) != 0) return "invalid command flag";
cp->err_msg = p->Recv_uint16();
cp->p1 = p->Recv_uint32();
cp->p2 = p->Recv_uint32();
@@ -320,7 +319,8 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp)
{
p->Send_uint8 (cp->company);
p->Send_uint32(cp->cmd);
p->Send_uint16(cp->cmd);
p->Send_uint16(cp->err_msg);
p->Send_uint32(cp->p1);
p->Send_uint32(cp->p2);
p->Send_uint32(cp->tile);

View File

@@ -1537,7 +1537,7 @@ private:
if (_network_server) {
DoCommandP(CMD_COMPANY_CTRL, 0, CCA_NEW, _network_own_client_id);
} else {
NetworkSendCommand(CMD_COMPANY_CTRL, nullptr, _local_company, 0, CCA_NEW, 0, {});
NetworkSendCommand(CMD_COMPANY_CTRL, STR_NULL, nullptr, _local_company, 0, CCA_NEW, 0, {});
}
}

View File

@@ -1034,12 +1034,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet
if ((GetCommandFlags(cp.cmd) & CMD_SERVER) && ci->client_id != CLIENT_ID_SERVER) {
IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a server only command {}.", ci->client_id, this->GetClientIP(), cp.cmd & CMD_ID_MASK);
IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a server only command {}.", ci->client_id, this->GetClientIP(), cp.cmd);
return this->SendError(NETWORK_ERROR_KICKED);
}
if ((GetCommandFlags(cp.cmd) & CMD_SPECTATOR) == 0 && !Company::IsValidID(cp.company) && ci->client_id != CLIENT_ID_SERVER) {
IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a non-spectator command {}.", ci->client_id, this->GetClientIP(), cp.cmd & CMD_ID_MASK);
IConsolePrint(CC_WARNING, "Kicking client #{} (IP: {}) due to calling a non-spectator command {}.", ci->client_id, this->GetClientIP(), cp.cmd);
return this->SendError(NETWORK_ERROR_KICKED);
}
@@ -2078,7 +2078,7 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci)
/* ci is nullptr when replaying, or for AIs. In neither case there is a client. */
ci->client_playas = c->index;
NetworkUpdateClientInfo(ci->client_id);
NetworkSendCommand(CMD_RENAME_PRESIDENT, nullptr, c->index, 0, 0, 0, ci->client_name);
NetworkSendCommand(CMD_RENAME_PRESIDENT, STR_NULL, nullptr, c->index, 0, 0, 0, ci->client_name);
}
/* Announce new company on network. */