feat: work on client logic & integration
This commit is contained in:
parent
21ed479960
commit
df5e2c86dc
5 changed files with 173 additions and 0 deletions
29
modules/you_done_it/server_node.cpp
Normal file
29
modules/you_done_it/server_node.cpp
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#include "server_node.h"
|
||||
#include "ydi_server.h"
|
||||
#include <core/config/engine.h>
|
||||
|
||||
void ServerNode::_bind_methods() {}
|
||||
|
||||
void ServerNode::enter_tree() {
|
||||
ydi::server::open();
|
||||
}
|
||||
|
||||
void ServerNode::exit_tree() {
|
||||
ydi::server::close();
|
||||
}
|
||||
|
||||
void ServerNode::_notification(int what) {
|
||||
if (Engine::get_singleton()->is_editor_hint()) {
|
||||
return;
|
||||
}
|
||||
switch (what) {
|
||||
case NOTIFICATION_ENTER_TREE:
|
||||
enter_tree();
|
||||
return;
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
exit_tree();
|
||||
return;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
13
modules/you_done_it/server_node.h
Normal file
13
modules/you_done_it/server_node.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
#pragma once
|
||||
|
||||
#include <scene/main/node.h>
|
||||
|
||||
class ServerNode : public Node {
|
||||
GDCLASS(ServerNode, Node);
|
||||
static void _bind_methods();
|
||||
void enter_tree();
|
||||
void exit_tree();
|
||||
|
||||
protected:
|
||||
void _notification(int what);
|
||||
};
|
||||
114
modules/you_done_it/ydi_client.cpp
Normal file
114
modules/you_done_it/ydi_client.cpp
Normal file
|
|
@ -0,0 +1,114 @@
|
|||
#include "ydi_client.h"
|
||||
#include "core/string/print_string.h"
|
||||
#include "you_done_it/ydi_networking.h"
|
||||
#include <atomic>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <zmq.hpp>
|
||||
#include <zmq_addon.hpp>
|
||||
|
||||
namespace ydi::client {
|
||||
struct Connection {
|
||||
std::optional<std::string> server;
|
||||
std::optional<zmq::context_t> context{ std::nullopt };
|
||||
std::optional<zmq::socket_t> socket{ std::nullopt };
|
||||
std::recursive_mutex mtx;
|
||||
std::atomic<ConnectionStatus> status;
|
||||
std::atomic<bool> stop_threads;
|
||||
};
|
||||
|
||||
std::optional<Connection> connection{ std::nullopt };
|
||||
|
||||
std::optional<std::thread> receive_thread{ std::nullopt };
|
||||
|
||||
void handle_ok(zmq::multipart_t const &message) {
|
||||
MessageType type{ to_message_type(message[1]) };
|
||||
switch (type) {
|
||||
default: // no need to handle every OK, just some relevant ones
|
||||
return;
|
||||
case CONNECT:
|
||||
connection->status = AUTHENTICATED;
|
||||
}
|
||||
}
|
||||
|
||||
void handle_message(zmq::multipart_t const &message) {
|
||||
MessageType type{ to_message_type(message[0]) };
|
||||
switch (type) {
|
||||
case OK:
|
||||
handle_ok(message);
|
||||
default:
|
||||
print_error(vformat("Client: Unhandled message type received: ", type, message[0].to_string().c_str()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void receive_thread_entry() {
|
||||
zmq::multipart_t message{};
|
||||
while (!connection->stop_threads) {
|
||||
using namespace std::chrono_literals;
|
||||
std::this_thread::sleep_for(10ms);
|
||||
std::scoped_lock lock{ connection->mtx };
|
||||
if (message.recv(*connection->socket)) {
|
||||
handle_message(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void connect(String const &url) {
|
||||
connection.emplace();
|
||||
print_line("Client: Connecting to ", url);
|
||||
try {
|
||||
connection->context.emplace(1);
|
||||
} catch (...) {
|
||||
connection.reset();
|
||||
print_line("Client: Failed to create context");
|
||||
return;
|
||||
}
|
||||
print_line("Client: Created context");
|
||||
try {
|
||||
connection->socket.emplace(*connection->context, zmq::socket_type::dealer);
|
||||
} catch (...) {
|
||||
connection->context->close();
|
||||
connection->context.reset();
|
||||
connection.reset();
|
||||
print_line("Client: Failed to create socket");
|
||||
return;
|
||||
}
|
||||
print_line("Client: Created socket");
|
||||
try {
|
||||
CharStringT<char> cstrurl{ url.ascii() };
|
||||
std::string server{ cstrurl.get_data() };
|
||||
server = "tcp://" + server + ":6667";
|
||||
connection->socket->connect(server);
|
||||
connection->server = server;
|
||||
} catch (...) {
|
||||
connection->socket->close();
|
||||
connection->socket.reset();
|
||||
connection->context->close();
|
||||
connection->context.reset();
|
||||
connection.reset();
|
||||
print_line("Client: Failed to connect to server");
|
||||
}
|
||||
print_line("Client: connected to server");
|
||||
receive_thread.emplace(receive_thread_entry);
|
||||
}
|
||||
|
||||
void disconnect() {
|
||||
if (connection) {
|
||||
std::scoped_lock lock{ connection->mtx };
|
||||
if (receive_thread && receive_thread->joinable()) {
|
||||
receive_thread->join();
|
||||
}
|
||||
if (connection->socket) {
|
||||
connection->socket->close();
|
||||
connection->socket.reset();
|
||||
}
|
||||
if (connection->context) {
|
||||
connection->context->shutdown();
|
||||
connection->context.reset();
|
||||
}
|
||||
}
|
||||
connection.reset();
|
||||
}
|
||||
} //namespace ydi::client
|
||||
12
modules/you_done_it/ydi_client.h
Normal file
12
modules/you_done_it/ydi_client.h
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "ydi_networking.h"
|
||||
#include <core/string/ustring.h>
|
||||
|
||||
namespace ydi::client {
|
||||
void connect(String const &url);
|
||||
void disconnect();
|
||||
namespace send {
|
||||
void reveal_clue(ClueID id);
|
||||
} //namespace send
|
||||
} //namespace ydi::client
|
||||
Loading…
Add table
Add a link
Reference in a new issue