zicaentu

SkillChat

Feb 26th, 2021
1,312
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.52 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <algorithm>
  4. #include <regex>
  5. #include <map>
  6. #include <uwebsockets/App.h>
  7.  
  8.  
  9. /*
  10. * Протокол
  11. * MESSAGE_TO::1025::Привет, мир!
  12. *
  13. * MESSAGE_FROM::1026::Какой то текст
  14. *
  15. * SET_NAME::Мой ник
  16. *
  17. * MESSAGE_ALL::Привет всем
  18. */
  19.  
  20. const std::string MESSAGE_TO = "MESSAGE_TO::";
  21. const std::string SET_NAME = "SET_NAME::";
  22. const uint32_t START_USER_ID = 1024;
  23.  
  24. std::string parseUserId(std::string message) {
  25.     std::string rest = message.substr(MESSAGE_TO.size());
  26.     int pos = rest.find("::");
  27.     return rest.substr(0, pos);
  28. }
  29.  
  30. std::string parseUserText(std::string message) {
  31.     std::string rest = message.substr(MESSAGE_TO.size());
  32.     int pos = rest.find("::");
  33.     return rest.substr(pos + 2);
  34. }
  35.  
  36. std::string parseName(std::string message) {
  37.     return message.substr(SET_NAME.size());;
  38. }
  39.  
  40. bool isValidName(std::string message) {
  41.     return message.find("::") == std::string::npos and message.size() <= 255;
  42. }
  43.  
  44. bool isMessageTo(std::string message) {
  45.     return message.find(MESSAGE_TO) == 0;
  46. }
  47.  
  48. bool isSetName(std::string message) {
  49.     return message.find(SET_NAME) == 0;
  50. }
  51.  
  52. std::string messageFrom(std::string user_id, std::string senderName, std::string message) {
  53.     return "MESSAGE_FROM::" + user_id + "::[" + senderName + "] " + message;
  54. }
  55.  
  56. std::string to_lower(std::string txt) {
  57.     transform(txt.begin(), txt.end(), txt.begin(), ::tolower);
  58.     return txt;
  59. }
  60.  
  61.  
  62.  
  63. int main() {
  64.     std::map<std::string, std::string> database = {
  65.         {"hello", "oh hi how are you?"},
  66.  
  67.         {"how are you", "Im doing just fine, LOL"},
  68.         {"what are you doing", "I'm answering stupid question"},
  69.         {"where are you from", "I'm from within your mind"},
  70.         {"how old are you", "I'm only 10 nanoseconds old"},
  71.         {"what are you", "I'm your friendly ChatBot2021"},
  72.  
  73.         {"exit", "Ok byyyyeeee"},
  74.     };
  75.  
  76.    
  77.  
  78.     struct PerSocketData {
  79.         std::string name;
  80.         uint32_t user_id;
  81.     };
  82.  
  83.     uint32_t last_user_id = START_USER_ID;
  84.  
  85.     uWS::App().
  86.         ws<PerSocketData>("/*", {
  87.             .idleTimeout = 1200,
  88.             .open = [&last_user_id](auto* ws) {
  89.                 PerSocketData* userData = (PerSocketData*)ws->getUserData();
  90.                 userData->name = "UNNAMED";
  91.                 userData->user_id = last_user_id++;
  92.                 std::cout << "New user connected, id = " << userData->user_id << std::endl;
  93.  
  94.                 ws->subscribe("user#" + std::to_string(userData->user_id));
  95.                 ws->subscribe("broadcast");
  96.  
  97.                 std::cout << "Total users connected: " << last_user_id - START_USER_ID << std::endl;
  98.             },
  99.             .message = [&last_user_id, database](auto* ws, std::string_view message, uWS::OpCode opCode) {
  100.                 std::string strMessage = std::string(message);
  101.                 PerSocketData* userData = (PerSocketData*)ws->getUserData();
  102.                 std::string senderId = std::to_string(userData->user_id);
  103.  
  104.                 if (isMessageTo(strMessage)) {
  105.                     std::string reseiverId = parseUserId(strMessage);
  106.                     std::string text = parseUserText(strMessage);
  107.                     std::string outgoingMessage = messageFrom(senderId, userData->name, text);
  108.                     uint32_t reseiver = std::stoi(reseiverId);
  109.                    
  110.                     if (reseiver == 1) {
  111.                         std::string question = to_lower(text);
  112.                         for (auto entry : database) {
  113.                             std::regex pattern = std::regex(".*" + entry.first + ".*");
  114.                             if (regex_match(question, pattern)) {
  115.                                 ws->publish("user#" + senderId, entry.second);
  116.                             }
  117.                         }
  118.                     }
  119.                     else {
  120.                         if (std::stoi(reseiverId) < last_user_id and std::stoi(reseiverId) >= START_USER_ID) {
  121.                             ws->publish("user#" + reseiverId, outgoingMessage);
  122.                             std::cout << "Author #" << senderId << " wrote message to " << reseiverId << std::endl;
  123.                         }
  124.                         else {
  125.                             std::string noUserMessage = "Error, there is no user with ID = " + reseiverId;
  126.                             ws->publish("user#" + senderId, noUserMessage);
  127.                             std::cout << noUserMessage << std::endl;
  128.                         }
  129.                     }
  130.  
  131.                    
  132.                 }
  133.                
  134.                 if (isSetName(strMessage)) {
  135.                     std::string newName = parseName(strMessage);
  136.                     if (isValidName(newName)) {
  137.                         userData->name = newName;
  138.                         std::cout << "User #" << senderId << " set name " << newName << std::endl;
  139.                     }
  140.                 }
  141.             },
  142.             .close = [&last_user_id](auto*/*ws*/, int /*code*/, std::string_view /*message*/) {
  143.                 last_user_id--;
  144.                 std::cout << "Total users connected: " << last_user_id - START_USER_ID << std::endl;
  145.             }
  146.         })
  147.         .listen(9001, [last_user_id](auto* listen_socket) {
  148.             if (listen_socket) {
  149.                 std::cout << "Listening on port " << 9001 << std::endl;
  150.                 std::cout << "Total users connected: " << last_user_id - START_USER_ID << std::endl;
  151.             }
  152.         })
  153.         .run();
  154. }
Advertisement
Add Comment
Please, Sign In to add comment