Skip to content
This repository was archived by the owner on Mar 29, 2026. It is now read-only.

Commit 112a738

Browse files
authored
fix, ci: general code improvements, removed some ci runners. (#15)
* fix, ci: general code improvements, packet_size no longer gets converted to size_t, removed some warnings on windows, added more unittests, removed some ci runners * fix: added/removed missing/unneeded spacing * feat: added missing socket header * ci: removed CI that isn't needed * ci: readded ctest to a runner * fix: Unit tests no longer complete if exception was found * ci: simplified ci for linux
1 parent d787a4e commit 112a738

10 files changed

Lines changed: 123 additions & 132 deletions

File tree

.github/workflows/CI.yml

Lines changed: 8 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,10 @@ jobs:
2626
fail-fast: false # Don't fail everything if one fails. We want to test each OS/Compiler individually
2727
matrix:
2828
cfg:
29-
- { arch: 'amd64', concurrency: 2, os: ubuntu-20.04, package: clang-10, cpp-version: clang++-10, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
30-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-11, cpp-version: clang++-11, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
31-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-12, cpp-version: clang++-12, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
32-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-13, cpp-version: clang++-13, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
33-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-14, cpp-version: clang++-14, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
34-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-15, cpp-version: clang++-15, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
35-
- { arch: 'amd64', concurrency: 2, os: ubuntu-20.04, package: g++-9, cpp-version: g++-9, ctest: 'yes', cpack: 'no', downloadcpp: 'yes'}
36-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-10, cpp-version: g++-10, ctest: 'no', cpack: 'yes', downloadcpp: 'yes'}
37-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-11, cpp-version: g++-11, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
38-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-12, cpp-version: g++-12, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
39-
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-13, cpp-version: g++-13, ctest: 'no', cpack: 'no', downloadcpp: 'yes'}
29+
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: clang-11, cpp-version: clang++-11, ctest: false, cpack: false }
30+
- { arch: 'amd64', concurrency: 2, os: ubuntu-24.04, package: clang-16, cpp-version: clang++-16, ctest: true, cpack: true }
31+
- { arch: 'amd64', concurrency: 2, os: ubuntu-22.04, package: g++-10, cpp-version: g++-10, ctest: false, cpack: false }
32+
- { arch: 'amd64', concurrency: 2, os: ubuntu-24.04, package: g++-13, cpp-version: g++-13, ctest: false, cpack: false }
4033
steps:
4134
- name: Harden Runner
4235
uses: step-security/harden-runner@20cf305ff2072d973412fa9b1e3a4f227bda3c76 # v2.14.0
@@ -47,11 +40,7 @@ jobs:
4740
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
4841

4942
- name: Install apt packages
50-
run: sudo sed -i 's/azure\.//' /etc/apt/sources.list && sudo apt update && sudo apt-get install -y pkg-config
51-
52-
- name: Install C++ apt package
53-
if: ${{ matrix.cfg.downloadcpp == 'yes' }}
54-
run: sudo apt-get install -y ${{ matrix.cfg.package }}
43+
run: sudo sed -i 's/azure\.//' /etc/apt/sources.list && sudo apt update && sudo apt-get install -y pkg-config ${{ matrix.cfg.package }}
5544

5645
- name: Generate CMake
5746
run: cmake -B build
@@ -62,19 +51,19 @@ jobs:
6251
run: cmake --build build -j${{ matrix.cfg.concurrency }}
6352

6453
- name: Run unit tests
65-
if: ${{ matrix.cfg.ctest == 'yes' }}
54+
if: ${{ matrix.cfg.ctest }}
6655
run: cd build && ctest -VV
6756
env:
6857
RCON_TESTING_IP: ${{secrets.RCON_TESTING_IP}}
6958
RCON_TESTING_PORT: ${{secrets.RCON_TESTING_PORT}}
7059
RCON_TESTING_PASSWORD: ${{secrets.RCON_TESTING_PASSWORD}}
7160

