diff -r 060a13878ca0 -r be953e1621d9 sources/network/rconsession.cpp --- a/sources/network/rconsession.cpp Wed Jan 27 12:41:50 2021 +0200 +++ b/sources/network/rconsession.cpp Wed Jan 27 19:48:41 2021 +0200 @@ -1,5 +1,5 @@ /* - Copyright 2014 - 2016 Teemu Piippo + Copyright 2014 - 2021 Teemu Piippo All rights reserved. Redistribution and use in source and binary forms, with or without @@ -31,6 +31,7 @@ #include #include "rconsession.h" #include "../interface.h" +#include "../md5.h" BEGIN_ZFC_NAMESPACE // ------------------------------------------------------------------------------------------------- @@ -41,10 +42,10 @@ m_adminCount(0), m_interface(nullptr) { - if (not m_socket.set_blocking(false)) + std::stringstream errors; + if (not m_socket.set_blocking(false, errors)) { - fprintf(stderr, "unable to set socket as non-blocking: %s\n", - m_socket.error_string().chars()); + fprintf(stderr, "unable to set socket as non-blocking: %s\n", errors.str().data()); exit(EXIT_FAILURE); } } @@ -55,7 +56,7 @@ // ------------------------------------------------------------------------------------------------- // -void RCONSession::connect(IPAddress address) +void RCONSession::connect(net::ip_address address) { m_address = address; m_state = RCON_CONNECTING; @@ -79,9 +80,15 @@ // ------------------------------------------------------------------------------------------------- // -void RCONSession::send(const ByteArray& packet) +bool RCONSession::send(const std::vector& packet) { - m_socket.send(m_address, packet); + std::stringstream errors; + const bool result = m_socket.send(m_address, packet, errors); + if (not result) + { + this->m_interface->printError("Network error: %s\n", errors.str().data()); + } + return result; } // ------------------------------------------------------------------------------------------------- @@ -112,8 +119,14 @@ } // Check for new packets in our socket - for (Datagram datagram; m_socket.read(datagram);) + std::stringstream errors; + for (net::Datagram datagram; m_socket.read(datagram, errors);) { + if (errors.tellp() > 0) + { + m_interface->printError("Network error: %s\n", errors.str().data()); + errors = {}; + } // Only process packets that originate from the game server. if (datagram.address == m_address) handlePacket(datagram.message); @@ -122,7 +135,7 @@ // ------------------------------------------------------------------------------------------------- // -void RCONSession::handlePacket(ByteArray& message) +void RCONSession::handlePacket(std::vector& message) { Bytestream stream(message); @@ -157,9 +170,9 @@ case SVRC_MESSAGE: { - String message = stream.readString(); - message.normalize(); - m_interface->printText("%s\n", message.chars()); + std::string message = stream.readString(); + normalize(message); + m_interface->printText("%s\n", message.data()); } break; @@ -177,9 +190,9 @@ for (int i = stream.readByte(); i > 0; --i) { - String message = stream.readString(); - message.normalize(); - m_interface->printText("--- %s\n", message.chars()); + std::string message = stream.readString(); + normalize(message); + m_interface->printText("--- %s\n", message.data()); } m_interface->print("End of previous messages.\n"); @@ -197,55 +210,55 @@ { unsigned int numCompletions = stream.readShort(); m_interface->print("%d completions for '%s'.\n", - int(numCompletions), m_lastTabComplete.chars()); + int(numCompletions), m_lastTabComplete.data()); } break; case SVRC_TABCOMPLETE: { - StringList completes; + std::vector completes; completes.resize(stream.readByte()); - for (String& completion : completes) + for (std::string& completion : completes) completion = stream.readString(); if (completes.size() == 1) { m_interface->tabComplete(m_lastTabComplete, completes[0]); } - else if (not completes.is_empty()) + else if (completes.size() > 0) { - m_interface->print("Completions for '%s':\n", m_lastTabComplete.chars()); + m_interface->print("Completions for '%s':\n", m_lastTabComplete.data()); - for (int i : range(0, completes.size(), 8)) + for (std::size_t i = 0; i < completes.size(); i += 8) { - Range spliceRange(i, min(i + 8, completes.size())); - StringList splice(completes.splice(spliceRange)); - m_interface->print("- %s\n", splice.join(", ").chars()); + const int end = min(i + 8, completes.size()); + std::vector splices = splice(completes, i, end); + m_interface->print("- %s\n", join_string_list(splices, ", ").data()); } } } break; case SVRC_WATCHINGCVAR: - m_interface->print ("You are now watching %s\n", stream.readString().chars()); - m_interface->print ("Its value is: %s\n", stream.readString().chars()); + m_interface->print ("You are now watching %s\n", stream.readString().data()); + m_interface->print ("Its value is: %s\n", stream.readString().data()); break; case SVRC_ALREADYWATCHINGCVAR: - m_interface->print ("You are already watching %s\n", stream.readString().chars()); + m_interface->print ("You are already watching %s\n", stream.readString().data()); break; case SVRC_WATCHCVARNOTFOUND: - m_interface->print ("CVar %s not found\n", stream.readString().chars()); + m_interface->print ("CVar %s not found\n", stream.readString().data()); break; case SVRC_CVARCHANGED: { String name = stream.readString(); String value = stream.readString(); - m_interface->print ("The value of CVar %s", name.chars()); - m_interface->print (" is now %s\n", value.chars()); + m_interface->print ("The value of CVar %s", name.data()); + m_interface->print (" is now %s\n", value.data()); // If sv_hostname changes, update the titlebar if (name == "sv_hostname") @@ -257,7 +270,7 @@ break; case SVRC_YOUREDISCONNECTED: - m_interface->print ("You have been disconnected: %s\n", stream.readString().chars()); + m_interface->print ("You have been disconnected: %s\n", stream.readString().data()); m_interface->disconnected(); break; } @@ -266,7 +279,7 @@ catch (std::exception& e) { m_interface->printWarning("Couldn't process packet: %s\n", e.what()); - m_interface->printWarning("Packet contents was: %s\n", message.quote().chars()); + m_interface->printWarning("Packet contents was: %s\n", quote(message).data()); m_interface->printWarning("Stream position in payload was: %d\n", stream.position()); } } @@ -279,10 +292,10 @@ { case SVRCU_PLAYERDATA: { - StringList players; + std::vector players; for (int i = packet.readByte(); i > 0; --i) - players.append(packet.readString()); + players.push_back(packet.readString()); m_interface->setPlayerNames(players); } @@ -306,7 +319,7 @@ // ------------------------------------------------------------------------------------------------- // -UDPSocket* RCONSession::getSocket() +net::UDPSocket* RCONSession::getSocket() { return &m_socket; } @@ -315,7 +328,7 @@ // void RCONSession::sendHello() { - m_interface->print("Connecting to %s...\n", m_address.to_string(IPAddress::WITH_PORT).chars()); + m_interface->print("Connecting to %s...\n", net::ip_address_to_string(m_address).data()); send({CLRC_BEGINCONNECTION, RCON_PROTOCOL_VERSION}); bumpLastPing(); } @@ -325,17 +338,17 @@ void RCONSession::sendPassword() { m_interface->print("Authenticating...\n"); - ByteArray message; + std::vector message; Bytestream stream(message); stream.writeByte(CLRC_PASSWORD); - stream.writeString((m_salt + m_password).md5()); + stream.writeString(md5((m_salt + m_password).data())); send(message); bumpLastPing(); } // ------------------------------------------------------------------------------------------------- // -void RCONSession::setPassword(const String& password) +void RCONSession::setPassword(const std::string& password) { m_password = password; } @@ -359,12 +372,12 @@ // ------------------------------------------------------------------------------------------------- // Returns true if the message was successfully sent. // -bool RCONSession::sendCommand(const String& commandString) +bool RCONSession::sendCommand(const std::string& commandString) { - if (m_state != RCON_CONNECTED or commandString.isEmpty()) + if (m_state != RCON_CONNECTED or commandString.empty()) return false; - ByteArray message; + std::vector message; Bytestream stream(message); stream.writeByte(CLRC_COMMAND); stream.writeString(commandString); @@ -382,7 +395,7 @@ // ------------------------------------------------------------------------------------------------- // -const IPAddress& RCONSession::address() const +const net::ip_address& RCONSession::address() const { return m_address; } @@ -396,18 +409,18 @@ // ------------------------------------------------------------------------------------------------- // -const String& RCONSession::getLevel() const +const std::string& RCONSession::getLevel() const { return m_level; } // ------------------------------------------------------------------------------------------------- // -void RCONSession::requestTabCompletion(const String& part) +void RCONSession::requestTabCompletion(const std::string& part) { if (m_serverProtocol >= 4) { - ByteArray message; + std::vector message; Bytestream stream(message); stream.writeByte(CLRC_TABCOMPLETE); stream.writeString(part); @@ -417,7 +430,7 @@ } else { - m_interface->print("This server does not support tab-completion\n", m_serverProtocol); + m_interface->print("This server does not support tab-completion\n"); } } @@ -432,22 +445,22 @@ // void RCONSession::requestWatch(const String& cvar) { - StringList cvars; - cvars.append(cvar); + const std::vector cvars{{cvar}}; requestWatch(cvars); } // ------------------------------------------------------------------------------------------------- // -void RCONSession::requestWatch(const StringList& cvars) +void RCONSession::requestWatch(const std::vector& cvars) { - ByteArray message; + std::vector message; Bytestream stream(message); stream.writeByte(CLRC_WATCHCVAR); - - for (const String& cvar : cvars) - stream.writeString(cvar.normalized()); - + for (String cvar : cvars) + { + normalize(cvar); + stream.writeString(cvar); + } stream.writeString(""); send(message); }