mirror of
https://github.com/EQEmu/Server.git
synced 2025-12-11 16:51:29 +00:00
[Saylinks] Fix auto saylink injection edge cases (#1620)
* Fix auto saylink injection edge cases * Add even more resiliency to edge cases * Move to split based injection * Add some constants
This commit is contained in:
parent
3dcddcba04
commit
d197ee631e
@ -126,6 +126,7 @@ namespace Logs {
|
||||
ClientList,
|
||||
DiaWind,
|
||||
HTTP,
|
||||
Saylink,
|
||||
MaxCategoryID /* Don't Remove this */
|
||||
};
|
||||
|
||||
@ -210,6 +211,7 @@ namespace Logs {
|
||||
"ClientList",
|
||||
"DialogueWindow",
|
||||
"HTTP",
|
||||
"Saylink",
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -686,6 +686,16 @@
|
||||
OutF(LogSys, Logs::Detail, Logs::HTTP, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSaylink(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Saylink].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::General, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define LogSaylinkDetail(message, ...) do {\
|
||||
if (LogSys.log_settings[Logs::Saylink].is_category_enabled == 1)\
|
||||
OutF(LogSys, Logs::Detail, Logs::Saylink, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
} while (0)
|
||||
|
||||
#define Log(debug_level, log_category, message, ...) do {\
|
||||
if (LogSys.log_settings[log_category].is_category_enabled == 1)\
|
||||
LogSys.Out(debug_level, log_category, __FILE__, __func__, __LINE__, message, ##__VA_ARGS__);\
|
||||
|
||||
@ -102,13 +102,13 @@ const std::string &EQ::SayLinkEngine::GenerateLink()
|
||||
m_Link = "<LINKER ERROR>";
|
||||
LogError("SayLinkEngine::GenerateLink() failed to generate a useable say link");
|
||||
LogError(">> LinkType: {}, Lengths: [link: {}({}), body: {}({}), text: {}({})]",
|
||||
m_LinkType,
|
||||
m_Link.length(),
|
||||
EQ::constants::SAY_LINK_MAXIMUM_SIZE,
|
||||
m_LinkBody.length(),
|
||||
EQ::constants::SAY_LINK_BODY_SIZE,
|
||||
m_LinkText.length(),
|
||||
EQ::constants::SAY_LINK_TEXT_SIZE
|
||||
m_LinkType,
|
||||
m_Link.length(),
|
||||
EQ::constants::SAY_LINK_MAXIMUM_SIZE,
|
||||
m_LinkBody.length(),
|
||||
EQ::constants::SAY_LINK_BODY_SIZE,
|
||||
m_LinkText.length(),
|
||||
EQ::constants::SAY_LINK_TEXT_SIZE
|
||||
);
|
||||
LogError(">> LinkBody: {}", m_LinkBody.c_str());
|
||||
LogError(">> LinkText: {}", m_LinkText.c_str());
|
||||
@ -343,44 +343,137 @@ std::string EQ::SayLinkEngine::GenerateQuestSaylink(std::string saylink_text, bo
|
||||
|
||||
std::string EQ::SayLinkEngine::InjectSaylinksIfNotExist(const char *message)
|
||||
{
|
||||
std::string new_message = message;
|
||||
std::string new_message = message;
|
||||
int link_index = 0;
|
||||
int saylink_index = 0;
|
||||
std::vector<std::string> links = {};
|
||||
std::vector<std::string> saylinks = {};
|
||||
int saylink_length = 50;
|
||||
std::string saylink_separator = "\u0012";
|
||||
std::string saylink_partial = "000";
|
||||
|
||||
int link_index = 0;
|
||||
std::vector<std::string> links = {};
|
||||
LogSaylinkDetail("new_message pre pass 1 [{}]", new_message);
|
||||
|
||||
// first pass - strip existing saylinks by putting placeholder anchors on them
|
||||
for (auto &saylink: split_string(new_message, saylink_separator)) {
|
||||
if (!saylink.empty() && saylink.length() > saylink_length &&
|
||||
saylink.find(saylink_partial) != std::string::npos) {
|
||||
saylinks.emplace_back(saylink);
|
||||
|
||||
LogSaylinkDetail("Found saylink [{}]", saylink);
|
||||
|
||||
// replace with anchor
|
||||
find_replace(
|
||||
new_message,
|
||||
fmt::format("{}", saylink),
|
||||
fmt::format("<saylink:{}>", saylink_index)
|
||||
);
|
||||
|
||||
saylink_index++;
|
||||
}
|
||||
}
|
||||
|
||||
LogSaylinkDetail("new_message post pass 1 [{}]", new_message);
|
||||
|
||||
// loop through brackets until none exist
|
||||
while (new_message.find('[') != std::string::npos && new_message.find(']') != std::string::npos) {
|
||||
std::string bracket_message = get_between(new_message, "[", "]");
|
||||
if (new_message.find('[') != std::string::npos) {
|
||||
for (auto &b: split_string(new_message, "[")) {
|
||||
if (!b.empty() && b.find(']') != std::string::npos) {
|
||||
std::vector<std::string> right_split = split_string(b, "]");
|
||||
if (!right_split.empty()) {
|
||||
std::string bracket_message = trim(right_split[0]);
|
||||
|
||||
// already a saylink
|
||||
// todo: improve this later
|
||||
if (!bracket_message.empty() && bracket_message.length() > 50) {
|
||||
links.emplace_back(bracket_message);
|
||||
// we shouldn't see a saylink fragment here, ignore this bracket
|
||||
if (bracket_message.find(saylink_partial) != std::string::npos) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// if non empty bracket contents
|
||||
if (!bracket_message.empty()) {
|
||||
LogSaylinkDetail("Found bracket_message [{}]", bracket_message);
|
||||
|
||||
// already a saylink
|
||||
// todo: improve this later
|
||||
if (!bracket_message.empty() &&
|
||||
(bracket_message.length() > saylink_length ||
|
||||
bracket_message.find(saylink_separator) != std::string::npos)) {
|
||||
links.emplace_back(bracket_message);
|
||||
}
|
||||
else {
|
||||
links.emplace_back(
|
||||
EQ::SayLinkEngine::GenerateQuestSaylink(
|
||||
bracket_message,
|
||||
false,
|
||||
bracket_message
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
// replace with anchor
|
||||
find_replace(
|
||||
new_message,
|
||||
fmt::format("[{}]", bracket_message),
|
||||
fmt::format("<prelink:{}>", link_index)
|
||||
);
|
||||
|
||||
link_index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
links.emplace_back(EQ::SayLinkEngine::GenerateQuestSaylink(bracket_message, false, bracket_message));
|
||||
}
|
||||
|
||||
// replace with anchor
|
||||
find_replace(
|
||||
new_message,
|
||||
fmt::format("[{}]", bracket_message),
|
||||
fmt::format("<link:{}>", link_index)
|
||||
);
|
||||
|
||||
link_index++;
|
||||
}
|
||||
|
||||
LogSaylinkDetail("new_message post pass 2 (post brackets) [{}]", new_message);
|
||||
|
||||
// strip any current delimiters of saylinks
|
||||
find_replace(new_message, saylink_separator, "");
|
||||
|
||||
// pop links onto anchors
|
||||
link_index = 0;
|
||||
for (auto &link: links) {
|
||||
|
||||
// strip any current delimiters of saylinks
|
||||
find_replace(link, saylink_separator, "");
|
||||
|
||||
find_replace(
|
||||
new_message,
|
||||
fmt::format("<link:{}>", link_index),
|
||||
fmt::format("[{}]", link)
|
||||
fmt::format("<prelink:{}>", link_index),
|
||||
fmt::format("[\u0012{}\u0012]", link)
|
||||
);
|
||||
link_index++;
|
||||
}
|
||||
|
||||
LogSaylinkDetail("new_message post pass 3 (post prelink anchor pop) [{}]", new_message);
|
||||
|
||||
// pop links onto anchors
|
||||
saylink_index = 0;
|
||||
for (auto &link: saylinks) {
|
||||
// strip any current delimiters of saylinks
|
||||
find_replace(link, saylink_separator, "");
|
||||
|
||||
// check to see if we did a double anchor pass (existing saylink that was also inside brackets)
|
||||
// this means we found a saylink and we're checking to see if we're already encoded before double encoding
|
||||
if (new_message.find(fmt::format("\u0012<saylink:{}>\u0012", saylink_index)) != std::string::npos) {
|
||||
LogSaylinkDetail("Found encoded saylink at index [{}]", saylink_index);
|
||||
|
||||
find_replace(
|
||||
new_message,
|
||||
fmt::format("\u0012<saylink:{}>\u0012", saylink_index),
|
||||
fmt::format("\u0012{}\u0012", link)
|
||||
);
|
||||
saylink_index++;
|
||||
continue;
|
||||
}
|
||||
|
||||
find_replace(
|
||||
new_message,
|
||||
fmt::format("<saylink:{}>", saylink_index),
|
||||
fmt::format("\u0012{}\u0012", link)
|
||||
);
|
||||
saylink_index++;
|
||||
}
|
||||
|
||||
LogSaylinkDetail("new_message post pass 4 (post saylink anchor pop) [{}]", new_message);
|
||||
|
||||
return new_message;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user