Better formspec prepend hack for 0.4 clients

master
luk3yx 2022-04-18 10:54:21 +12:00
parent 915f986e3d
commit e739e47273
4 changed files with 48 additions and 10 deletions

View File

@ -51,9 +51,8 @@ void NodeMetadata::serialize(std::ostream &os, u8 version, bool disk,
continue;
os << serializeString16(sv.first);
if (!formspec_prepend.empty() && sv.first == "formspec" &&
sv.second.find("no_prepend[]") == std::string::npos)
os << serializeString32(sv.second + formspec_prepend);
if (!formspec_prepend.empty() && sv.first == "formspec")
os << serializeString32(insert_formspec_prepend(sv.second, formspec_prepend));
else
os << serializeString32(sv.second);
if (version >= 2)

View File

@ -1542,9 +1542,8 @@ void Server::SendShowFormspecMessage(session_t peer_id, const std::string &forms
} else {
m_formspec_state_data[peer_id] = formname;
RemotePlayer *player = m_env->getPlayer(peer_id);
if (player && player->protocol_version < 37 &&
formspec.find("no_prepend[]") == std::string::npos)
pkt.putLongString(formspec + player->formspec_prepend);
if (player && player->protocol_version < 37)
pkt.putLongString(insert_formspec_prepend(formspec, player->formspec_prepend));
else
pkt.putLongString(formspec);
}
@ -1935,10 +1934,9 @@ void Server::SendPlayerInventoryFormspec(session_t peer_id)
return;
NetworkPacket pkt(TOCLIENT_INVENTORY_FORMSPEC, 0, peer_id);
if (player->protocol_version < 37 && player->inventory_formspec.find(
"no_prepend[]") == std::string::npos)
pkt.putLongString(player->inventory_formspec +
player->formspec_prepend);
if (player->protocol_version < 37)
pkt.putLongString(insert_formspec_prepend(player->inventory_formspec,
player->formspec_prepend));
else
pkt.putLongString(player->inventory_formspec);

View File

@ -894,3 +894,36 @@ std::string sanitizeDirName(const std::string &str, const std::string &optional_
return wide_to_utf8(safe_name);
}
std::string insert_formspec_prepend(const std::string &formspec, const std::string &prepend) {
size_t pos = 0;
size_t pos2;
while ((pos2 = formspec.find('[', pos)) != std::string::npos) {
const std::string element_type = trim(formspec.substr(pos, pos2 - pos));
// If a no_prepend[] is found then don't insert the prepend
if (element_type == "no_prepend")
return formspec;
// Insert the prepend before this element if it isn't size, position,
// or anchor.
if (element_type != "size" && element_type != "position" &&
element_type != "anchor") {
break;
}
// Search for the closing ] and continue iterating
// Valid size, position, and anchor elements only have numbers so
// escaping doesn't have to be accounted for here.
pos = formspec.find(']', pos2);
if (pos == std::string::npos)
return formspec;
pos++;
}
// Make a copy of the const string and insert the formspec prepend in the
// correct location.
std::string prepended_fs = formspec;
prepended_fs.insert(pos, prepend);
return prepended_fs;
}

View File

@ -728,3 +728,11 @@ inline irr::core::stringw utf8_to_stringw(const std::string &input)
* 2. Remove 'unsafe' characters from the name by replacing them with '_'
*/
std::string sanitizeDirName(const std::string &str, const std::string &optional_prefix);
/**
* @param formspec The version 1 formspec string
* @param prepend The formspec prepend
* @return A copy of \p formspec with \p prepend added if possible.
*/
std::string insert_formspec_prepend(const std::string &formspec, const std::string &prepend);