| 
									
										
										
										
											2024-06-04 19:47:14 +08:00
										 |  |  | #pragma once
 | 
					
						
							|  |  |  | #include <iostream>
 | 
					
						
							|  |  |  | #include <ctime>
 | 
					
						
							|  |  |  | #include <sstream>
 | 
					
						
							|  |  |  | #include <chrono>
 | 
					
						
							|  |  |  | #include <asio.hpp>
 | 
					
						
							|  |  |  | #include <asio/ssl.hpp>
 | 
					
						
							| 
									
										
										
										
											2024-06-24 22:52:14 +08:00
										 |  |  | #include <asio/basic_socket_streambuf.hpp>
 | 
					
						
							| 
									
										
										
										
											2024-06-04 19:47:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | // 单个字符解密
 | 
					
						
							|  |  |  | char CutcodeChar(char c, int key, int key2) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     char a = (((c - 1) ^ key) ^ key2) - key; | 
					
						
							|  |  |  |     return a; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 解密
 | 
					
						
							|  |  |  | void Cutecode(char *pstr, int *pkey, int len) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     if (len == -1) | 
					
						
							|  |  |  |         len = strlen(pstr); | 
					
						
							|  |  |  |     for (int i = 0; i < len; i++) | 
					
						
							|  |  |  |         *(pstr + i) = CutcodeChar(*(pstr + i), pkey[i % 5], pkey[(i + 18) % 5]); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 加密函数
 | 
					
						
							|  |  |  | static std::string r_encryptDecrypt(const std::string &input, const std::string &key) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     std::string output = input; | 
					
						
							|  |  |  |     for (size_t i = 0; i < input.size(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         output[i] = input[i] ^ key[i % key.size()]; // 使用异或运算进行加密
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     return output; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static std::string ReqScriptUrl(std::string ce) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     asio::io_context io_context; | 
					
						
							|  |  |  |     asio::ssl::context ctx(asio::ssl::context::tlsv12_client); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asio::ssl::stream<asio::ip::tcp::socket> socket(io_context, ctx); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asio::ip::tcp::resolver resolver(io_context); | 
					
						
							|  |  |  |     auto endpoints = resolver.resolve("www.rindro.cn", "https"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asio::connect(socket.lowest_layer(), endpoints); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     socket.handshake(asio::ssl::stream_base::handshake_type::client); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string post_data = "s=" + ce; | 
					
						
							|  |  |  |     std::string request = "POST /c/user/getServiceUrl HTTP/1.1\r\n"; | 
					
						
							|  |  |  |     request += "Host: www.rindro.cn\r\n"; | 
					
						
							|  |  |  |     request += "Content-Length: " + std::to_string(post_data.size()) + "\r\n"; | 
					
						
							|  |  |  |     request += "Content-Type: application/x-www-form-urlencoded\r\n"; | 
					
						
							|  |  |  |     request += "\r\n"; | 
					
						
							|  |  |  |     request += post_data; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asio::write(socket, asio::buffer(request)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     asio::streambuf response; | 
					
						
							|  |  |  |     asio::read_until(socket, response, "\r\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::istream response_stream(&response); | 
					
						
							|  |  |  |     std::string http_version; | 
					
						
							|  |  |  |     response_stream >> http_version; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::stringstream ss; | 
					
						
							|  |  |  |     ss << &response; | 
					
						
							|  |  |  |     std::string response_data = ss.str(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return response_data; | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static std::string make_request(const std::string &host, const std::string &port, const std::string &path) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     asio::io_context io_context; | 
					
						
							|  |  |  |     tcp::resolver resolver(io_context); | 
					
						
							|  |  |  |     tcp::resolver::results_type endpoints = resolver.resolve(host, port); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     tcp::socket socket(io_context); | 
					
						
							|  |  |  |     asio::connect(socket, endpoints); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Form the request. We specify the "Connection: close" header so that the
 | 
					
						
							|  |  |  |     // server will close the socket after transmitting the response. This
 | 
					
						
							|  |  |  |     // will allow us to treat all data up until the EOF as the content.
 | 
					
						
							|  |  |  |     std::string request = "GET " + path + " HTTP/1.1\r\n"; | 
					
						
							|  |  |  |     request += "Host: " + host + "\r\n"; | 
					
						
							|  |  |  |     request += "Connection: close\r\n\r\n"; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Send the request.
 | 
					
						
							|  |  |  |     asio::write(socket, asio::buffer(request)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Read the response status line. The response streambuf will automatically
 | 
					
						
							|  |  |  |     // grow to accommodate the entire line. The growth may be limited by passing
 | 
					
						
							|  |  |  |     // a maximum size to the streambuf constructor.
 | 
					
						
							|  |  |  |     asio::streambuf response; | 
					
						
							|  |  |  |     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); | 
					
						
							|  |  |  |     if (!response_stream || http_version.substr(0, 5) != "HTTP/") | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         throw std::runtime_error("Invalid response"); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (status_code != 200) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         throw std::runtime_error("Response returned with status code " + std::to_string(status_code)); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Read the response headers, which are terminated by a blank line.
 | 
					
						
							|  |  |  |     asio::read_until(socket, response, "\r\n\r\n"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Process the response headers.
 | 
					
						
							|  |  |  |     std::string header; | 
					
						
							|  |  |  |     while (std::getline(response_stream, header) && header != "\r") | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2024-06-04 20:01:01 +08:00
										 |  |  |         // std::cout << header << "\n";
 | 
					
						
							| 
									
										
										
										
											2024-06-04 19:47:14 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-06-04 20:01:01 +08:00
										 |  |  |     // std::cout << "\n";
 | 
					
						
							| 
									
										
										
										
											2024-06-04 19:47:14 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     // Write whatever content we already have to output.
 | 
					
						
							|  |  |  |     std::ostringstream response_body; | 
					
						
							|  |  |  |     if (response.size() > 0) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         response_body << &response; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     // Read until EOF, writing data to output as we go.
 | 
					
						
							|  |  |  |     asio::error_code error; | 
					
						
							|  |  |  |     while (asio::read(socket, response, asio::transfer_at_least(1), error)) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         response_body << &response; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     if (error != asio::error::eof) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         throw asio::system_error(error); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     return response_body.str(); | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static std::string ReqScript(std::string url) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     std::vector<std::string> UrlData; | 
					
						
							|  |  |  |     Tool::Split(url, UrlData, ","); | 
					
						
							|  |  |  |     try | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::string host = UrlData[0]; | 
					
						
							|  |  |  |         std::string port = UrlData[1]; | 
					
						
							|  |  |  |         std::string path = "/" + UrlData[2]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         std::string response = make_request(host, port, path); | 
					
						
							|  |  |  |         // std::cout << "Response body:\n"
 | 
					
						
							|  |  |  |         //           << response << "\n";
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         return response; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  |     catch (std::exception &e) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         // std::cerr << "Exception: " << e.what() << "\n";
 | 
					
						
							|  |  |  |         return "null"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | static void ReqSquirrelScript(HSQUIRRELVM v) | 
					
						
							|  |  |  | { | 
					
						
							|  |  |  |     // 获取随机值
 | 
					
						
							|  |  |  |     clock_t start = clock(); | 
					
						
							|  |  |  |     double elapsed_time = double(start) / CLOCKS_PER_SEC; | 
					
						
							|  |  |  |     std::string ce = "" + std::to_string(elapsed_time); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string UrlRes = ReqScriptUrl(ce); | 
					
						
							|  |  |  |     UrlRes = UrlRes.substr(UrlRes.find("RindroXXXXXX") + 12); | 
					
						
							|  |  |  |     UrlRes = r_encryptDecrypt(UrlRes, "aesgfasdgdrshdfbtykuilhnvbcera5634%#t$"); | 
					
						
							|  |  |  |     std::vector<std::string> Buf; | 
					
						
							|  |  |  |     Tool::Split(UrlRes, Buf, "$$$$"); | 
					
						
							|  |  |  |     if (Buf[1] != ce) | 
					
						
							|  |  |  |         return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::vector<std::string> keyBuf; | 
					
						
							|  |  |  |     Tool::Split(Buf[2].substr(1, -1), keyBuf, ","); | 
					
						
							| 
									
										
										
										
											2024-06-16 20:10:51 +08:00
										 |  |  |     // std::cout << "key: " << Buf[2] << std::endl;
 | 
					
						
							| 
									
										
										
										
											2024-06-04 19:47:14 +08:00
										 |  |  |     int RealKey[5] = {}; | 
					
						
							|  |  |  |     for (size_t i = 0; i < keyBuf.size(); i++) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         RealKey[i] = (std::stoi(keyBuf[i])); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     std::string Script = ReqScript(Buf[0]); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if (Script != "null") | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         std::vector<std::string> ScriptMan; | 
					
						
							|  |  |  |         Tool::Split(Script, ScriptMan, "$$$$"); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         std::map<std::string, std::string> SquirrelFilePath; | 
					
						
							|  |  |  |         for (size_t i = 0; i < ScriptMan.size(); i += 2) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             std::string str = ScriptMan[i + 1].substr(ScriptMan[i + 1].find("[") + 1, ScriptMan[i + 1].length() - 2); | 
					
						
							|  |  |  |             std::vector<std::string> Data; | 
					
						
							|  |  |  |             Tool::Split(str, Data, ", "); | 
					
						
							|  |  |  |             size_t DDs = Data.size(); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             char *nutstr = new char[DDs + 1]; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             for (size_t s = 0; s < DDs; s++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 nutstr[s] = char(atoi(Data[s].c_str())); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             nutstr[DDs] = '\0'; | 
					
						
							|  |  |  |             Cutecode(nutstr, RealKey, DDs); // 解密
 | 
					
						
							|  |  |  |             std::string FileData(nutstr); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             // std::cout << "文件名: " << ScriptMan[i] << std::endl;
 | 
					
						
							|  |  |  |             // std::cout
 | 
					
						
							|  |  |  |             //     << "文件内容: " << FileData << std::endl;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             SquirrelFilePath[ScriptMan[i]] = FileData; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         std::map<std::string, std::string> SquirrelLastFilePath; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         for (auto it = SquirrelFilePath.begin(); it != SquirrelFilePath.end(); it++) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             std::string Sourcename = it->first; | 
					
						
							|  |  |  |             std::string ContentString = it->second; | 
					
						
							|  |  |  |             if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true))) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 sq_pushroottable(v); | 
					
						
							|  |  |  |                 sq_call(v, 1, 1, 1); | 
					
						
							|  |  |  |                 sq_pop(v, 1); | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             else | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 SquirrelLastFilePath[Sourcename] = ContentString; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         while (SquirrelLastFilePath.size() > 0) | 
					
						
							|  |  |  |         { | 
					
						
							|  |  |  |             std::map<std::string, std::string> FailMapBuffer; | 
					
						
							|  |  |  |             for (auto it = SquirrelLastFilePath.begin(); it != SquirrelLastFilePath.end(); it++) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 std::string Sourcename = it->first; | 
					
						
							|  |  |  |                 std::string ContentString = it->second; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |                 if (SQ_SUCCEEDED(sq_compilebuffer(v, (SQChar *)(ContentString.c_str()), ContentString.length(), (SQChar *)(Sourcename.c_str()), true))) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     sq_pushroottable(v); | 
					
						
							|  |  |  |                     if (SQ_FAILED(sq_call(v, 1, 1, 1))) | 
					
						
							|  |  |  |                     { | 
					
						
							|  |  |  |                         FailMapBuffer[Sourcename] = ContentString; | 
					
						
							|  |  |  |                     }; | 
					
						
							|  |  |  |                     sq_pop(v, 1); | 
					
						
							|  |  |  |                 }; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |             SquirrelLastFilePath.clear(); | 
					
						
							|  |  |  |             if (FailMapBuffer.size() > 0) | 
					
						
							|  |  |  |             { | 
					
						
							|  |  |  |                 for (auto it = FailMapBuffer.begin(); it != FailMapBuffer.end(); it++) | 
					
						
							|  |  |  |                 { | 
					
						
							|  |  |  |                     std::string Sourcename = it->first; | 
					
						
							|  |  |  |                     std::string ContentString = it->second; | 
					
						
							|  |  |  |                     SquirrelLastFilePath[Sourcename] = ContentString; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } |