main.cpp 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. #include <chrono>
  2. #include <iostream>
  3. #include <string>
  4. #include <thread> // sleep_for
  5. #include "door.h"
  6. #include "input.h"
  7. #include "irc.h"
  8. #include "render.h"
  9. #include "yaml-cpp/yaml.h"
  10. #include <boost/asio.hpp>
  11. // #include <boost/thread.hpp>
  12. YAML::Node config;
  13. std::function<std::ofstream &(void)> get_logger;
  14. bool file_exists(const std::string name) {
  15. std::ifstream f(name.c_str());
  16. return f.good();
  17. }
  18. int main(int argc, char *argv[]) {
  19. using namespace std::chrono_literals;
  20. boost::asio::io_context io_context;
  21. ircClient irc(io_context);
  22. door::Door door("irc-door", argc, argv);
  23. get_logger = [&door]() -> ofstream & { return door.log(); };
  24. if (file_exists("irc-door.yaml")) {
  25. config = YAML::LoadFile("irc-door.yaml");
  26. }
  27. bool update_config = false;
  28. if (!config["hostname"]) {
  29. config["hostname"] = "127.0.0.1";
  30. update_config = true;
  31. }
  32. if (!config["port"]) {
  33. config["port"] = "6697";
  34. update_config = true;
  35. }
  36. if (!config["allow_join"]) {
  37. config["allow_join"] = "0";
  38. update_config = true;
  39. }
  40. if (!config["autojoin"]) {
  41. config["autojoin"] = "#bugz";
  42. update_config = true;
  43. }
  44. if (!config["realname"]) {
  45. config["realname"] = "A poor soul on BZBZ BBS...";
  46. update_config = true;
  47. }
  48. if (!config["username"]) {
  49. config["username"] = "bzbz";
  50. update_config = true;
  51. }
  52. if (!config["input_delay"]) {
  53. config["input_delay"] = "500";
  54. update_config = true;
  55. }
  56. if (!config["timestamp_format"]) {
  57. config["timestamp_format"] = "%T";
  58. update_config = true;
  59. }
  60. if (update_config) {
  61. std::ofstream fout("irc-door.yaml");
  62. fout << "# IRC Chat Door configuration" << std::endl;
  63. fout << "# to add comments (that don't get destroyed)" << std::endl;
  64. fout << "# Add comments as key: values, like:" << std::endl;
  65. fout << "# _comment: This will survive the test of time." << std::endl;
  66. fout << "# %r AM/PM, %T 24 hour time" << std::endl;
  67. fout << std::endl;
  68. fout << config << std::endl;
  69. fout << "# end yaml config" << std::endl;
  70. }
  71. // configure
  72. irc.nick = door.handle;
  73. irc.realname = config["realname"].as<std::string>();
  74. irc.hostname = config["hostname"].as<std::string>();
  75. irc.port = config["port"].as<std::string>();
  76. if (config["server_password"]) {
  77. irc.server_password = config["server_password"].as<std::string>();
  78. }
  79. if (config["sasl_password"]) {
  80. irc.sasl_plain_password = config["sasl_password"].as<std::string>();
  81. }
  82. irc.username = config["username"].as<std::string>();
  83. irc.autojoin = config["autojoin"].as<std::string>();
  84. irc.version = "Bugz IRC Door 0.1 (C) 2021 Red-Green Software";
  85. // set the delay between irc updates
  86. ms_input_delay = config["input_delay"].as<int>();
  87. timestamp_format = config["timestamp_format"].as<std::string>();
  88. if (config["log"]) {
  89. irc.debug_output = config["log"].as<std::string>();
  90. door << "irc debug logfile = " << config["log"].as<std::string>()
  91. << door::nl;
  92. }
  93. if (config["allow_join"].as<int>() == 1) {
  94. allow_part = true;
  95. allow_join = true;
  96. }
  97. irc.begin(); // start the initial request so io_context has work to do
  98. // boost::thread thread(boost::bind(&boost::asio::io_service::run,
  99. // &io_context));
  100. // thread Thread(boost::bind(&boost::asio::io_service::run, &io_context));
  101. thread Thread([&io_context]() -> void { io_context.run(); });
  102. door << "Welcome to the IRC chat door." << door::nl;
  103. bool in_door = true;
  104. while (in_door) {
  105. // the main loop
  106. // custom input routine goes here
  107. check_for_input(door, irc);
  108. boost::optional<message_stamp> msg;
  109. bool input_cleared = false;
  110. if (irc.channels_updated)
  111. do {
  112. msg = irc.message_pop();
  113. if (msg) {
  114. if (!input_cleared) {
  115. input_cleared = true;
  116. clear_input(door);
  117. }
  118. render(*msg, door, irc);
  119. }
  120. } while (msg);
  121. if (input_cleared)
  122. restore_input(door);
  123. // sleep is done in the check_for_input
  124. // std::this_thread::sleep_for(200ms);
  125. if (irc.shutdown)
  126. in_door = false;
  127. }
  128. // Store error messages into door log!
  129. while (!irc.errors.empty()) {
  130. door.log() << "ERROR: " << irc.errors.front() << std::endl;
  131. irc.errors.erase(irc.errors.begin());
  132. }
  133. io_context.stop();
  134. Thread.join();
  135. // disable the global logging std::function
  136. get_logger = nullptr;
  137. door << "Returning to the BBS..." << door::nl;
  138. return 0;
  139. }