From f942405184c2d6067fb5303b58a225edf7e452b1 Mon Sep 17 00:00:00 2001 From: LaG1924 <12997935+LaG1924@users.noreply.github.com> Date: Sat, 29 Jul 2017 19:55:16 +0500 Subject: 2017-07-29 --- src/NetworkClient.cpp | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/NetworkClient.cpp (limited to 'src/NetworkClient.cpp') diff --git a/src/NetworkClient.cpp b/src/NetworkClient.cpp new file mode 100644 index 0000000..0b759e6 --- /dev/null +++ b/src/NetworkClient.cpp @@ -0,0 +1,93 @@ +#include "NetworkClient.hpp" + +NetworkClient::NetworkClient(std::string address, unsigned short port, std::string username, bool &quit) + : network(address, port), isRunning(quit) { + state = Handshaking; + + PacketHandshake handshake; + handshake.protocolVersion = 335; + handshake.serverAddress = "127.0.0.1"; + handshake.serverPort = 25565; + handshake.nextState = 2; + network.SendPacket(handshake); + state = Login; + + PacketLoginStart loginStart; + loginStart.Username = "HelloOne"; + network.SendPacket(loginStart); + + auto response = std::static_pointer_cast(network.ReceivePacket(Login)); + if (response->Username != username) { + throw std::logic_error("Received username is not sended username"); + } + + state = Play; + + isActive = true; + std::thread thread(&NetworkClient::NetworkLoop, this); + std::swap(networkThread, thread); +} + +NetworkClient::~NetworkClient() { + isActive = false; + networkThread.join(); +} + +std::shared_ptr NetworkClient::ReceivePacket() { + if (toReceive.empty()) + return std::shared_ptr(nullptr); + toReceiveMutex.lock(); + auto ret = toReceive.front(); + toReceive.pop(); + toReceiveMutex.unlock(); + return ret; +} + +void NetworkClient::SendPacket(std::shared_ptr packet) { + toSendMutex.lock(); + toSend.push(packet); + toSendMutex.unlock(); +} + +void NetworkClient::NetworkLoop() { + auto timeOfLastKeepAlivePacket = std::chrono::steady_clock::now(); + el::Helpers::setThreadName("Network"); + LOG(INFO) << "Network thread is started"; + try { + while (isActive) { + toSendMutex.lock(); + while (!toSend.empty()) { + if (toSend.front()!=nullptr) + network.SendPacket(*toSend.front()); + toSend.pop(); + } + toSendMutex.unlock(); + auto packet = network.ReceivePacket(state); + if (packet.get() != nullptr) { + if (packet->GetPacketId() != PacketNamePlayCB::KeepAliveCB) { + toReceiveMutex.lock(); + toReceive.push(packet); + toReceiveMutex.unlock(); + } else { + timeOfLastKeepAlivePacket = std::chrono::steady_clock::now(); + auto packetKeepAlive = std::static_pointer_cast(packet); + auto packetKeepAliveSB = std::make_shared(packetKeepAlive->KeepAliveId); + network.SendPacket(*packetKeepAliveSB); + } + } + using namespace std::chrono_literals; + if (std::chrono::steady_clock::now() - timeOfLastKeepAlivePacket > 20s) { + auto disconnectPacket = std::make_shared(); + disconnectPacket->Reason = "Timeout"; + toReceiveMutex.lock(); + toReceive.push(disconnectPacket); + toReceiveMutex.unlock(); + break; + } + } + } catch (std::exception &e) { + LOG(ERROR) << "Exception catched in NetworkLoop: " << e.what(); + isRunning = false; + } + LOG(INFO) << "Network thread is stopped"; +} -- cgit v1.2.3