Wed, 20 Jul 2016 12:55:39 +0300
Merged with default
--- a/sources/coloredline.cpp Mon Jan 11 16:58:59 2016 +0200 +++ b/sources/coloredline.cpp Wed Jul 20 12:55:39 2016 +0300 @@ -160,6 +160,14 @@ // ------------------------------------------------------------------------------------------------- // +void ColoredLine::add_string (const String& text) +{ + for (char a : text) + add_char (a); +} + +// ------------------------------------------------------------------------------------------------- +// void ColoredLine::activate_color (Color color, bool bold) { if (m_boldActive)
--- a/sources/coloredline.h Mon Jan 11 16:58:59 2016 +0200 +++ b/sources/coloredline.h Wed Jul 20 12:55:39 2016 +0300 @@ -69,6 +69,7 @@ const Vector<int>& data() const { return m_data; } int length() const { return m_length; } void add_char (char ch); + void add_string (const String& msg); void finalize(); int rows (int cols) const;
--- a/sources/interface.cpp Mon Jan 11 16:58:59 2016 +0200 +++ b/sources/interface.cpp Wed Jul 20 12:55:39 2016 +0300 @@ -637,10 +637,7 @@ if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION) { if (ch == 'y' or ch == 'Y') - { - m_session.disconnect(); - m_disconnectCallback(true); - } + disconnected(); else if (ch == 'n' or ch == 'N') set_input_state (INPUTSTATE_NORMAL); @@ -1099,8 +1096,15 @@ endwin(); throw Exitception(); } + else if (command == "watch") + { + if (not args.is_empty()) + m_session.request_watch(args); + else + print_error("No CVars to watch.\n"); + } else - print_error("Unknown command: %s\n", command.chars()); + print_error("Unknown command %s\n", command.chars()); } // -------------------------------------------------------------------------------------------------
--- a/sources/network/rconsession.cpp Mon Jan 11 16:58:59 2016 +0200 +++ b/sources/network/rconsession.cpp Wed Jul 20 12:55:39 2016 +0300 @@ -116,18 +116,23 @@ } for (Datagram datagram; m_socket.read (datagram);) - handle_packet (datagram.data, datagram.from); + handle_packet (datagram); } // ------------------------------------------------------------------------------------------------- // -void RCONSession::handle_packet (Bytestream& packet, const IPAddress& from) +void RCONSession::handle_packet (Datagram& datagram) { - if (from != m_address) + if (datagram.from != m_address) return; try { + Bytestream& packet = datagram.data; + int32_t header = packet.read_long(); + int32_t sequenceNumber = (header != 0) ? packet.read_long() : 0; + m_interface->print("Recieved packet with header 0x%x and sequence number #%d\n", header, sequenceNumber); + while (packet.bytes_left() > 0) { int header = packet.read_byte(); @@ -183,6 +188,10 @@ } m_interface->print ("End of previous messages.\n"); + + // Watch sv_hostname so that we can update the titlebar when it changes. + request_watch("sv_hostname"); + m_interface->print ("Watch requested.\n"); break; case SVRC_UPDATE: @@ -221,6 +230,40 @@ } } break; + + case SVRC_WATCHINGCVAR: + m_interface->print ("You are now watching %s\n", packet.read_string().chars()); + m_interface->print ("Its value is: %s\n", packet.read_string().chars()); + break; + + case SVRC_ALREADYWATCHINGCVAR: + m_interface->print ("You are already watching %s\n", packet.read_string().chars()); + break; + + case SVRC_WATCHCVARNOTFOUND: + m_interface->print ("CVar %s not found\n", packet.read_string().chars()); + break; + + case SVRC_CVARCHANGED: + { + String name = packet.read_string(); + String value = packet.read_string(); + m_interface->print ("The value of CVar %s", name.chars()); + m_interface->print (" is now %s\n", value.chars()); + + // If sv_hostname changes, update the titlebar + if (name == "sv_hostname") + { + m_hostname = value; + m_interface->set_title(m_hostname); + } + } + break; + + case SVRC_YOUREDISCONNECTED: + m_interface->print ("You have been disconnected: %s\n", packet.read_string().chars()); + m_interface->disconnected(); + break; } } } @@ -327,8 +370,18 @@ return false; Bytestream packet; - packet.write_byte (CLRC_COMMAND); - packet.write_string (message); + + // Let's hardcode a /watch for CVar watching testing purposes + if (message.starts_with ("/watch ")) + { + request_watch(message.mid(String("/watch ").length(), -1).split(',')); + } + else + { + packet.write_byte (CLRC_COMMAND); + packet.write_string (message); + } + send (packet); bump_last_ping(); return true; @@ -388,4 +441,27 @@ m_interface = iface; } +// ------------------------------------------------------------------------------------------------- +// +void RCONSession::request_watch (const String& cvar) +{ + StringList cvars; + cvars.append(cvar); + request_watch(cvars); +} + +// ------------------------------------------------------------------------------------------------- +// +void RCONSession::request_watch (const StringList& cvars) +{ + Bytestream packet; + packet.write_byte(CLRC_WATCHCVAR); + + for (int i = 0; i < cvars.size(); ++i) + packet.write_string(cvars[i].normalized()); + + packet.write_string(""); + send(packet); +} + END_ZFC_NAMESPACE
--- a/sources/network/rconsession.h Mon Jan 11 16:58:59 2016 +0200 +++ b/sources/network/rconsession.h Wed Jul 20 12:55:39 2016 +0300 @@ -38,7 +38,7 @@ // enum { - RCON_PROTOCOL_VERSION = 4 + RCON_PROTOCOL_VERSION = 5 }; // ------------------------------------------------------------------------------------------------- @@ -54,6 +54,11 @@ SVRC_UPDATE, SVRC_TABCOMPLETE, SVRC_TOOMANYTABCOMPLETES, + SVRC_WATCHINGCVAR, + SVRC_ALREADYWATCHINGCVAR, + SVRC_WATCHCVARNOTFOUND, + SVRC_CVARCHANGED, + SVRC_YOUREDISCONNECTED, }; // ------------------------------------------------------------------------------------------------- @@ -66,6 +71,7 @@ CLRC_PONG, CLRC_DISCONNECT, CLRC_TABCOMPLETE, + CLRC_WATCHCVAR, }; // ------------------------------------------------------------------------------------------------- @@ -98,7 +104,7 @@ const IPAddress& address() const; void connect (IPAddress address); void disconnect(); - void handle_packet (Bytestream& packet, const IPAddress& from); + void handle_packet (Datagram& datagram); void process_server_updates (Bytestream& packet); int num_admins() const; void send (const Bytestream& packet); @@ -114,6 +120,8 @@ bool is_active() const; void request_tab_complete (const String& part); void set_interface (class Interface* iface); + void request_watch (const String& cvar); + void request_watch (const StringList& cvars); private: RCONSessionState m_state; @@ -130,4 +138,4 @@ class Interface* m_interface; }; -END_ZFC_NAMESPACE \ No newline at end of file +END_ZFC_NAMESPACE
--- a/sources/network/udpsocket.cpp Mon Jan 11 16:58:59 2016 +0200 +++ b/sources/network/udpsocket.cpp Wed Jul 20 12:55:39 2016 +0300 @@ -129,10 +129,15 @@ return false; } + if (length < 4) + { + m_error = "The server sent a too short packet"; + return false; + } + unsigned char decodedPacket[MAX_DATAGRAM_LENGTH]; int decodedLength = sizeof decodedPacket; - HUFFMAN_Decode (reinterpret_cast<unsigned char*> (HuffmanBuffer), - decodedPacket, length, &decodedLength); + HUFFMAN_Decode (reinterpret_cast<unsigned char*>(HuffmanBuffer), decodedPacket, length, &decodedLength); datagram.from.host = ntohl (claddr.sin_addr.s_addr); datagram.from.port = ntohs (claddr.sin_port); datagram.data = Bytestream (decodedPacket, decodedLength);