Add command/string helpers for string separator control character
This commit is contained in:
@@ -588,6 +588,7 @@ enum CommandFlags {
|
|||||||
CMD_SERVER_NS = 0x1000, ///< the command can only be initiated by the server (this is not executed in spectator mode)
|
CMD_SERVER_NS = 0x1000, ///< the command can only be initiated by the server (this is not executed in spectator mode)
|
||||||
CMD_LOG_AUX = 0x2000, ///< the command should be logged in the auxiliary log instead of the main log
|
CMD_LOG_AUX = 0x2000, ///< the command should be logged in the auxiliary log instead of the main log
|
||||||
CMD_P1_TILE = 0x4000, ///< use p1 for money text and error tile
|
CMD_P1_TILE = 0x4000, ///< use p1 for money text and error tile
|
||||||
|
CMD_STR_SEP = 0x8000, ///< the command's string may contain separator control characters
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(CommandFlags)
|
DECLARE_ENUM_AS_BIT_SET(CommandFlags)
|
||||||
|
|
||||||
|
@@ -330,7 +330,9 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c
|
|||||||
cp->tile = p->Recv_uint32();
|
cp->tile = p->Recv_uint32();
|
||||||
cp->binary_length = p->Recv_uint32();
|
cp->binary_length = p->Recv_uint32();
|
||||||
if (cp->binary_length == 0) {
|
if (cp->binary_length == 0) {
|
||||||
p->Recv_string(cp->text, (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK);
|
StringValidationSettings settings = (!_network_server && GetCommandFlags(cp->cmd) & CMD_STR_CTRL) != 0 ? SVS_ALLOW_CONTROL_CODE | SVS_REPLACE_WITH_QUESTION_MARK : SVS_REPLACE_WITH_QUESTION_MARK;
|
||||||
|
if (GetCommandFlags(cp->cmd) & CMD_STR_SEP) settings |= SVS_ALLOW_SEPARATOR_CODE;
|
||||||
|
p->Recv_string(cp->text, settings);
|
||||||
} else {
|
} else {
|
||||||
if (!p->CanReadFromPacket(cp->binary_length + /* callback index */ 1)) return "invalid binary data length";
|
if (!p->CanReadFromPacket(cp->binary_length + /* callback index */ 1)) return "invalid binary data length";
|
||||||
if (cp->binary_length > MAX_CMD_TEXT_LENGTH) return "over-size binary data length";
|
if (cp->binary_length > MAX_CMD_TEXT_LENGTH) return "over-size binary data length";
|
||||||
|
@@ -319,7 +319,7 @@ ScriptObject::ActiveInstance::~ActiveInstance()
|
|||||||
/* The string must be valid, i.e. not contain special codes. Since some
|
/* The string must be valid, i.e. not contain special codes. Since some
|
||||||
* can be made with GSText, make sure the control codes are removed. */
|
* can be made with GSText, make sure the control codes are removed. */
|
||||||
text_validated = text;
|
text_validated = text;
|
||||||
::StrMakeValidInPlace(text_validated, SVS_NONE);
|
::StrMakeValidInPlace(text_validated, (GetCommandFlags(cmd) & CMD_STR_SEP) ? SVS_ALLOW_SEPARATOR_CODE : SVS_NONE);
|
||||||
text = text_validated.c_str();
|
text = text_validated.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -261,6 +261,8 @@ static void StrMakeValidInPlace(T &dst, const char *str, const char *last, Strin
|
|||||||
} while (--len != 0);
|
} while (--len != 0);
|
||||||
} else if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\n') {
|
} else if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\n') {
|
||||||
*dst++ = *str++;
|
*dst++ = *str++;
|
||||||
|
} else if ((settings & SVS_ALLOW_SEPARATOR_CODE) != 0 && c == 0x1F) {
|
||||||
|
*dst++ = *str++;
|
||||||
} else {
|
} else {
|
||||||
if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\r' && str[1] == '\n') {
|
if ((settings & SVS_ALLOW_NEWLINE) != 0 && c == '\r' && str[1] == '\n') {
|
||||||
str += len;
|
str += len;
|
||||||
@@ -416,6 +418,21 @@ bool StrEndsWith(const std::string_view str, const std::string_view suffix)
|
|||||||
return str.compare(str.size() - suffix_len, suffix_len, suffix, 0, suffix_len) == 0;
|
return str.compare(str.size() - suffix_len, suffix_len, suffix, 0, suffix_len) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *StrConsumeToSeparator(std::string &result, const char *str)
|
||||||
|
{
|
||||||
|
if (str == nullptr) {
|
||||||
|
result = "";
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *end = str;
|
||||||
|
while (*end != '\0' && *end != 0x1F) {
|
||||||
|
end++;
|
||||||
|
}
|
||||||
|
result.assign(str, end);
|
||||||
|
if (*end == 0x1F) return end + 1;
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
/** Scans the string for colour codes and strips them */
|
/** Scans the string for colour codes and strips them */
|
||||||
void str_strip_colours(char *str)
|
void str_strip_colours(char *str)
|
||||||
|
@@ -59,6 +59,8 @@ void StrTrimInPlace(std::string &str);
|
|||||||
bool StrStartsWith(const std::string_view str, const std::string_view prefix);
|
bool StrStartsWith(const std::string_view str, const std::string_view prefix);
|
||||||
bool StrEndsWith(const std::string_view str, const std::string_view suffix);
|
bool StrEndsWith(const std::string_view str, const std::string_view suffix);
|
||||||
|
|
||||||
|
const char *StrConsumeToSeparator(std::string &result, const char *str);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if a string buffer is empty.
|
* Check if a string buffer is empty.
|
||||||
*
|
*
|
||||||
|
@@ -52,6 +52,7 @@ enum StringValidationSettings {
|
|||||||
SVS_REPLACE_WITH_QUESTION_MARK = 1 << 0, ///< Replace the unknown/bad bits with question marks.
|
SVS_REPLACE_WITH_QUESTION_MARK = 1 << 0, ///< Replace the unknown/bad bits with question marks.
|
||||||
SVS_ALLOW_NEWLINE = 1 << 1, ///< Allow newlines.
|
SVS_ALLOW_NEWLINE = 1 << 1, ///< Allow newlines.
|
||||||
SVS_ALLOW_CONTROL_CODE = 1 << 2, ///< Allow the special control codes.
|
SVS_ALLOW_CONTROL_CODE = 1 << 2, ///< Allow the special control codes.
|
||||||
|
SVS_ALLOW_SEPARATOR_CODE = 1 << 3, ///< Allow separator control code (0x1F).
|
||||||
};
|
};
|
||||||
DECLARE_ENUM_AS_BIT_SET(StringValidationSettings)
|
DECLARE_ENUM_AS_BIT_SET(StringValidationSettings)
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user