auto-reconnect and don't drop messages
This commit is contained in:
parent
586889f543
commit
173182f8e7
99
src/main.cc
99
src/main.cc
|
@ -6,11 +6,13 @@
|
|||
#include <boost/asio/io_context.hpp>
|
||||
#include <boost/asio/ip/tcp.hpp>
|
||||
#include <boost/asio/read_until.hpp>
|
||||
#include <boost/asio/steady_timer.hpp>
|
||||
#include <boost/asio/streambuf.hpp>
|
||||
#include <boost/asio/use_awaitable.hpp>
|
||||
#include <boost/asio/write.hpp>
|
||||
#include <iostream>
|
||||
#include <random>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <utility>
|
||||
|
@ -40,6 +42,7 @@ std::string_view DirectionToString(Direction direction) {
|
|||
|
||||
class Bot {
|
||||
asio::any_io_executor executor;
|
||||
asio::steady_timer timer;
|
||||
asio::ip::tcp::socket socket;
|
||||
std::string name;
|
||||
std::string pass;
|
||||
|
@ -62,6 +65,7 @@ class Bot {
|
|||
Bot::Bot(asio::any_io_executor executor, std::string_view name,
|
||||
std::string_view pass)
|
||||
: executor{executor},
|
||||
timer{executor},
|
||||
socket{executor},
|
||||
name{name},
|
||||
pass{pass},
|
||||
|
@ -72,49 +76,66 @@ Bot::Bot(asio::any_io_executor executor, std::string_view name,
|
|||
asio::awaitable<void> Bot::Protocol() {
|
||||
asio::ip::tcp::resolver resolver{executor};
|
||||
asio::ip::tcp::resolver::query query{"94.45.241.27", "4000"};
|
||||
|
||||
co_await asio::async_connect(
|
||||
socket, co_await resolver.async_resolve(query, asio::use_awaitable),
|
||||
asio::use_awaitable);
|
||||
auto host = co_await resolver.async_resolve(query, asio::use_awaitable);
|
||||
|
||||
while (true) {
|
||||
asio::streambuf buf;
|
||||
buf.commit(co_await asio::async_read_until(socket, buf, '\n',
|
||||
asio::use_awaitable));
|
||||
std::istream is{&buf};
|
||||
std::string field;
|
||||
char dummy;
|
||||
std::getline(is, field, '|');
|
||||
if (field == "motd") {
|
||||
std::getline(is, field);
|
||||
std::cout << "-> MotD: " << field << std::endl;
|
||||
co_await Join();
|
||||
} else if (field == "error") {
|
||||
std::getline(is, field);
|
||||
std::cout << "-> Error: " << field << std::endl;
|
||||
co_return;
|
||||
} else if (field == "goal") {
|
||||
is >> goal_x >> dummy >> goal_y;
|
||||
std::cout << "-> Goal is at (" << goal_x << ", " << goal_y << ")"
|
||||
<< std::endl;
|
||||
} else if (field == "pos") {
|
||||
is >> x >> dummy >> y >> dummy >> up >> dummy >> right >> dummy >> down >>
|
||||
dummy >> left;
|
||||
std::cout << "-> Position at (" << x << ", " << y << ")" << std::endl;
|
||||
while (true) {
|
||||
try {
|
||||
co_await asio::async_connect(socket, host, asio::use_awaitable);
|
||||
break;
|
||||
} catch (std::exception &e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
timer.expires_after(std::chrono::seconds(1));
|
||||
co_await timer.async_wait(asio::use_awaitable);
|
||||
}
|
||||
|
||||
try {
|
||||
while (true) {
|
||||
asio::streambuf buf;
|
||||
co_await asio::async_read_until(socket, buf, '\n', asio::use_awaitable);
|
||||
std::istream is{&buf};
|
||||
std::string line;
|
||||
while (std::getline(is, line)) {
|
||||
std::istringstream iss{line};
|
||||
std::string field;
|
||||
char dummy;
|
||||
std::getline(iss, field, '|');
|
||||
if (field == "motd") {
|
||||
std::getline(iss, field);
|
||||
std::cout << "-> MotD: " << field << std::endl;
|
||||
co_await Join();
|
||||
} else if (field == "error") {
|
||||
std::getline(iss, field);
|
||||
std::cout << "-> Error: " << field << std::endl;
|
||||
} else if (field == "goal") {
|
||||
iss >> goal_x >> dummy >> goal_y;
|
||||
std::cout << "-> Goal is at (" << goal_x << ", " << goal_y << ")"
|
||||
<< std::endl;
|
||||
} else if (field == "pos") {
|
||||
iss >> x >> dummy >> y >> dummy >> up >> dummy >> right >> dummy >>
|
||||
down >> dummy >> left;
|
||||
std::cout << "-> Position at (" << x << ", " << y << ")"
|
||||
<< std::endl;
|
||||
#define X(b) (b ? #b ", " : "")
|
||||
std::cout << " Walls are " << X(up) << X(right) << X(down) << X(left)
|
||||
<< std::endl;
|
||||
std::cout << " Walls are (" << X(up) << X(right) << X(down)
|
||||
<< X(left) << ")" << std::endl;
|
||||
#undef X
|
||||
co_await ChooseMove();
|
||||
} else if (field == "win" || field == "lose") {
|
||||
int win, lose;
|
||||
is >> win >> dummy >> lose;
|
||||
std::cout << "-> You " << field << '!' << std::endl;
|
||||
std::cout << " Score: " << win << '/' << lose << std::endl;
|
||||
} else {
|
||||
std::cout << "unhandled message: " << field << '|';
|
||||
std::getline(is, field);
|
||||
std::cout << field << std::endl;
|
||||
co_await ChooseMove();
|
||||
} else if (field == "win" || field == "lose") {
|
||||
int win, lose;
|
||||
iss >> win >> dummy >> lose;
|
||||
std::cout << "-> You " << field << '!' << std::endl;
|
||||
std::cout << " Score: " << win << '/' << lose << std::endl;
|
||||
} else {
|
||||
std::cout << "unhandled message: " << field << '|';
|
||||
std::getline(iss, field);
|
||||
std::cout << field << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (std::exception &e) {
|
||||
std::cout << e.what() << std::endl;
|
||||
}
|
||||
}
|
||||
co_return;
|
||||
|
|
Loading…
Reference in a new issue