7261
- name: Package distributable
73-
if: ${{ matrix.cfg.cpack == 'yes' }}
62+
if: ${{ matrix.cfg.cpack }}
7463
run: cd build && cpack --verbose
7564

7665
- name: Upload Binary (DEB)
77-
if: ${{ matrix.cfg.cpack == 'yes' }}
66+
if: ${{ matrix.cfg.cpack }}
7867
uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0
7968
with:
8069
name: "librconpp - Debian Package ${{matrix.cfg.arch}}"
@@ -87,10 +76,6 @@ jobs:
8776
fail-fast: false # Don't cancel other matrix jobs if one fails
8877
matrix:
8978
cfg:
90-
- { name: 'x64', arch: x64, config: Release, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '' }
91-
- { name: 'x64', arch: x64, config: Debug, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '' }
92-
- { name: 'x86', arch: x86, config: Release, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '-T host=x86 ' }
93-
- { name: 'x86', arch: x86, config: Debug, vs: '2019', os: 'windows-2019', vsv: '16', upload: true, options: '-T host=x86 ' }
9479
- { name: 'x64', arch: x64, config: Release, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '' }
9580
- { name: 'x64', arch: x64, config: Debug, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '' }
9681
- { name: 'x86', arch: x86, config: Release, vs: '2022', os: 'windows-2022', vsv: '17', upload: true, options: '-T host=x86' }

CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@ option(BUILD_SHARED_LIBS "Build shared libraries" ON)
66
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
77
add_compile_definitions(RCONPP_BUILD)
88

9+
if(WIN32)
10+
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
11+
add_compile_definitions(_WINSOCK_DEPRECATED_NO_WARNINGS)
12+
endif ()
13+
914
set(RCONPP_ROOT_PATH ${CMAKE_CURRENT_SOURCE_DIR})
1015

1116
project(rconpp

include/rconpp/client.h

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class RCONPP_EXPORT rcon_client {
7777
*
7878
* @warning If you are expecting no response from the server, do NOT use the callback. You will halt the RCON process until the next received message (which will chain).
7979
*/
80-
void send_data(const std::string_view data, const int32_t id, data_type type, std::function<void(const response& retrieved_data)> callback = {}) {
80+
void send_data(const std::string_view data, const int32_t id, const data_type type, std::function<void(const response& retrieved_data)> callback = {}) {
8181
requests_queued.emplace_back(queued_request{ std::string{data}, id, type, std::move(callback) });
8282
}
8383

@@ -122,13 +122,6 @@ class RCONPP_EXPORT rcon_client {
122122
* @return A packet structure containing the length, size, data, and if server responded.
123123
*/
124124
packet read_packet();
125-
126-
/**
127-
* @brief Reads the first 4 bytes of a packet to get the packet size (not to be mistaken with length).
128-
*
129-
* @return The size (not length) of the packet.
130-
*/
131-
int read_packet_size();
132125
};
133126

134-
} // namespace rconpp
127+
} // namespace rconpp

include/rconpp/export.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,4 @@
1212
#else
1313
#define RCONPP_EXPORT
1414
#endif
15-
#endif
15+
#endif

include/rconpp/server.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,6 @@ class RCONPP_EXPORT rcon_server {
112112
* @brief Gathers all the packet's content (based on the length returned by `read_packet_length`)
113113
*/
114114
void read_packet(rconpp::connected_client client);
115-
116-
/**
117-
* @brief Reads the first 4 bytes of a packet to get the packet size (not to be mistaken with length).
118-
*
119-
* @return The size (not length) of the packet.
120-
*/
121-
int read_packet_size(const rconpp::connected_client client);
122115
};
123116

124-
} // namespace rconpp
117+
} // namespace rconpp

include/rconpp/utilities.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#pragma once
22

3+
#include <functional>
4+
35
#include "export.h"
46
#include <string>
57
#include <string_view>
@@ -8,9 +10,10 @@
810

