diff options
author | Nayd <dnpd.dd@gmail.com> | 2014-12-20 22:58:21 +0000 |
---|---|---|
committer | Nayd <dnpd.dd@gmail.com> | 2014-12-20 22:58:21 +0000 |
commit | 560e531da7113cf54f4ab5c8437925ece4b4a616 (patch) | |
tree | 146f850b980e09ba5b73088534add29bbcfac184 /src/tools/connection_patcher/Program.cpp | |
parent | 54f5582871dd01398f2ece516436b49dc80f077f (diff) |
Tools/ConnectionPatcher: Restore previous functionally that downloaded modules if they did not exist
Diffstat (limited to 'src/tools/connection_patcher/Program.cpp')
-rw-r--r-- | src/tools/connection_patcher/Program.cpp | 90 |
1 files changed, 86 insertions, 4 deletions
diff --git a/src/tools/connection_patcher/Program.cpp b/src/tools/connection_patcher/Program.cpp index 8c9060dc45d..cd942531529 100644 --- a/src/tools/connection_patcher/Program.cpp +++ b/src/tools/connection_patcher/Program.cpp @@ -31,11 +31,16 @@ #include <boost/filesystem.hpp> #include <iostream> +#include <fstream> +#include <boost/asio.hpp> #if PLATFORM == PLATFORM_WINDOWS #include <Shlobj.h> #endif +using namespace boost::asio; +using boost::asio::ip::tcp; + namespace Connection_Patcher { namespace @@ -69,14 +74,24 @@ namespace Connection_Patcher } template<typename PATCH, typename PATTERN> - void do_module(std::string moduleName, boost::filesystem::path path) + void do_module(const std::string& moduleName, const boost::filesystem::path& path) { boost::filesystem::path const modulePath (path / std::string(&moduleName[0], 2) / std::string(&moduleName[2], 2)); boost::filesystem::path const module(modulePath / moduleName); - if (!boost::filesystem::exists (module)) - throw std::runtime_error("base module does not exist. run client once."); + if (!boost::filesystem::exists(module)) + { + std::cout << "Base module doesn't exist, downloading it...\n"; + + if (!boost::filesystem::exists(modulePath)) + boost::filesystem::create_directories(modulePath); + + std::ofstream outFile(module.string(), std::ofstream::out | std::ofstream::binary); + GetFile("xx.depot.battle.net", 1119, "/" + moduleName, outFile); + outFile.close(); + std::cout << "Done.\n"; + } PatchModule<PATCH, PATTERN>(module, path); } @@ -131,6 +146,73 @@ namespace Connection_Patcher fs::copy_file(current, destination / current.filename()); } } + + // adapted from http://stackoverflow.com/questions/21422094/boostasio-download-image-file-from-server + void GetFile(const std::string& serverName, int port, const std::string& getCommand, std::ostream& out) + { + boost::asio::io_service io_service; + + // Get a list of endpoints corresponding to the server name. + tcp::resolver resolver(io_service); + tcp::resolver::query query(serverName, std::to_string(port)); + tcp::resolver::iterator endpoint_iterator = resolver.resolve(query); + tcp::resolver::iterator end; + + // Try each endpoint until we successfully establish a connection. + tcp::socket socket(io_service); + boost::system::error_code error = boost::asio::error::host_not_found; + while (error && endpoint_iterator != end) + { + socket.close(); + socket.connect(*endpoint_iterator++, error); + } + + boost::asio::streambuf request; + std::ostream request_stream(&request); + + request_stream << "GET " << getCommand << " HTTP/1.0\r\n"; + request_stream << "Host: " << serverName << ':' << port << "\r\n"; + request_stream << "Accept: */*\r\n"; + request_stream << "Connection: close\r\n\r\n"; + + // Send the request. + boost::asio::write(socket, request); + + // Read the response status line. + boost::asio::streambuf response; + boost::asio::read_until(socket, response, "\r\n"); + + // Check that response is OK. + std::istream response_stream(&response); + std::string http_version; + response_stream >> http_version; + unsigned int status_code; + response_stream >> status_code; + std::string status_message; + std::getline(response_stream, status_message); + + + // Read the response headers, which are terminated by a blank line. + boost::asio::read_until(socket, response, "\r\n\r\n"); + + // Process the response headers. + std::string header; + while (std::getline(response_stream, header) && header != "\r") + { + } + + // Write whatever content we already have to output. + if (response.size() > 0) + { + out << &response; + } + + // Read until EOF, writing data to output as we go. + while (boost::asio::read(socket, response, boost::asio::transfer_at_least(1), error)) + { + out << &response; + } + } } int main(int argc, char** argv) @@ -146,7 +228,7 @@ int main(int argc, char** argv) std::string renamed_binary_path(binary_path); - wchar_t* commonAppData (nullptr); + wchar_t* commonAppData(nullptr); #if PLATFORM == PLATFORM_WINDOWS SHGetKnownFolderPath(FOLDERID_ProgramData, 0, NULL, &commonAppData); #endif |