diff --git a/CMakeLists.txt b/CMakeLists.txt index 1d3adcc25..55d9a4cfb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -229,6 +229,7 @@ ENDIF(EQEMU_ENABLE_BOTS) #What to build OPTION(EQEMU_BUILD_SERVER "Build the game server." ON) OPTION(EQEMU_BUILD_LOGIN "Build the login server." OFF) +OPTION(EQEMU_BUILD_SOCKET_SERVER "Build the socket server." OFF) OPTION(EQEMU_BUILD_TESTS "Build utility tests." OFF) OPTION(EQEMU_BUILD_PERL "Build Perl parser." ON) OPTION(EQEMU_BUILD_LUA "Build Lua parser." OFF) @@ -297,6 +298,13 @@ IF(EQEMU_BUILD_LUA) ENDIF(EQEMU_SANITIZE_LUA_LIBS) ENDIF(EQEMU_BUILD_LUA) +IF(EQEMU_BUILD_SOCKET_SERVER) + FIND_PACKAGE(Boost COMPONENTS system filesystem thread REQUIRED) + INCLUDE_DIRECTORIES("${CMAKE_CURRENT_SOURCE_DIR}/dependencies/websocketpp") + ADD_DEFINITIONS(-D_WEBSOCKETPP_CPP11_STL_) + +ENDIF(EQEMU_BUILD_SOCKET_SERVER) + INCLUDE_DIRECTORIES("${ZLIB_INCLUDE_DIRS}" "${MySQL_INCLUDE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}/common/glm/glm") IF(EQEMU_BUILD_LUA) diff --git a/socket_server/CMakeLists.txt b/socket_server/CMakeLists.txt index f647863d9..abaec0f21 100644 --- a/socket_server/CMakeLists.txt +++ b/socket_server/CMakeLists.txt @@ -19,7 +19,7 @@ INSTALL(TARGETS socket_server RUNTIME DESTINATION ${CMAKE_INSTALL_PREFIX}) ADD_DEFINITIONS(-DQSERV) -TARGET_LINK_LIBRARIES(socket_server Common debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) +TARGET_LINK_LIBRARIES(socket_server Common ${Boost_LIBRARIES} debug ${MySQL_LIBRARY_DEBUG} optimized ${MySQL_LIBRARY_RELEASE} ${ZLIB_LIBRARY}) IF(MSVC) SET_TARGET_PROPERTIES(socket_server PROPERTIES LINK_FLAGS_RELEASE "/OPT:REF /OPT:ICF") diff --git a/socket_server/socket_server.cpp b/socket_server/socket_server.cpp index eed4751d1..997d9965f 100644 --- a/socket_server/socket_server.cpp +++ b/socket_server/socket_server.cpp @@ -17,6 +17,26 @@ */ +#include +#include +#include +/*#include +#include +#include */ +#include + +typedef websocketpp::server server; + +using websocketpp::connection_hdl; +using websocketpp::lib::placeholders::_1; +using websocketpp::lib::placeholders::_2; +using websocketpp::lib::bind; + +using websocketpp::lib::thread; +using websocketpp::lib::mutex; +using websocketpp::lib::unique_lock; +using websocketpp::lib::condition_variable; + #include "../common/debug.h" #include "../common/opcodemgr.h" #include "../common/EQStreamFactory.h" @@ -44,7 +64,150 @@ void CatchSignal(int sig_num) { worldserver->Disconnect(); } +/* Web Sockets Start Shit */ + +enum action_type { + SUBSCRIBE, + UNSUBSCRIBE, + MESSAGE +}; + +struct action { + action(action_type t, connection_hdl h) : type(t), hdl(h) {} + action(action_type t, connection_hdl h, server::message_ptr m) + : type(t), hdl(h), msg(m) {} + + action_type type; + websocketpp::connection_hdl hdl; + server::message_ptr msg; +}; + +class broadcast_server { +public: + broadcast_server() { + // Initialize Asio Transport + m_server.init_asio(); + + // Register handler callbacks + m_server.set_open_handler(bind(&broadcast_server::on_open, this, ::_1)); + m_server.set_close_handler(bind(&broadcast_server::on_close, this, ::_1)); + m_server.set_message_handler(bind(&broadcast_server::on_message, this, ::_1, ::_2)); + } + + void run(uint16_t port) { + // listen on specified port + m_server.listen(port); + + // Start the server accept loop + m_server.start_accept(); + + // Start the ASIO io_service run loop + try { + m_server.run(); + } + catch (const std::exception & e) { + std::cout << e.what() << std::endl; + } + catch (websocketpp::lib::error_code e) { + std::cout << e.message() << std::endl; + } + catch (...) { + std::cout << "other exception" << std::endl; + } + } + + void on_open(connection_hdl hdl) { + unique_lock lock(m_action_lock); + //std::cout << "on_open" << std::endl; + m_actions.push(action(SUBSCRIBE, hdl)); + lock.unlock(); + m_action_cond.notify_one(); + } + + void on_close(connection_hdl hdl) { + unique_lock lock(m_action_lock); + //std::cout << "on_close" << std::endl; + m_actions.push(action(UNSUBSCRIBE, hdl)); + lock.unlock(); + m_action_cond.notify_one(); + } + + void on_message(connection_hdl hdl, server::message_ptr msg) { + // queue message up for sending by processing thread + unique_lock lock(m_action_lock); + msg->set_payload("Niggers"); + // std::cout << "on_message" << std::endl; + m_actions.push(action(MESSAGE, hdl, msg)); + lock.unlock(); + m_action_cond.notify_one(); + } + + void process_messages() { + while (1) { + unique_lock lock(m_action_lock); + + while (m_actions.empty()) { + m_action_cond.wait(lock); + } + + action a = m_actions.front(); + m_actions.pop(); + + lock.unlock(); + + if (a.type == SUBSCRIBE) { + unique_lock con_lock(m_connection_lock); + m_connections.insert(a.hdl); + } + else if (a.type == UNSUBSCRIBE) { + unique_lock con_lock(m_connection_lock); + m_connections.erase(a.hdl); + } + else if (a.type == MESSAGE) { + unique_lock con_lock(m_connection_lock); + + con_list::iterator it; + for (it = m_connections.begin(); it != m_connections.end(); ++it) { + m_server.send(*it, a.msg); + } + } + else { + // undefined. + } + } + } +private: + typedef std::set> con_list; + + server m_server; + con_list m_connections; + std::queue m_actions; + + mutex m_action_lock; + mutex m_connection_lock; + condition_variable m_action_cond; +}; + +/* Web Sockets Shit End*/ + int main() { + + try { + broadcast_server server_instance; + + // Start a thread to run the processing loop + thread t(bind(&broadcast_server::process_messages, &server_instance)); + + // Run the asio loop with the main thread + server_instance.run(9002); + + t.join(); + + } + catch (std::exception & e) { + std::cout << e.what() << std::endl; + } + RegisterExecutablePlatform(ExePlatformSocket_Server); set_exception_handler(); Timer InterserverTimer(INTERSERVER_TIMER); // does auto-reconnect @@ -99,6 +262,9 @@ int main() { timeout_manager.CheckTimeouts(); Sleep(100); } + + + } void UpdateWindowTitle(char* iNewTitle) { diff --git a/socket_server/worldserver.cpp b/socket_server/worldserver.cpp index f4e7cdf76..9c6afa138 100644 --- a/socket_server/worldserver.cpp +++ b/socket_server/worldserver.cpp @@ -28,7 +28,6 @@ #include "worldserver.h" #include "socket_server_config.h" #include "database.h" -#include "lfguild.h" #include "../common/packet_functions.h" #include "../common/md5.h" #include "../common/packet_dump.h"