911
namespace rconpp {
1012

11-
constexpr int DEFAULT_TIMEOUT = 4;
13+
constexpr int DEFAULT_TIMEOUT = 4; // In Seconds.
1214
constexpr int MIN_PACKET_SIZE = 10;
1315
constexpr int MIN_PACKET_LENGTH = 14;
16+
constexpr int MAX_RETRIES_TO_RECEIVE_INFO = 500;
1417

1518
enum data_type {
1619
/**
@@ -91,4 +94,11 @@ RCONPP_EXPORT int type_to_int(const std::vector<char>& buffer);
9194
*/
9295
RCONPP_EXPORT void report_error();
9396

94-
} // namespace rconpp
97+
/**
98+
* @brief Reads the first 4 bytes of a packet to get the packet size (not to be mistaken with length).
99+
*
100+
* @return The size (not length) of the packet.
101+
*/
102+
RCONPP_EXPORT int read_packet_size(int socket, const std::function<void(const std::string_view log)>& on_log);
103+
104+
} // namespace rconpp

src/rconpp/client.cpp

Lines changed: 37 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,12 @@ rconpp::response rconpp::rcon_client::send_data_sync(const std::string_view data
4949
bool rconpp::rcon_client::connect_to_server() {
5050
#ifdef _WIN32
5151
// Initialize Winsock
52-
WSADATA wsa_data;
53-
int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
54-
if (result != 0) {
55-
on_log("WSAStartup failed. Error: " + std::to_string(result));
56-
return false;
57-
}
52+
WSADATA wsa_data;
53+
int result = WSAStartup(MAKEWORD(2, 2), &wsa_data);
54+
if (result != 0) {
55+
on_log("WSAStartup failed. Error: " + std::to_string(result));
56+
return false;
57+
}
5858
#endif
5959

6060
// Create new TCP socket.
@@ -71,7 +71,7 @@ bool rconpp::rcon_client::connect_to_server() {
7171
}
7272

7373
// Setup port, address, and family.
74-
struct sockaddr_in server {};
74+
sockaddr_in server{};
7575
server.sin_family = AF_INET;
7676
#ifdef _WIN32
7777
#ifdef UNICODE
@@ -85,7 +85,8 @@ bool rconpp::rcon_client::connect_to_server() {
8585
server.sin_port = htons(port);
8686

8787
#ifdef _WIN32
88-
int corrected_timeout = DEFAULT_TIMEOUT * 1000;
88+
// DEFAULT_TIMEOUT is in seconds (library was originally built for Linux and Linux/Unix uses seconds, we just need to convert to milliseconds for Windows.
89+
const int corrected_timeout = DEFAULT_TIMEOUT * 1000;
8990
setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, (const char*)&corrected_timeout, sizeof(corrected_timeout));
9091
#else
9192
// Set a timeout of 4 seconds.
@@ -109,32 +110,27 @@ bool rconpp::rcon_client::connect_to_server() {
109110
rconpp::response rconpp::rcon_client::receive_information(int32_t id, rconpp::data_type type) {
110111
// Whilst this loop is better than a while loop,
111112
// it should really just keep going for a certain amount of seconds.
112-
for (int i = 0; i < 500; i++) {
113+
for (int i = 0; i < MAX_RETRIES_TO_RECEIVE_INFO; i++) {
113114
packet packet_response = read_packet();
114115

115-
int packet_type = bit32_to_int(packet_response.data);
116+
const auto packet_type = static_cast<data_type>(bit32_to_int(packet_response.data));
116117

117118
if (packet_response.length == 0) {
118-
if (packet_type != SERVERDATA_AUTH)
119+
if (packet_type != SERVERDATA_AUTH) {
119120
return { "", packet_response.server_responded };
120-
else
121-
continue;
121+
}
122+
123+
continue;
122124
}
123125

124126
if (type == SERVERDATA_AUTH) {
125-
if (packet_type == -1) {
126-
return { "", false };
127-
} else {
128-
if (packet_type == id) {
129-
return { "", true };
130-
}
131-
}
127+
return { "", packet_type == id };
132128
}
133129

134130
if (packet_type == id) {
135131
std::string part{};
136132

137-
if(packet_response.size > 10) {
133+
if (packet_response.size > MIN_PACKET_SIZE) {
138134
part = std::string(&packet_response.data[8], &packet_response.data[packet_response.data.size()-1]);
139135
}
140136

@@ -146,29 +142,27 @@ rconpp::response rconpp::rcon_client::receive_information(int32_t id, rconpp::da
146142
}
147143

148144
rconpp::packet rconpp::rcon_client::read_packet() {
149-
size_t packet_size = read_packet_size();
145+
const int packet_size = read_packet_size(static_cast<int>(sock), on_log);
150146

151147
packet temp_packet{};
152148
temp_packet.length = packet_size + 4;
153149

154-
if(packet_size > 0) {
150+
if (packet_size > 0) {
155151
temp_packet.size = packet_size;
156152
}
157153

158-
/*
159-
* If the packet size is -1, the server didn't respond.
160-
* If the packet size is 0, the server did respond but said nothing.
161-
*/
154+
// If the packet size is -1, the server didn't respond.
162155
if (packet_size == -1) {
163156
return temp_packet;
164157
}
165-
else if (packet_size == 0) {
166-
temp_packet.server_responded = true;
167-
return temp_packet;
168-
}
169158

170159
temp_packet.server_responded = true;
171160

161+
// If the packet size is 0, the server did respond but said nothing.
162+
if (packet_size == 0) {
163+
return temp_packet;
164+
}
165+
172166
std::vector<char> buffer{};
173167
buffer.resize(temp_packet.length);
174168

@@ -183,50 +177,38 @@ rconpp::packet rconpp::rcon_client::read_packet() {
183177
return temp_packet;
184178
}
185179

186-
int rconpp::rcon_client::read_packet_size() {
187-
std::vector<char> buffer{};
188-
buffer.resize(4);
189-
190-
/*
191-
* RCON gives the packet SIZE in the first four (4) bytes of each packet.
192-
* We simply just want to read that and then return it.
193-
*/
194-
if (recv(sock, buffer.data(), 4, 0) == -1) {
195-
on_log("Did not receive a packet in time. Did the server send a response?");
196-
report_error();
197-
return -1;
198-
}
199-
200-
return bit32_to_int(buffer);
201-
}
202-
203-
void rconpp::rcon_client::start(bool return_after) {
204-
180+
void rconpp::rcon_client::start(const bool return_after) {
205181
auto block_calling_thread = [this]() {
206182
std::mutex thread_mutex;
207183
std::unique_lock thread_lock(thread_mutex);
208184
this->terminating.wait(thread_lock);
209185
};
210186

211-
if(port > 65535) {
187+
if (address.empty()) {
188+
on_log("Address is empty! You need to pass a valid address!");
189+
return;
190+
}
191+
192+
if (port > 65535) {
212193
on_log("Invalid port! The port can't exceed 65535!");
213194
return;
214195
}
215196

216197
on_log("Attempting connection to RCON server...");
217198

218199
if (!connect_to_server()) {
219-
on_log("RCON is aborting as it failed to initiate client.");
200+
on_log("RCON++ is aborting as it failed to initiate client.");
220201
return;
221202
}
222203

223204
on_log("Connected successfully! Sending login data...");
224205

225206
// The server will send SERVERDATA_AUTH_RESPONSE once it's happy. If it's not -1, the server will have accepted us!
226-
response response = send_data_sync(password, 1, data_type::SERVERDATA_AUTH, true);
207+
// We use the _sync method here to do a blocking call.
208+
const response response = send_data_sync(password, 1, data_type::SERVERDATA_AUTH, true);
227209

228210
if (!response.server_responded) {
229-
on_log("Login data was incorrect. RCON will now abort.");
211+
on_log("Login data was incorrect. RCON++ will now abort.");
230212
return;
231213
}
232214

@@ -252,7 +234,7 @@ void rconpp::rcon_client::start(bool return_after) {
252234
}
253235
});
254236

255-
if(!return_after) {
237+
if (!return_after) {
256238
block_calling_thread();
257239
}
258240
};

0 commit comments

Comments
 (0)