Change: [Network] Transfer command data as serialized byte stream without fixed structure.
The data will be transmitted as the length followed by the serialized data. This allows the command data to be different for every command type in the future.
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include "../core/pool_func.hpp"
|
||||
#include "../gfx_func.h"
|
||||
#include "../error.h"
|
||||
#include "../misc_cmd.h"
|
||||
#include <charconv>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
@@ -1064,8 +1065,8 @@ void NetworkGameLoop()
|
||||
while (f != nullptr && !feof(f)) {
|
||||
if (_date == next_date && _date_fract == next_date_fract) {
|
||||
if (cp != nullptr) {
|
||||
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));
|
||||
NetworkSendCommand(cp->cmd, cp->err_msg, nullptr, cp->company, cp->data);
|
||||
Debug(desync, 0, "Injecting: {:08x}; {:02x}; {:02x}; {:08x}; {:06x}; {} ({})", _date, _date_fract, (int)_current_company, cp->cmd, cp->tile, FormatArrayAsHex(cp->data), GetCommandName(cp->cmd));
|
||||
delete cp;
|
||||
cp = nullptr;
|
||||
}
|
||||
@@ -1104,15 +1105,21 @@ void NetworkGameLoop()
|
||||
cp = new CommandPacket();
|
||||
int company;
|
||||
uint cmd;
|
||||
char buffer[128];
|
||||
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 == 9 || ret == 8);
|
||||
char buffer[256];
|
||||
int ret = sscanf(p, "%x; %x; %x; %x; %x; %x; %255s", &next_date, &next_date_fract, &company, &cmd, &cp->err_msg, &cp->tile, buffer);
|
||||
assert(ret == 6);
|
||||
cp->company = (CompanyID)company;
|
||||
cp->cmd = (Commands)cmd;
|
||||
|
||||
/* Parse command data. */
|
||||
std::vector<byte> args;
|
||||
size_t arg_len = strlen(buffer);
|
||||
for (size_t i = 0; i + 1 < arg_len; i += 2) {
|
||||
byte e = 0;
|
||||
std::from_chars(buffer + i, buffer + i + 1, e, 16);
|
||||
args.emplace_back(e);
|
||||
}
|
||||
cp->data = args;
|
||||
} 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);
|
||||
@@ -1121,8 +1128,7 @@ void NetworkGameLoop()
|
||||
cp = new CommandPacket();
|
||||
cp->company = COMPANY_SPECTATOR;
|
||||
cp->cmd = CMD_PAUSE;
|
||||
cp->p1 = PM_PAUSED_NORMAL;
|
||||
cp->p2 = 1;
|
||||
cp->data = EndianBufferWriter<>::FromValue(CommandTraits<CMD_PAUSE>::Args{ 0, PM_PAUSED_NORMAL, 1, "" });
|
||||
_ddc_fastforward = false;
|
||||
} else if (strncmp(p, "sync: ", 6) == 0) {
|
||||
int ret = sscanf(p + 6, "%x; %x; %x; %x", &next_date, &next_date_fract, &sync_state[0], &sync_state[1]);
|
||||
|
Reference in New Issue
Block a user