tcpsyncclient.cpp 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. #include "tcpsyncclient.h"
  2. void TcpSyncClient::log(std::string message)
  3. {
  4. std::cout << "[TSC] " << message;
  5. if (message[message.size() - 1] != '\n') std::cout << std::endl;
  6. }
  7. TcpSyncClient::TcpSyncClient(boost::asio::io_service& service, std::string config) :
  8. to_read(false),
  9. to_raw(false),
  10. to_start(false),
  11. m_sock(service),
  12. m_config_file(config)
  13. {
  14. to_start = read_config();
  15. if(to_start)
  16. {
  17. if (params["channel"][0] != '#') params["channel"] = "#" + params["channel"];
  18. try {
  19. boost::asio::ip::tcp::endpoint e(
  20. boost::asio::ip::address::from_string(
  21. params["address"]), std::stoi(params["port"]) );
  22. m_ep = e;
  23. } catch (boost::system::system_error & err) {
  24. std::cerr << err.what() << ": " << params["address"] << " / "
  25. << params["port"] << std::endl;
  26. }
  27. log (m_ep.address().to_string());
  28. log (std::to_string (m_ep.port()));
  29. log (params["channel"]);
  30. }
  31. }
  32. bool TcpSyncClient::write(std::string msg)
  33. {
  34. try {
  35. m_sock.write_some(boost::asio::buffer(msg + '\n'));
  36. } catch (boost::system::system_error & err) {
  37. log("Write("+msg+") error");
  38. std::cerr << err.what() <<std::endl;
  39. return false;
  40. }
  41. return true;
  42. }
  43. bool TcpSyncClient::write_to_channel(std::string msg)
  44. {
  45. return write("PRIVMSG " + params["channel"] + " " + msg);
  46. }
  47. bool TcpSyncClient::write_to_user(std::string user, std::string msg)
  48. {
  49. return write("PRIVMSG " + user + " " + msg);
  50. }
  51. std::string TcpSyncClient::get_msg()
  52. {
  53. if (!to_read) return "to_read is false";
  54. to_read = false;
  55. return m_msg;
  56. }
  57. std::string TcpSyncClient::get_msg_nick()
  58. {
  59. return m_msg_nickname;
  60. }
  61. std::string TcpSyncClient::get_raw()
  62. {
  63. if (!to_raw) return "to_raw is false";
  64. to_raw = false;
  65. return m_raw;
  66. }
  67. std::string TcpSyncClient::get_raw_nick()
  68. {
  69. return m_raw_nickname;
  70. }
  71. bool TcpSyncClient::have_pm_from_user(std::string nick)
  72. {
  73. return (raw_msg_from_socket.find(":" + nick + "!") == 0 &&
  74. raw_msg_from_socket.find("PRIVMSG " + params["nickname"]) != std::string::npos);
  75. }
  76. bool TcpSyncClient::connect_to_ep()
  77. {
  78. try {
  79. m_sock.connect(m_ep);
  80. } catch (boost::system::system_error & err) {
  81. std::cerr << err.what() <<std::endl;
  82. return false;
  83. }
  84. return true;
  85. }
  86. size_t TcpSyncClient::read_complete(const error_code& err, size_t bytes) {
  87. if ( err) return 0;
  88. m_already_read = bytes;
  89. bool found = std::find(m_buff, m_buff + bytes, '\n') < m_buff + bytes;
  90. return found ? 0 : 1;
  91. }
  92. void TcpSyncClient::read_answer()
  93. {
  94. m_already_read = 0;
  95. read(m_sock, boost::asio::buffer(m_buff, 1024),
  96. boost::bind(&TcpSyncClient::read_complete, this, _1, _2));
  97. process_msg();
  98. }
  99. void TcpSyncClient::answer_to_ping(std::string ping)
  100. {
  101. write("PONG :" + ping);
  102. log("[PONG] " + ping);
  103. }
  104. void TcpSyncClient::connect_to_server()
  105. {
  106. write("USER " + m_user + " . . :" + m_realname);
  107. write("NICK " + params["nickname"]);
  108. read_answer();
  109. if(params["password"] != "x") {
  110. write("PRIVMSG NICKSERV IDENTIFY " + params["password"]);
  111. }
  112. write("JOIN " + params["channel"]);
  113. read_answer();
  114. write("MODE " + params["nickname"] + " +B"); // флаг бота
  115. }
  116. void TcpSyncClient::start()
  117. {
  118. if ( connect_to_ep()) {
  119. connect_to_server();
  120. log("[CONNECTED TO SERVER]");
  121. while (true) read_answer();
  122. }
  123. else {
  124. log("[START FAILED]");
  125. }
  126. }
  127. bool TcpSyncClient::read_config()
  128. {
  129. if (!boost::filesystem::exists(m_config_file)) {
  130. std::cerr << "Config not found" << std::endl;
  131. return false;
  132. }
  133. boost::property_tree::ptree pt;
  134. boost::property_tree::read_json(m_config_file, pt);
  135. for (auto child: pt.get_child("socket"))
  136. {
  137. for (size_t i = 0; i < params.size(); ++i)
  138. {
  139. if (params[child.first] != "")
  140. {
  141. params[child.first] = child.second.get_value<std::string>();
  142. }
  143. }
  144. }
  145. return true;
  146. }
  147. void TcpSyncClient::process_msg()
  148. {
  149. std::string msg(m_buff, m_already_read);
  150. log("[MSG] " + msg);
  151. if (msg.find("PING :") == 0) answer_to_ping(msg.substr(6));
  152. raw_msg_from_socket = msg;
  153. // Парсинг сообщений, адресованных боту. Сохраняет ник отправителя и текст.
  154. if (msg.find("PRIVMSG " + params["channel"] + " :" + params["nickname"]) != std::string::npos)
  155. {
  156. m_msg = msg.substr(msg.find(" :" + params["nickname"]) + 3 + params["nickname"].size() );
  157. while (m_msg[0] == ' ') m_msg = m_msg.substr(1);
  158. while (m_msg.back() == '\n'|| m_msg.back() == '\r' || m_msg.back() == ' ') m_msg.pop_back();
  159. m_msg_nickname = msg.substr(1, msg.find('!') - 1);
  160. to_read = true;
  161. }
  162. // Парсинг всех сообщений на канале. Сохраняет ник отправителя и текст.
  163. else if (msg.find("PRIVMSG " + params["channel"] + " :") != std::string::npos)
  164. {
  165. m_raw = msg.substr(msg.find(params["channel"] + " :") + 2 + params["channel"].size());
  166. m_raw_nickname = msg.substr(1, msg.find('!') - 1);
  167. while (m_raw[0] == ' ') m_raw = m_raw.substr(1);
  168. while (m_raw.back() == '\n'|| m_raw.back() == '\r' || m_raw.back() == ' ') m_raw.pop_back();
  169. if (m_raw.find("ACTION") == 0) {
  170. m_raw = "-" + m_raw.substr(7);
  171. while (m_raw.find('') != std::string::npos) m_raw.pop_back();
  172. m_raw += " -";
  173. }
  174. to_raw = true;
  175. if (m_raw[0] == '.') {
  176. if (m_raw[1] == '.') to_raw = false; // Максимальная анонимность, нет лога
  177. m_raw = "**blinded message**";
  178. }
  179. }
  180. }
  181. TcpSyncClient::~TcpSyncClient()
  182. {
  183. std::cout << "TcpSyncClient destructed" << std::endl;
  184. }