diff --git a/CMakeLists.txt b/CMakeLists.txt index 910241d4..1329ed2e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -36,11 +36,11 @@ add_subdirectory( "src/common" ) add_subdirectory( "src/servers" ) #add_subdirectory( "src/dbm" ) -add_subdirectory( "src/tools/exd_common_gen" ) -add_subdirectory( "src/tools/exd_struct_gen" ) -add_subdirectory( "src/tools/exd_struct_test" ) -add_subdirectory( "src/tools/quest_parser" ) -add_subdirectory( "src/tools/discovery_parser" ) -add_subdirectory( "src/tools/mob_parse" ) +#add_subdirectory( "src/tools/exd_common_gen" ) +#add_subdirectory( "src/tools/exd_struct_gen" ) +#add_subdirectory( "src/tools/exd_struct_test" ) +#add_subdirectory( "src/tools/quest_parser" ) +#add_subdirectory( "src/tools/discovery_parser" ) +#add_subdirectory( "src/tools/mob_parse" ) #add_subdirectory("src/tools/pcb_reader") #add_subdirectory("src/tools/event_object_parser") diff --git a/src/servers/sapphire_api/main.cpp b/src/servers/sapphire_api/main.cpp index baf1f56b..5d627b64 100644 --- a/src/servers/sapphire_api/main.cpp +++ b/src/servers/sapphire_api/main.cpp @@ -487,7 +487,12 @@ void checkSession( shared_ptr< HttpServer::Response > response, shared_ptr< Http } else { - std::string json_string = "{\"result\":\"" + std::to_string( result ) + "\"}"; + std::string json_string = nlohmann::json( { + { "result", result }, + { "result2", "penis" }, + { "result3", "wtf" } + } ).dump() + ; *response << buildHttpResponse( 200, json_string, JSON ); } } diff --git a/src/servers/sapphire_lobby/RestConnector.cpp b/src/servers/sapphire_lobby/RestConnector.cpp index ac1727b1..4f8ac0a9 100644 --- a/src/servers/sapphire_lobby/RestConnector.cpp +++ b/src/servers/sapphire_lobby/RestConnector.cpp @@ -57,7 +57,7 @@ Core::LobbySessionPtr Core::Network::RestConnector::getSession( char* sId ) try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { @@ -99,7 +99,7 @@ bool Core::Network::RestConnector::checkNameTaken( std::string name ) try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { @@ -133,7 +133,7 @@ uint32_t Core::Network::RestConnector::getNextCharId() try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { @@ -172,7 +172,7 @@ uint64_t Core::Network::RestConnector::getNextContentId() try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { @@ -213,7 +213,7 @@ CharList Core::Network::RestConnector::getCharList( char* sId ) try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { @@ -230,10 +230,11 @@ CharList Core::Network::RestConnector::getCharList( char* sId ) { g_log.debug( child["contentId"] ); //std::string, uint32_t, uint64_t, std::string - list.push_back( std::make_tuple( child["name"].get< std::string >() ), - child["charId"].get< uint32_t >(), - child["contentId"].get< uint64_t >(), - child["infoJson"].get< std::string >() ); + list.push_back( { child["name"].get< std::string >(), + child["charId"].get< uint32_t >(), + child["contentId"].get< uint64_t >(), + child["infoJson"].get< std::string >() + } ); } return list; @@ -266,7 +267,7 @@ bool Core::Network::RestConnector::deleteCharacter( char* sId, std::string name auto json = nlohmann::json(); try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { @@ -303,7 +304,7 @@ int Core::Network::RestConnector::createCharacter( char* sId, std::string name, try { - json.parse( content ); + json = json.parse( content ); } catch( std::exception& e ) { diff --git a/src/servers/sapphire_lobby/client_http.hpp b/src/servers/sapphire_lobby/client_http.hpp index a9518d30..dfca7326 100644 --- a/src/servers/sapphire_lobby/client_http.hpp +++ b/src/servers/sapphire_lobby/client_http.hpp @@ -4,414 +4,419 @@ #include #include + #include #include #include #include #include -#include + +#ifndef CASE_INSENSITIVE_EQUALS_AND_HASH +#define CASE_INSENSITIVE_EQUALS_AND_HASH class case_insensitive_equals { public: - bool operator()( const std::string &key1, const std::string &key2 ) const { - return Core::Util::toLowerCopy( key1 ) == Core::Util::toLowerCopy( key2 ); - } + bool operator()(const std::string &key1, const std::string &key2) const { + return Core::Util::toLowerCopy( key1 ) == Core::Util::toLowerCopy( key2 ); + } }; class case_insensitive_hash { public: - size_t operator()( const std::string &key ) const { - std::size_t seed = 0; - for( auto &c : key ) - Core::Util::hashCombine< char >( seed, std::tolower( c ) ); - return seed; - } + size_t operator()( const std::string &key ) const + { + std::size_t seed=0; + for( auto &c : key ) + Core::Util::hashCombine< char >( seed, std::tolower( c ) ); + return seed; + } }; +#endif namespace SimpleWeb { - template - class Client; + template + class Client; + + template + class ClientBase { + public: + virtual ~ClientBase() {} - template - class ClientBase { - public: - virtual ~ClientBase() {} + class Response { + friend class ClientBase; + friend class Client; + public: + std::string http_version, status_code; - class Response { - friend class ClientBase; - friend class Client; - public: - std::string http_version, status_code; + std::istream content; - std::istream content; + std::unordered_multimap header; + + private: + asio::streambuf content_buffer; + + Response(): content(&content_buffer) {} + }; + + class Config { + friend class ClientBase; + private: + Config() {} + public: + /// Set timeout on requests in seconds. Default value: 0 (no timeout). + size_t timeout=0; + /// Set proxy server (server:port) + std::string proxy_server; + }; + + /// Set before calling request + Config config; + + std::shared_ptr request(const std::string& request_type, const std::string& path="/", std::string_view content="", + const std::map& header=std::map()) { + auto corrected_path=path; + if(corrected_path=="") + corrected_path="/"; + if(!config.proxy_server.empty() && std::is_same::value) + corrected_path="http://"+host+':'+std::to_string(port)+corrected_path; + + asio::streambuf write_buffer; + std::ostream write_stream(&write_buffer); + write_stream << request_type << " " << corrected_path << " HTTP/1.1\r\n"; + write_stream << "Host: " << host << "\r\n"; + for(auto& h: header) { + write_stream << h.first << ": " << h.second << "\r\n"; + } + if(content.size()>0) + write_stream << "Content-Length: " << content.size() << "\r\n"; + write_stream << "\r\n"; + + connect(); + + auto timer=get_timeout_timer(); + asio::async_write(*socket, write_buffer, + [this, &content, timer](const std::error_code &ec, size_t /*bytes_transferred*/) { + if(timer) + timer->cancel(); + if(!ec) { + if(!content.empty()) { + auto timer=get_timeout_timer(); + asio::async_write(*socket, asio::buffer(content.data(), content.size()), + [this, timer](const std::error_code &ec, size_t /*bytes_transferred*/) { + if(timer) + timer->cancel(); + if(ec) { + std::lock_guard lock(socket_mutex); + this->socket=nullptr; + throw std::system_error(ec); + } + }); + } + } + else { + std::lock_guard lock(socket_mutex); + socket=nullptr; + throw std::system_error(ec); + } + }); + io_service.reset(); + io_service.run(); + + return request_read(); + } + + std::shared_ptr request(const std::string& request_type, const std::string& path, std::iostream& content, + const std::map& header=std::map()) { + auto corrected_path=path; + if(corrected_path=="") + corrected_path="/"; + if(!config.proxy_server.empty() && std::is_same::value) + corrected_path="http://"+host+':'+std::to_string(port)+corrected_path; + + content.seekp(0, std::ios::end); + auto content_length=content.tellp(); + content.seekp(0, std::ios::beg); + + asio::streambuf write_buffer; + std::ostream write_stream(&write_buffer); + write_stream << request_type << " " << corrected_path << " HTTP/1.1\r\n"; + write_stream << "Host: " << host << "\r\n"; + for(auto& h: header) { + write_stream << h.first << ": " << h.second << "\r\n"; + } + if(content_length>0) + write_stream << "Content-Length: " << content_length << "\r\n"; + write_stream << "\r\n"; + if(content_length>0) + write_stream << content.rdbuf(); + + connect(); + + auto timer=get_timeout_timer(); + asio::async_write(*socket, write_buffer, + [this, timer](const std::error_code &ec, size_t /*bytes_transferred*/) { + if(timer) + timer->cancel(); + if(ec) { + std::lock_guard lock(socket_mutex); + socket=nullptr; + throw std::system_error(ec); + } + }); + io_service.reset(); + io_service.run(); + + return request_read(); + } + + void close() { + std::lock_guard lock(socket_mutex); + if(socket) { + std::error_code ec; + socket->lowest_layer().shutdown(asio::ip::tcp::socket::shutdown_both, ec); + socket->lowest_layer().close(); + } + } + + protected: + asio::io_service io_service; + asio::ip::tcp::resolver resolver; + + std::unique_ptr socket; + std::mutex socket_mutex; + + std::string host; + unsigned short port; + + ClientBase(const std::string& host_port, unsigned short default_port) : resolver(io_service) { + auto parsed_host_port=parse_host_port(host_port, default_port); + host=parsed_host_port.first; + port=parsed_host_port.second; + } + + std::pair parse_host_port(const std::string &host_port, unsigned short default_port) { + std::pair parsed_host_port; + size_t host_end=host_port.find(':'); + if(host_end==std::string::npos) { + parsed_host_port.first=host_port; + parsed_host_port.second=default_port; + } + else { + parsed_host_port.first=host_port.substr(0, host_end); + parsed_host_port.second=static_cast(stoul(host_port.substr(host_end+1))); + } + return parsed_host_port; + } + + virtual void connect()=0; + + std::shared_ptr< asio::basic_waitable_timer< std::chrono::steady_clock > > get_timeout_timer() { + if(config.timeout==0) + return nullptr; + + auto timer=std::make_shared< asio::basic_waitable_timer< std::chrono::steady_clock > >(io_service); + timer->expires_from_now( std::chrono::seconds( config.timeout ) ); + timer->async_wait([this](const std::error_code& ec) { + if(!ec) { + close(); + } + }); + return timer; + } + + void parse_response_header(const std::shared_ptr &response) const { + std::string line; + getline(response->content, line); + size_t version_end=line.find(' '); + if(version_end!=std::string::npos) { + if(5http_version=line.substr(5, version_end-5); + if((version_end+1)status_code=line.substr(version_end+1, line.size()-(version_end+1)-1); - std::unordered_multimap header; + getline(response->content, line); + size_t param_end; + while((param_end=line.find(':'))!=std::string::npos) { + size_t value_start=param_end+1; + if((value_start)header.insert(std::make_pair(line.substr(0, param_end), line.substr(value_start, line.size()-value_start-1))); + } - private: - asio::streambuf content_buffer; - - Response() : content( &content_buffer ) {} - }; - - class Config { - friend class ClientBase; - private: - Config() {} - public: - /// Set timeout on requests in seconds. Default value: 0 (no timeout). - size_t timeout = 0; - /// Set proxy server (server:port) - std::string proxy_server; - }; - - /// Set before calling request - Config config; - - std::shared_ptr request( const std::string& request_type, const std::string& path = "/", std::string_view content = "", - const std::map& header = std::map() ) { - auto corrected_path = path; - if( corrected_path == "" ) - corrected_path = "/"; - if( !config.proxy_server.empty() && std::is_same::value ) - corrected_path = "http://" + host + ':' + std::to_string( port ) + corrected_path; - - asio::streambuf write_buffer; - std::ostream write_stream( &write_buffer ); - write_stream << request_type << " " << corrected_path << " HTTP/1.1\r\n"; - write_stream << "Host: " << host << "\r\n"; - for( auto& h : header ) { - write_stream << h.first << ": " << h.second << "\r\n"; - } - if( content.size()>0 ) - write_stream << "Content-Length: " << content.size() << "\r\n"; - write_stream << "\r\n"; - - connect(); - - auto timer = get_timeout_timer(); - asio::async_write( *socket, write_buffer, - [this, &content, timer]( const std::error_code &ec, size_t /*bytes_transferred*/ ) { - if( timer ) - timer->cancel(); - if( !ec ) { - if( !content.empty() ) { - auto timer = get_timeout_timer(); - asio::async_write( *socket, asio::buffer( content.data(), content.size() ), - [this, timer]( const std::error_code &ec, size_t /*bytes_transferred*/ ) { - if( timer ) - timer->cancel(); - if( ec ) { - std::lock_guard lock( socket_mutex ); - this->socket = nullptr; - throw std::system_error( ec ); - } - } ); - } - } - else { - std::lock_guard lock( socket_mutex ); - socket = nullptr; - throw std::system_error( ec ); - } - } ); - io_service.reset(); - io_service.run(); - - return request_read(); - } - - std::shared_ptr request( const std::string& request_type, const std::string& path, std::iostream& content, - const std::map& header = std::map() ) { - auto corrected_path = path; - if( corrected_path == "" ) - corrected_path = "/"; - if( !config.proxy_server.empty() && std::is_same::value ) - corrected_path = "http://" + host + ':' + std::to_string( port ) + corrected_path; - - content.seekp( 0, std::ios::end ); - auto content_length = content.tellp(); - content.seekp( 0, std::ios::beg ); - - asio::streambuf write_buffer; - std::ostream write_stream( &write_buffer ); - write_stream << request_type << " " << corrected_path << " HTTP/1.1\r\n"; - write_stream << "Host: " << host << "\r\n"; - for( auto& h : header ) { - write_stream << h.first << ": " << h.second << "\r\n"; - } - if( content_length>0 ) - write_stream << "Content-Length: " << content_length << "\r\n"; - write_stream << "\r\n"; - if( content_length>0 ) - write_stream << content.rdbuf(); - - connect(); - - auto timer = get_timeout_timer(); - asio::async_write( *socket, write_buffer, - [this, timer]( const std::error_code &ec, size_t /*bytes_transferred*/ ) { - if( timer ) - timer->cancel(); - if( ec ) { - std::lock_guard lock( socket_mutex ); - socket = nullptr; - throw std::system_error( ec ); - } - } ); - io_service.reset(); - io_service.run(); - - return request_read(); - } - - void close() { - std::lock_guard lock( socket_mutex ); - if( socket ) { - std::error_code ec; - socket->lowest_layer().shutdown( asio::ip::tcp::socket::shutdown_both, ec ); - socket->lowest_layer().close(); - } - } - - protected: - asio::io_service io_service; - asio::ip::tcp::resolver resolver; - - std::unique_ptr socket; - std::mutex socket_mutex; - - std::string host; - unsigned short port; - - ClientBase( const std::string& host_port, unsigned short default_port ) : resolver( io_service ) { - auto parsed_host_port = parse_host_port( host_port, default_port ); - host = parsed_host_port.first; - port = parsed_host_port.second; - } - - std::pair parse_host_port( const std::string &host_port, unsigned short default_port ) { - std::pair parsed_host_port; - size_t host_end = host_port.find( ':' ); - if( host_end == std::string::npos ) { - parsed_host_port.first = host_port; - parsed_host_port.second = default_port; - } - else { - parsed_host_port.first = host_port.substr( 0, host_end ); - parsed_host_port.second = static_cast( stoul( host_port.substr( host_end + 1 ) ) ); - } - return parsed_host_port; - } - - virtual void connect() = 0; - - std::shared_ptr< asio::deadline_timer > get_timeout_timer() { - if( config.timeout == 0 ) - return nullptr; - - auto timer = std::make_shared< asio::deadline_timer >( io_service ); - timer->expires_from_now( std::chrono::seconds( config.timeout ) ); - timer->async_wait( [this]( const std::error_code& ec ) { - if( !ec ) { - close(); - } - } ); - return timer; - } - - void parse_response_header( const std::shared_ptr &response ) const { - std::string line; - getline( response->content, line ); - size_t version_end = line.find( ' ' ); - if( version_end != std::string::npos ) { - if( 5http_version = line.substr( 5, version_end - 5 ); - if( ( version_end + 1 )status_code = line.substr( version_end + 1, line.size() - ( version_end + 1 ) - 1 ); - - getline( response->content, line ); - size_t param_end; - while( ( param_end = line.find( ':' ) ) != std::string::npos ) { - size_t value_start = param_end + 1; - if( ( value_start )header.insert( std::make_pair( line.substr( 0, param_end ), line.substr( value_start, line.size() - value_start - 1 ) ) ); - } - - getline( response->content, line ); - } - } - } - - std::shared_ptr request_read() { - std::shared_ptr response( new Response() ); - - asio::streambuf chunked_streambuf; - - auto timer = get_timeout_timer(); - asio::async_read_until( *socket, response->content_buffer, "\r\n\r\n", - [this, &response, &chunked_streambuf, timer]( const std::error_code& ec, size_t bytes_transferred ) { - if( timer ) - timer->cancel(); - if( !ec ) { - size_t num_additional_bytes = response->content_buffer.size() - bytes_transferred; - - parse_response_header( response ); - - auto header_it = response->header.find( "Content-Length" ); - if( header_it != response->header.end() ) { - auto content_length = stoull( header_it->second ); - if( content_length>num_additional_bytes ) { - auto timer = get_timeout_timer(); - asio::async_read( *socket, response->content_buffer, - asio::transfer_exactly( static_cast< size_t >( content_length - num_additional_bytes ) ), - [this, timer]( const std::error_code& ec, size_t /*bytes_transferred*/ ) { - if( timer ) - timer->cancel(); - if( ec ) { - std::lock_guard lock( socket_mutex ); - this->socket = nullptr; - throw std::system_error( ec ); - } - } ); - } - } - else if( ( header_it = response->header.find( "Transfer-Encoding" ) ) != response->header.end() && header_it->second == "chunked" ) { - request_read_chunked( response, chunked_streambuf ); - } - } - else { - std::lock_guard lock( socket_mutex ); - socket = nullptr; - throw std::system_error( ec ); - } - } ); - io_service.reset(); - io_service.run(); - - return response; - } - - void request_read_chunked( const std::shared_ptr &response, asio::streambuf &streambuf ) { - auto timer = get_timeout_timer(); - asio::async_read_until( *socket, response->content_buffer, "\r\n", - [this, &response, &streambuf, timer]( const std::error_code& ec, size_t bytes_transferred ) { - if( timer ) - timer->cancel(); - if( !ec ) { - std::string line; - getline( response->content, line ); - bytes_transferred -= line.size() + 1; - line.pop_back(); - std::streamsize length = stol( line, 0, 16 ); - - auto num_additional_bytes = response->content_buffer.size() - bytes_transferred; - - auto post_process = [this, &response, &streambuf, length] { - std::ostream stream( &streambuf ); - if( length>0 ) { - std::vector buffer( static_cast( length ) ); - response->content.read( &buffer[0], length ); - stream.write( &buffer[0], length ); - } - - //Remove "\r\n" - response->content.get(); - response->content.get(); - - if( length>0 ) - request_read_chunked( response, streambuf ); - else { - std::ostream response_stream( &response->content_buffer ); - response_stream << stream.rdbuf(); - } - }; - - if( ( 2 + length )>num_additional_bytes ) { - auto timer = get_timeout_timer(); - asio::async_read( *socket, response->content_buffer, - asio::transfer_exactly( static_cast< size_t >( 2 + length - num_additional_bytes ) ), - [this, post_process, timer]( const std::error_code& ec, size_t /*bytes_transferred*/ ) { - if( timer ) - timer->cancel(); - if( !ec ) { - post_process(); - } - else { - std::lock_guard lock( socket_mutex ); - this->socket = nullptr; - throw std::system_error( ec ); - } - } ); - } - else - post_process(); - } - else { - std::lock_guard lock( socket_mutex ); - socket = nullptr; - throw std::system_error( ec ); - } - } ); - } - }; - - template - class Client : public ClientBase {}; - - typedef asio::ip::tcp::socket HTTP; - - template<> - class Client : public ClientBase { - public: - Client( const std::string& server_port_path ) : ClientBase::ClientBase( server_port_path, 80 ) {} - - protected: - void connect() { - if( !socket || !socket->is_open() ) { - std::unique_ptr query; - if( config.proxy_server.empty() ) - query = std::unique_ptr( new asio::ip::tcp::resolver::query( host, std::to_string( port ) ) ); - else { - auto proxy_host_port = parse_host_port( config.proxy_server, 8080 ); - query = std::unique_ptr( new asio::ip::tcp::resolver::query( proxy_host_port.first, std::to_string( proxy_host_port.second ) ) ); - } - resolver.async_resolve( *query, [this]( const std::error_code &ec, - asio::ip::tcp::resolver::iterator it ) { - if( !ec ) { - { - std::lock_guard lock( socket_mutex ); - socket = std::unique_ptr( new HTTP( io_service ) ); - } - - auto timer = get_timeout_timer(); - asio::async_connect( *socket, it, [this, timer] - ( const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/ ) { - if( timer ) - timer->cancel(); - if( !ec ) { - asio::ip::tcp::no_delay option( true ); - this->socket->set_option( option ); - } - else { - std::lock_guard lock( socket_mutex ); - this->socket = nullptr; - throw std::system_error( ec ); - } - } ); - } - else { - std::lock_guard lock( socket_mutex ); - socket = nullptr; - throw std::system_error( ec ); - } - } ); - io_service.reset(); - io_service.run(); - } - } - }; + getline(response->content, line); + } + } + } + + std::shared_ptr request_read() { + std::shared_ptr response(new Response()); + + asio::streambuf chunked_streambuf; + + auto timer=get_timeout_timer(); + asio::async_read_until(*socket, response->content_buffer, "\r\n\r\n", + [this, &response, &chunked_streambuf, timer](const std::error_code& ec, size_t bytes_transferred) { + if(timer) + timer->cancel(); + if(!ec) { + size_t num_additional_bytes=response->content_buffer.size()-bytes_transferred; + + parse_response_header(response); + + auto header_it=response->header.find("Content-Length"); + if(header_it!=response->header.end()) { + auto content_length=stoull(header_it->second); + if(content_length>num_additional_bytes) { + auto timer=get_timeout_timer(); + asio::async_read(*socket, response->content_buffer, + asio::transfer_exactly(content_length-num_additional_bytes), + [this, timer](const std::error_code& ec, size_t /*bytes_transferred*/) { + if(timer) + timer->cancel(); + if(ec) { + std::lock_guard lock(socket_mutex); + this->socket=nullptr; + throw std::system_error(ec); + } + }); + } + } + else if((header_it=response->header.find("Transfer-Encoding"))!=response->header.end() && header_it->second=="chunked") { + request_read_chunked(response, chunked_streambuf); + } + } + else { + std::lock_guard lock(socket_mutex); + socket=nullptr; + throw std::system_error(ec); + } + }); + io_service.reset(); + io_service.run(); + + return response; + } + + void request_read_chunked(const std::shared_ptr &response, asio::streambuf &streambuf) { + auto timer=get_timeout_timer(); + asio::async_read_until(*socket, response->content_buffer, "\r\n", + [this, &response, &streambuf, timer](const std::error_code& ec, size_t bytes_transferred) { + if(timer) + timer->cancel(); + if(!ec) { + std::string line; + getline(response->content, line); + bytes_transferred-=line.size()+1; + line.pop_back(); + std::streamsize length=stol(line, 0, 16); + + auto num_additional_bytes=static_cast(response->content_buffer.size()-bytes_transferred); + + auto post_process=[this, &response, &streambuf, length] { + std::ostream stream(&streambuf); + if(length>0) { + std::vector buffer(static_cast(length)); + response->content.read(&buffer[0], length); + stream.write(&buffer[0], length); + } + + //Remove "\r\n" + response->content.get(); + response->content.get(); + + if(length>0) + request_read_chunked(response, streambuf); + else { + std::ostream response_stream(&response->content_buffer); + response_stream << stream.rdbuf(); + } + }; + + if((2+length)>num_additional_bytes) { + auto timer=get_timeout_timer(); + asio::async_read(*socket, response->content_buffer, + asio::transfer_exactly(2+length-num_additional_bytes), + [this, post_process, timer](const std::error_code& ec, size_t /*bytes_transferred*/) { + if(timer) + timer->cancel(); + if(!ec) { + post_process(); + } + else { + std::lock_guard lock(socket_mutex); + this->socket=nullptr; + throw std::system_error(ec); + } + }); + } + else + post_process(); + } + else { + std::lock_guard lock(socket_mutex); + socket=nullptr; + throw std::system_error(ec); + } + }); + } + }; + + template + class Client : public ClientBase {}; + + typedef asio::ip::tcp::socket HTTP; + + template<> + class Client : public ClientBase { + public: + Client(const std::string& server_port_path) : ClientBase::ClientBase(server_port_path, 80) {} + + protected: + void connect() { + if(!socket || !socket->is_open()) { + std::unique_ptr query; + if(config.proxy_server.empty()) + query=std::unique_ptr(new asio::ip::tcp::resolver::query(host, std::to_string(port))); + else { + auto proxy_host_port=parse_host_port(config.proxy_server, 8080); + query=std::unique_ptr(new asio::ip::tcp::resolver::query(proxy_host_port.first, std::to_string(proxy_host_port.second))); + } + resolver.async_resolve(*query, [this](const std::error_code &ec, + asio::ip::tcp::resolver::iterator it){ + if(!ec) { + { + std::lock_guard lock(socket_mutex); + socket=std::unique_ptr(new HTTP(io_service)); + } + + auto timer=get_timeout_timer(); + asio::async_connect(*socket, it, [this, timer] + (const std::error_code &ec, asio::ip::tcp::resolver::iterator /*it*/){ + if(timer) + timer->cancel(); + if(!ec) { + asio::ip::tcp::no_delay option(true); + this->socket->set_option(option); + } + else { + std::lock_guard lock(socket_mutex); + this->socket=nullptr; + throw std::system_error(ec); + } + }); + } + else { + std::lock_guard lock(socket_mutex); + socket=nullptr; + throw std::system_error(ec); + } + }); + io_service.reset(); + io_service.run(); + } + } + }; } #endif /* CLIENT_HTTP_HPP */ diff --git a/src/servers/sapphire_zone/Script/ScriptLoader.cpp b/src/servers/sapphire_zone/Script/ScriptLoader.cpp index 9805072d..b4db026b 100644 --- a/src/servers/sapphire_zone/Script/ScriptLoader.cpp +++ b/src/servers/sapphire_zone/Script/ScriptLoader.cpp @@ -162,7 +162,7 @@ bool Core::Scripting::ScriptLoader::isModuleLoaded( std::string name ) for( auto it = m_scriptMap.begin(); it != m_scriptMap.end(); ++it ) { - if( Util::toLowerCopy( it->second->library_name) == Util::toLowerCopy( name ) ) + if( Util::toLowerCopy( it->second->library_name ) == Util::toLowerCopy( name ) ) return true; }