1
0
Fork 0

Codechange: Replace sscanf with StringConsumer.

pull/14161/head
frosch 2025-04-29 13:30:56 +02:00 committed by frosch
parent 8027e31f47
commit e7d758c82a
2 changed files with 45 additions and 39 deletions

View File

@ -1156,70 +1156,72 @@ void NetworkGameLoop()
char buff[4096]; char buff[4096];
if (fgets(buff, lengthof(buff), *f) == nullptr) break; if (fgets(buff, lengthof(buff), *f) == nullptr) break;
char *p = buff; StringConsumer consumer{std::string_view{buff}};
/* Ignore the "[date time] " part of the message */ /* Ignore the "[date time] " part of the message */
if (*p == '[') { if (consumer.ReadCharIf('[')) {
p = strchr(p, ']'); consumer.SkipUntilChar(']', StringConsumer::SKIP_ONE_SEPARATOR);
if (p == nullptr) break; consumer.SkipCharIf(' ');
p += 2;
} }
if (strncmp(p, "cmd: ", 5) == 0 if (consumer.ReadIf("cmd: ")
#ifdef DEBUG_FAILED_DUMP_COMMANDS #ifdef DEBUG_FAILED_DUMP_COMMANDS
|| strncmp(p, "cmdf: ", 6) == 0 || consumer.ReadIf("cmdf: ")
#endif #endif
) { ) {
p += 5;
if (*p == ' ') p++;
cp = new CommandPacket(); cp = new CommandPacket();
int company; next_date = TimerGameEconomy::Date(consumer.ReadIntegerBase<uint32_t>(16));
uint cmd; bool valid = consumer.ReadIf("; ");
char buffer[256]; next_date_fract = consumer.ReadIntegerBase<uint32_t>(16);
uint32_t next_date_raw; valid &= consumer.ReadIf("; ");
int ret = sscanf(p, "%x; %x; %x; %x; %x; %255s", &next_date_raw, &next_date_fract, &company, &cmd, &cp->err_msg, buffer); cp->company = static_cast<CompanyID>(consumer.ReadIntegerBase<uint16_t>(16));
assert(ret == 6); valid &= consumer.ReadIf("; ");
next_date = TimerGameEconomy::Date((int32_t)next_date_raw); cp->cmd = static_cast<Commands>(consumer.ReadIntegerBase<uint32_t>(16));
cp->company = (CompanyID)company; valid &= consumer.ReadIf("; ");
cp->cmd = (Commands)cmd; cp->err_msg = consumer.ReadIntegerBase<uint32_t>(16);
valid &= consumer.ReadIf("; ");
auto args = consumer.ReadUntilChar(' ', StringConsumer::SKIP_ONE_SEPARATOR);
assert(valid);
/* Parse command data. */ /* Parse command data. */
std::vector<uint8_t> args; cp->data.clear();
size_t arg_len = strlen(buffer); for (size_t i = 0; i + 1 < args.size(); i += 2) {
for (size_t i = 0; i + 1 < arg_len; i += 2) {
uint8_t e = 0; uint8_t e = 0;
std::from_chars(buffer + i, buffer + i + 2, e, 16); std::from_chars(buffer + i, buffer + i + 2, e, 16);
args.emplace_back(e); cp->data.push_back(e);
} }
cp->data = args; } else if (consumer.ReadIf("join: ")) {
} else if (strncmp(p, "join: ", 6) == 0) {
/* Manually insert a pause when joining; this way the client can join at the exact right time. */ /* Manually insert a pause when joining; this way the client can join at the exact right time. */
uint32_t next_date_raw; next_date = TimerGameEconomy::Date(consumer.ReadIntegerBase<uint32_t>(16));
int ret = sscanf(p + 6, "%x; %x", &next_date_raw, &next_date_fract); bool valid = consumer.ReadIf("; ");
next_date = TimerGameEconomy::Date((int32_t)next_date_raw); next_date_fract = consumer.ReadIntegerBase<uint32_t>(16);
assert(ret == 2); assert(valid);
Debug(desync, 0, "Injecting pause for join at {:08x}:{:02x}; please join when paused", next_date, next_date_fract); Debug(desync, 0, "Injecting pause for join at {:08x}:{:02x}; please join when paused", next_date, next_date_fract);
cp = new CommandPacket(); cp = new CommandPacket();
cp->company = COMPANY_SPECTATOR; cp->company = COMPANY_SPECTATOR;
cp->cmd = CMD_PAUSE; cp->cmd = CMD_PAUSE;
cp->data = EndianBufferWriter<>::FromValue(CommandTraits<CMD_PAUSE>::Args{ PauseMode::Normal, true }); cp->data = EndianBufferWriter<>::FromValue(CommandTraits<CMD_PAUSE>::Args{ PauseMode::Normal, true });
_ddc_fastforward = false; _ddc_fastforward = false;
} else if (strncmp(p, "sync: ", 6) == 0) { } else if (consumer.ReadIf("sync: ")) {
uint32_t next_date_raw; next_date = TimerGameEconomy::Date(consumer.ReadIntegerBase<uint32_t>(16));
int ret = sscanf(p + 6, "%x; %x; %x; %x", &next_date_raw, &next_date_fract, &sync_state[0], &sync_state[1]); bool valid = consumer.ReadIf("; ");
next_date = TimerGameEconomy::Date((int32_t)next_date_raw); next_date_fract = consumer.ReadIntegerBase<uint32_t>(16);
assert(ret == 4); valid &= consumer.ReadIf("; ");
sync_state[0] = consumer.ReadIntegerBase<uint32_t>(16);
valid &= consumer.ReadIf("; ");
sync_state[1] = consumer.ReadIntegerBase<uint32_t>(16);
assert(valid);
check_sync_state = true; check_sync_state = true;
} else if (strncmp(p, "msg: ", 5) == 0 || strncmp(p, "client: ", 8) == 0 || } else if (consumer.ReadIf("msg: ") || consumer.ReadIf("client: ") ||
strncmp(p, "load: ", 6) == 0 || strncmp(p, "save: ", 6) == 0 || consumer.ReadIf("load: ") || consumer.ReadIf("save: ") ||
strncmp(p, "warning: ", 9) == 0) { consumer.ReadIf("warning: ")) {
/* A message that is not very important to the log playback, but part of the log. */ /* A message that is not very important to the log playback, but part of the log. */
#ifndef DEBUG_FAILED_DUMP_COMMANDS #ifndef DEBUG_FAILED_DUMP_COMMANDS
} else if (strncmp(p, "cmdf: ", 6) == 0) { } else if (consumer.ReadIf("cmdf: ")) {
Debug(desync, 0, "Skipping replay of failed command: {}", p + 6); Debug(desync, 0, "Skipping replay of failed command: {}", consumer.Read(StringConsumer::npos));
#endif #endif
} else { } else {
/* Can't parse a line; what's wrong here? */ /* Can't parse a line; what's wrong here? */
Debug(desync, 0, "Trying to parse: {}", p); Debug(desync, 0, "Trying to parse: {}", consumer.Read(StringConsumer::npos));
NOT_REACHED(); NOT_REACHED();
} }
} }

View File

@ -47,6 +47,10 @@
/* No clear replacement. */ /* No clear replacement. */
#define strtok SAFEGUARD_DO_NOT_USE_THIS_METHOD #define strtok SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use StringConsumer instead. */
#define sscanf SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define from_string SAFEGUARD_DO_NOT_USE_THIS_METHOD
/* Use fmt::print instead. */ /* Use fmt::print instead. */
#define printf SAFEGUARD_DO_NOT_USE_THIS_METHOD #define printf SAFEGUARD_DO_NOT_USE_THIS_METHOD
#define fprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD #define fprintf SAFEGUARD_DO_NOT_USE_THIS_METHOD