#102 Added a simple sandbox-implementation of "IRCClient" - For testing stuff.
parent
b74969cef9
commit
31be24eb7f
@ -0,0 +1,4 @@ |
|||||||
|
project(IRCClientSandbox) |
||||||
|
|
||||||
|
add_executable(${PROJECT_NAME} main.cpp) |
||||||
|
target_link_libraries(${PROJECT_NAME} IRCClient) |
@ -0,0 +1,277 @@ |
|||||||
|
#include "IRCClient/IRCBase.h" |
||||||
|
#include <fmt/format.h> |
||||||
|
|
||||||
|
//#define ENABLE_MESSAGES
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef ENABLE_MESSAGES |
||||||
|
template <typename ... Ts> |
||||||
|
void print(const std::string& msg, Ts ... arg) |
||||||
|
{ |
||||||
|
fmt::print(msg, arg...); |
||||||
|
} |
||||||
|
|
||||||
|
void print(const std::string& msg) |
||||||
|
{ |
||||||
|
fmt::print(msg); |
||||||
|
} |
||||||
|
#else |
||||||
|
void print(const std::string&) |
||||||
|
{} |
||||||
|
template <typename ... Ts> |
||||||
|
void print(const std::string&, Ts ...) |
||||||
|
{} |
||||||
|
#endif |
||||||
|
|
||||||
|
class IRCClient : public IRCBase |
||||||
|
{ |
||||||
|
void onConnected() override |
||||||
|
{ |
||||||
|
print("Connected to {}:{} (ssl={})", getHostname(), getPort(), isSSL()); |
||||||
|
} |
||||||
|
|
||||||
|
void onConnectedWithSSLExceptions(const std::vector<IRCError>& codes) override |
||||||
|
{ |
||||||
|
print("Connected (with ssl exceptions) to {}:{} (ssl={})", getHostname(), getPort(), isSSL()); |
||||||
|
for (const auto& code : codes) |
||||||
|
print("SSL exception: {}", IRCErrorToString(code)); |
||||||
|
} |
||||||
|
|
||||||
|
void onDisconnected() override |
||||||
|
{ |
||||||
|
print("Disconnected from {}:{} (ssl={})", getHostname(), getPort(), isSSL()); |
||||||
|
m_running = false; |
||||||
|
} |
||||||
|
|
||||||
|
void onRegistered() override |
||||||
|
{ |
||||||
|
print("Successfully registered with the server"); |
||||||
|
} |
||||||
|
|
||||||
|
void onConnectionError(IRCError e) override |
||||||
|
{ |
||||||
|
print("Connection error: ", IRCErrorToString(e)); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgNick(const IRCPrefix& sender, const std::string& newNickname, const std::vector<std::string>& channelsAffected) override |
||||||
|
{ |
||||||
|
print("{} is now known as {}", sender.nickname(), newNickname); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgMode(const IRCPrefix& sender, const std::string& target, const std::string& modes, const std::vector<std::string>& args) override |
||||||
|
{ |
||||||
|
std::string everything = modes; |
||||||
|
for (const auto& arg : args) |
||||||
|
everything.append(fmt::format(" {}", arg)); |
||||||
|
|
||||||
|
if (target == getNickname()) |
||||||
|
print("Own usermode changed: {}", everything); |
||||||
|
else |
||||||
|
print("[{}] Mode set: {}", target, everything); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgQuit(const IRCPrefix& sender, const std::string& message, const std::vector<std::string>& channelsAffected) override |
||||||
|
{ |
||||||
|
print("Quit: {} ({}@{}) ({})", sender.nickname(), sender.user(), sender.host(), message); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgJoin(const IRCPrefix& sender, const std::string& target) override |
||||||
|
{ |
||||||
|
print("[{}] Join: {} ({}@{})", target, sender.nickname(), sender.user(), sender.host()); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgPart(const IRCPrefix& sender, const std::string& target, const std::string& message) override |
||||||
|
{ |
||||||
|
if (message.empty()) |
||||||
|
print("[{}] Part: {} ({}@{})", target, sender.nickname(), sender.user(), sender.host()); |
||||||
|
else |
||||||
|
print("[{}] Part: {} ({}@{}) ({})", target, sender.nickname(), sender.user(), sender.host(), message); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgTopic(const IRCPrefix& sender, const std::string& target, const std::string& topic) override |
||||||
|
{ |
||||||
|
if (topic.empty()) |
||||||
|
print("[{}] {} cleared the topic", target, sender.nickname()); |
||||||
|
else |
||||||
|
print("[{}] {} set new topic: {}", target, sender.nickname(), topic); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgInvite(const IRCPrefix& sender, const std::string& target) override |
||||||
|
{ |
||||||
|
print("{} invited you to join {}", sender.nickname(), target); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgKick(const IRCPrefix& sender, const std::string& target, const std::string& who, const std::string& reason) override |
||||||
|
{ |
||||||
|
if (who == getNickname()) |
||||||
|
print("[{}] You were kicked by {} ({})", target, sender.nickname(), reason); |
||||||
|
else |
||||||
|
print("[{}] {} kicked {} ({})", target, sender.nickname(), who, reason); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgPrivmsg(const IRCPrefix& sender, const std::string& target, const std::string& message) override |
||||||
|
{ |
||||||
|
print("[{}] <{}> {}", target, sender.nickname(), message); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgNotice(const IRCPrefix& sender, const std::string& target, const std::string& message) override |
||||||
|
{ |
||||||
|
if (target == getNickname()) |
||||||
|
print("-{}- {}", sender.nickname(), message); |
||||||
|
else |
||||||
|
print("[{}] -{}- {}", target, sender.nickname(), message); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgKill(const IRCPrefix& sender, const std::string& reason) override |
||||||
|
{ |
||||||
|
print("You were killed by {} ({})", sender.nickname(), reason); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgPing(const std::string& message) override |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void onMsgPong(const std::string& message) override |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void onMsgError(const std::string& message) override |
||||||
|
{ |
||||||
|
print("Server error: {}", message); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgWallops(const IRCPrefix& sender, const std::string& message) override |
||||||
|
{ |
||||||
|
print("!{}! {}", sender.nickname(), message); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgNumeric(const IRCPrefix& sender, const std::string& num, const std::vector<std::string>& args, const std::string& message) override |
||||||
|
{ |
||||||
|
std::string everything; |
||||||
|
|
||||||
|
for (const auto& arg : args) |
||||||
|
everything.append(fmt::format("{} ", arg)); |
||||||
|
|
||||||
|
if (!everything.empty()) |
||||||
|
everything.append(": "); |
||||||
|
|
||||||
|
everything.append(message); |
||||||
|
print(everything); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgCTCPRequest(const IRCPrefix& sender, const std::string& target, const std::string& command, const std::string& message) override |
||||||
|
{ |
||||||
|
std::string printmsg; |
||||||
|
if (message.empty()) |
||||||
|
printmsg = fmt::format("[CTCP {} from {}]", command, sender.nickname()); |
||||||
|
else |
||||||
|
printmsg = fmt::format("[CTCP {} from {}] {}", command, sender.nickname(), message); |
||||||
|
|
||||||
|
if (target != getNickname()) |
||||||
|
printmsg = fmt::format("[{}] {}", target, printmsg); |
||||||
|
|
||||||
|
print(printmsg); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgCTCPResponse(const IRCPrefix& sender, const std::string& target, const std::string& command, const std::string& message) override |
||||||
|
{ |
||||||
|
std::string printmsg; |
||||||
|
if (message.empty()) |
||||||
|
printmsg = fmt::format("[CTCP REPLY {} from {}]", command, sender.nickname()); |
||||||
|
else |
||||||
|
printmsg = fmt::format("[CTCP REPLY {} from {}] {}", command, sender.nickname(), message); |
||||||
|
|
||||||
|
if (target != getNickname()) |
||||||
|
printmsg = fmt::format("[{}] {}", target, printmsg); |
||||||
|
|
||||||
|
print(printmsg); |
||||||
|
} |
||||||
|
|
||||||
|
void onMsgDCCRequest(std::shared_ptr<DCC> dcc, const IRCPrefix& sender, const std::string& target, const std::string& type, const std::string& message) override |
||||||
|
{ |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
void v3onMsgAway(const IRCPrefix& sender, const std::string& message, const std::vector<std::string>& channelsAffected) override |
||||||
|
{ |
||||||
|
if (message.empty()) |
||||||
|
print("{} is no longer away", sender.nickname()); |
||||||
|
else |
||||||
|
print("{} is away: {}", sender.nickname(), message); |
||||||
|
} |
||||||
|
|
||||||
|
void v3onMsgAccountLogin(const IRCPrefix& sender, const std::string& useraccount) override |
||||||
|
{ |
||||||
|
print("{} is now logged in as {}", sender.nickname(), useraccount); |
||||||
|
} |
||||||
|
|
||||||
|
void v3onMsgAccountLogout(const IRCPrefix& sender) override |
||||||
|
{ |
||||||
|
print("{} logged out from their account", sender.nickname()); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Required IRCv3 extensions to implement. |
||||||
|
*/ |
||||||
|
void v3onMsgJoin(const IRCPrefix& sender, const std::string& channel, const std::string& useraccount, const std::string& realname) override |
||||||
|
{ |
||||||
|
print("[{}] Join: {} (Account: {}) ({}@{})", channel, sender.nickname(), useraccount, sender.user(), sender.host()); |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* Catch-all handler. If the message parser cannot match for any of the commands, it will turn up here. |
||||||
|
* Optional to implement. |
||||||
|
*/ |
||||||
|
void onMsgUnhandled(const IRCPrefix& sender, const std::string& command, const std::vector<std::string>& args, const std::string& message) override |
||||||
|
{ |
||||||
|
std::string everything = command; |
||||||
|
|
||||||
|
for (const auto& arg : args) |
||||||
|
everything.append(fmt::format(" {}", arg)); |
||||||
|
|
||||||
|
if (!message.empty()) |
||||||
|
everything.append(fmt::format(" {}", message)); |
||||||
|
|
||||||
|
print("Unhandled command from {}: {}", sender.nickname(), everything); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
bool m_running{ true }; |
||||||
|
|
||||||
|
public: |
||||||
|
[[nodiscard]] bool isRunning() const { return m_running; } |
||||||
|
}; |
||||||
|
|
||||||
|
int main() |
||||||
|
{ |
||||||
|
IRCClient client; |
||||||
|
|
||||||
|
/*
|
||||||
|
* WARNING |
||||||
|
* Do not commit any connection details to the source repository! |
||||||
|
*/ |
||||||
|
client.setHostname(""); |
||||||
|
client.setPort(""); |
||||||
|
client.setNickname(""); |
||||||
|
client.setIdent(""); |
||||||
|
client.setRealname(""); |
||||||
|
|
||||||
|
auto connectionStatus = client.tryConnect(); |
||||||
|
|
||||||
|
print("Entering event loop"); |
||||||
|
|
||||||
|
while (true) { |
||||||
|
if (connectionStatus != IRCError::NoError || !client.isRunning()) |
||||||
|
break; |
||||||
|
|
||||||
|
client.poll(); |
||||||
|
|
||||||
|
connectionStatus = client.lastErrorCode(); |
||||||
|
} |
||||||
|
|
||||||
|
print("Leaving event loop"); |
||||||
|
|
||||||
|
return 0; |
||||||
|
} |
Loading…
Reference in new issue