aboutsummaryrefslogtreecommitdiff
path: root/src/handler.cpp
blob: f82573c193df4b4af29430b653fe2ac8d056112d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
#include <winsock2.h>

#include "handler.h"
#include "plugin.h"
#include "internal/convarproxy.h"

#define SLEEP_DURATION 5000

ServerHandler::ServerHandler(Plugin* plugin):
	plugin(plugin)
{
    this->Convar_Port = plugin->ConVar("southrpc_port", DEFAULT_PORT, FCVAR_ARCHIVE, "South RPC HTTP Port (requires restart, default: " DEFAULT_PORT ")");

    if (WSAStartup(MAKEWORD(2, 2), &this->wsaData) != 0) {
        spdlog::error("Failed to open Windows Socket");
        return;
    }

    if (LOBYTE(this->wsaData.wVersion) != 2 ||
        HIBYTE(this->wsaData.wVersion) != 2)
    {
        spdlog::error("Incorrect Winsock version loaded");
        WSACleanup();
        return;
    }

    spdlog::info("Initialized handler");

    this->init = true;

    /*
    @TODO
    this->register_callback(
        "list_methods",
        [=](rapidjson::Value& params) -> rapidjson::Value
        {
            rapidjson::MemoryPoolAllocator<>& allocator = this->body.GetAllocator();

            return rapidjson::Value(1);
        }
    );
    */

}

static DWORD WINAPI static_server_run(void* param)
{
    ServerHandler* server = (ServerHandler*)param;

    server->run();

    return 0;
}

void ServerHandler::start()
{
	if (!this->init || this->running)
		return;

    DWORD thread_id;
    this->thread = CreateThread(NULL, 0, static_server_run, (void*)this, 0, &thread_id);
}

void ServerHandler::stop()
{
    if (!this->thread)
        return;

    this->running = false;
    TerminateThread(this->thread, 0);
    this->thread = nullptr;
}

void ServerHandler::run()
{
	this->running = true;

    spdlog::info("Running Handler");

    // The engine won't have loaded convar data until after the entry
    //Sleep(SLEEP_DURATION);

    //int port = this->Convar_Port->GetInt();
    int port = 26503;
    RPCServer* server = new RPCServer(INADDR_ANY, port);
    Sleep(SLEEP_DURATION);

    while (this->running)
    {
    	RPCRequest* request = server->receive_request();
        spdlog::debug("received request");
    	if (!request)
    		continue;

        std::string method_name = request->get_method();

        callback_list::const_iterator method_pos = this->methods.find(method_name);
        if (method_pos != this->methods.end())
        {
            spdlog::info("Invoked method '{}'", method_name);
            request->result(method_pos->second(request->get_allocator(), request->get_params()));
        }
        else
        {
            spdlog::error("Attempted to invoke unknown method '{}'", method_name);
            request->error(rapidjson::Value("Unknown method"));
        }

        delete request;
    }

    delete server;
}