From 6ca3fae702bd995d2f415a7ebfbd5b9dc2b851fa Mon Sep 17 00:00:00 2001 From: Nils Date: Sat, 19 Jun 2021 15:08:19 +0200 Subject: [PATCH] Fully implemented modes synchronisation --- instance.cpp | 26 ++++++++++++++++++++++---- instance.hpp | 7 ++++++- 2 files changed, 28 insertions(+), 5 deletions(-) diff --git a/instance.cpp b/instance.cpp index dc53dc9..6f62239 100644 --- a/instance.cpp +++ b/instance.cpp @@ -90,7 +90,7 @@ void ModeSet::parse(std::string_view in, NetworkInfo &netInfo) { op = REMOVING; } else { if (op == ADDING) { - if (str.find(character) == str.npos) { + if (str.find(character) == str.npos || netInfo.channelModes.isListMode(character)) { str.push_back(character); if constexpr(channelModes) { if (netInfo.channelModes.takesParamOnSet(character)) { @@ -106,7 +106,7 @@ void ModeSet::parse(std::string_view in, NetworkInfo &netInfo) { } else if (op == REMOVING) { auto res = str.find(character); if (res != str.npos) { - str.erase(res); + str.erase(res, 1); if constexpr(channelModes) { if (netInfo.channelModes.takesParamOnUnset(character)) { if (paramIt == split.end()) { @@ -170,9 +170,13 @@ void Channel::parse_sjoin(const Event& event, Cache& cache, NetworkInfo& netInfo mode.parse(split[2], netInfo); // Get members for (auto& raw_uuid : strSplit(event.text, ' ')) { - // Erase leading sign + // Erase prefix if (raw_uuid.size() > UUID_len) { + char prefixChar = raw_uuid[0]; raw_uuid = {raw_uuid.data()+1, raw_uuid.size()-1}; + char modeChar = netInfo.channelModes.prefixMap[prefixChar]; + mode.str.push_back(modeChar); + mode.params.push_back({modeChar, std::string(raw_uuid)}); } // Find user in cache auto res = cache.find_user_by_uid(UUID(raw_uuid)); @@ -336,9 +340,11 @@ async::result Instance::process(const Event event) { } // Check if we've got the right key if (split[0] == "NETWORK") { + // Network name netInfo.name = std::move(split[1]); netInfo.fields_received++; } else if (split[0] == "CHANMODES") { + // Channel modes auto modeLists = strSplit(split[1], ',', 3); netInfo.channelModes = { .listModes = std::string(modeLists[0]), @@ -347,10 +353,22 @@ async::result Instance::process(const Event event) { .paramLessModes = std::string(modeLists[3]) }; netInfo.fields_received++; + } else if (split[0] == "PREFIX") { + auto val = split[1]; + // User prefixes + auto modesIt = val.find("(") + 1; + auto prefixesIt = val.find(")") + 1; + while (val[modesIt] != ')') { + netInfo.channelModes.prefixMap[val[prefixesIt]] = val[modesIt]; + netInfo.channelModes.listModes.push_back(val[modesIt]); + modesIt++; + prefixesIt++; + } + netInfo.fields_received++; } } // Check if everything needed has been fetched - if (netInfo.fields_received == 2 && !netInfo.ready) { + if (netInfo.fields_received == 3 && !netInfo.ready) { netInfo.mark_ready(); } } else { diff --git a/instance.hpp b/instance.hpp index a4e3921..9c97418 100644 --- a/instance.hpp +++ b/instance.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -120,12 +121,16 @@ struct NetworkInfo { paramOnSetAndUnsetModes, // Properties like k paramOnSetOnlyModes, // Properties like f paramLessModes; // Properties like z + std::unordered_map prefixMap; // Maps for example '@' to 'o' + bool isListMode(char mode) { + return listModes.find(mode) != std::string::npos; + } bool takesNoParam(char mode) { return paramLessModes.find(mode) != paramLessModes.npos; } bool takesParamOnUnset(char mode) { - return listModes.find(mode) != std::string::npos || + return isListMode(mode) || paramOnSetAndUnsetModes.find(mode) != std::string::npos; } bool takesParamOnSet(char mode) {