From a60367caa0757420ebf4cdfab90dc414dfc27254 Mon Sep 17 00:00:00 2001 From: qingjiao <2199458175@qq.com> Date: Fri, 1 Nov 2024 16:09:31 +0800 Subject: [PATCH] V1.0 --- .idea/.name | 1 + .idea/editor.xml | 495 ++++++++++++++ .idea/misc.xml | 12 + .idea/vcs.xml | 6 + CMakeLists.txt | 37 +- ObjectVariable/Configuration.h | 373 +++++++++++ SDK/CCServlet/include/CCRequest.h | 45 +- SDK/CCServlet/include/CCResponse.h | 21 +- SDK/CCServlet/include/CCString.h | 106 --- SDK/CCServlet/include/CCWeb.h | 145 ----- SDK/CCServlet/include/CCWebServlet.h | 48 +- SDK/CCServlet/src/CCRequest.cpp | 218 ++++++- SDK/CCServlet/src/CCResponse.cpp | 247 +++++-- SDK/CCServlet/src/CCString.cpp | 308 --------- SDK/CCServlet/src/CCWeb.cpp | 743 --------------------- SDK/CCServlet/src/CCWebServlet.cpp | 461 +++++++++++-- SDK/CMakeLists.txt | 79 ++- SDK/Depend/Bin/bin/sqlite3.def | 361 ---------- SDK/Install.sh | 27 +- SDK/include/CCEpoll.h | 1 + SDK/include/CCFile.h | 13 +- SDK/include/CCJSONObject.h | 19 +- SDK/include/CCSocket.h | 62 +- SDK/include/CCThread.h | 18 +- SDK/include/CCThreadPool.h | 96 ++- SDK/include/CCVector.hpp | 100 --- SDK/src/CCEpoll.cpp | 10 +- SDK/src/CCFile.cpp | 18 +- SDK/src/CCJSONObject.cpp | 33 +- SDK/src/CCSocket.cpp | 169 +++-- SDK/src/CCThreadPool.cpp | 163 +++-- Tools/CText.h | 4 +- UI/W1/widget.cpp | 941 +++++++++++++++++++++++++++ widget.h => UI/W1/widget.h | 25 +- widget.ui => UI/W1/widget.ui | 544 ++++++++-------- UI/W2/widgetyz.cpp | 44 ++ UI/W2/widgetyz.h | 25 + UI/W2/widgetyz.ui | 174 +++++ UI/W3/widget3.cpp | 64 ++ UI/W3/widget3.h | 31 + UI/W3/widget3.ui | 119 ++++ UI/W4/csinfow4.cpp | 46 ++ UI/W4/csinfow4.h | 31 + UI/W4/csinfow4.ui | 170 +++++ widget.cpp | 668 ------------------- 45 files changed, 4219 insertions(+), 3102 deletions(-) create mode 100644 .idea/.name create mode 100644 .idea/editor.xml create mode 100644 .idea/vcs.xml create mode 100644 ObjectVariable/Configuration.h delete mode 100644 SDK/CCServlet/include/CCString.h delete mode 100644 SDK/CCServlet/include/CCWeb.h delete mode 100644 SDK/CCServlet/src/CCString.cpp delete mode 100644 SDK/CCServlet/src/CCWeb.cpp delete mode 100644 SDK/Depend/Bin/bin/sqlite3.def delete mode 100644 SDK/include/CCVector.hpp create mode 100644 UI/W1/widget.cpp rename widget.h => UI/W1/widget.h (90%) rename widget.ui => UI/W1/widget.ui (82%) create mode 100644 UI/W2/widgetyz.cpp create mode 100644 UI/W2/widgetyz.h create mode 100644 UI/W2/widgetyz.ui create mode 100644 UI/W3/widget3.cpp create mode 100644 UI/W3/widget3.h create mode 100644 UI/W3/widget3.ui create mode 100644 UI/W4/csinfow4.cpp create mode 100644 UI/W4/csinfow4.h create mode 100644 UI/W4/csinfow4.ui delete mode 100644 widget.cpp diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..2b2f3fa --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +IPBS_Station \ No newline at end of file diff --git a/.idea/editor.xml b/.idea/editor.xml new file mode 100644 index 0000000..c5f3572 --- /dev/null +++ b/.idea/editor.xml @@ -0,0 +1,495 @@ + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 79b3c94..56e425f 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,16 @@ + + + + + {} \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 720bceb..2375cc6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,10 +1,10 @@ -cmake_minimum_required(VERSION 3.5) +cmake_minimum_required(VERSION 3.27) project(IPBS_Station LANGUAGES CXX) - +#set(Qt5_DIR "I:\\QT\\5.14.2\\mingw73_64\\lib\\cmake") add_subdirectory(SDK) set(CMAKE_INCLUDE_CURRENT_DIR ON) - +set(CMAKE_EXE_LINKER_FLAGS "-static-libgcc -static-libstdc++") set(CMAKE_AUTOUIC ON) set(CMAKE_AUTOMOC ON) set(CMAKE_AUTORCC ON) @@ -28,21 +28,34 @@ find_package(Qt5 COMPONENTS Network Widgets REQUIRED) if(ANDROID) add_library(IPBS_Station SHARED - main.cpp - widget.cpp - widget.h - widget.ui + main.cpp + UI/W1/widget.cpp + UI/W1/widget.h + UI/W1/widget.ui ) else() add_executable(IPBS_Station -# WIN32 +# WIN32 main.cpp - widget.cpp - widget.h - widget.ui + UI/W1/widget.cpp + UI/W1/widget.h + UI/W1/widget.ui Res/icons.rc Tools/CText.h + UI/W2/widgetyz.cpp + UI/W2/widgetyz.h + UI/W2/widgetyz.ui + UI/W3/widget3.cpp + UI/W3/widget3.h + UI/W3/widget3.ui + ObjectVariable/Configuration.h + UI/W4/csinfow4.cpp + UI/W4/csinfow4.h + UI/W4/csinfow4.ui + UI/W5/sub_ipui.cpp + UI/W5/sub_ipui.h + UI/W5/sub_ipui.ui ) endif() -target_include_directories(IPBS_Station PUBLIC SDK) +target_include_directories(IPBS_Station PUBLIC SDK ObjectVariable UI/W1 UI UI/W2 UI/W3 UI/W4 UI/W5) target_link_libraries(IPBS_Station PRIVATE Qt5::Widgets CC_API Qt5::Network) diff --git a/ObjectVariable/Configuration.h b/ObjectVariable/Configuration.h new file mode 100644 index 0000000..6cfa141 --- /dev/null +++ b/ObjectVariable/Configuration.h @@ -0,0 +1,373 @@ +#ifndef CONFIGURATION_H +#define CONFIGURATION_H +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Tools/CText.h" +#include "CCSocket.h" +#include "CCProcess.h" + +#define SubControl_Jar "SubControl/WebSub/SpringWeb.jar" +#define SubControl_Back_Cfg "SubControl/src/main/resources/ServerSettings/ServerSettings.CText" +#define SubControl_Web_Cfg "SubControl/conf/nginx.conf" +#define Sub_Logo "SubControl/html/assets/logo-CuXNbvLG.png" +#define Sub_ImgBuffer "ImgBuffer/" + +#ifdef _WIN32 +#define SubControl_Java "SubControl/WebSub/jreWin/bin/Sub_Server.exe" +#define SubControl_Web_Exe "SubControl/Sub_Web.exe" +#define IPBS_NSSM_Exe "IPBS_NSSM.exe" +#elif __linux__ +#define SubControl_Java "SubControl/WebSub/jreWin/bin/Sub_Server" +#define SubControl_Web_Exe "SubControl/Sub_WebL" +#endif + +class Configuration +{ +private: + inline static std::mutex _mutex; +public: + Configuration() = default; + inline static CCString ExePath = CApplication::GetTheProgramDirectory() + "/"; + inline static CCString jarPath = CCFile::GetnormalizePath(ExePath + SubControl_Jar); + inline static CCString JavaPath = CCFile::GetnormalizePath(ExePath + SubControl_Java); + inline static CCString CfgPath = ExePath + SubControl_Back_Cfg; + inline static CCString WebCfgPath = ExePath + SubControl_Web_Cfg; + inline static CCString WebPath = CCFile::GetnormalizePath(ExePath + SubControl_Web_Exe); + inline static CCString IPBS_NSSMPath = CCFile::GetnormalizePath(ExePath + IPBS_NSSM_Exe); + inline static CCString CS_IP = ""; + inline static CCString CS_Port = ""; + inline static CCString Web_IP = ""; + inline static CCString Web_Port = ""; + inline static CCString Sub_IP = CCSocket::GetLocalIP()[0]; + inline static CCString Sub_Port = ""; + inline static CCString Sub_Audio_Port = ""; + inline static CCString Sub_Org = ""; + inline static CCString Language = ""; + inline static CCString State = "Close"; + inline static int OpenSleep = 20; + inline static CCString CORSEn = "false"; + inline static int FirstRun = 1; + inline static CCString Web_URL = ""; + inline static std::vector CSPortList; + inline static std::vector CSIPList; + inline static std::vector SubIPList; + inline static CCProcess WebRun,SubRun; +public: + static int GetInt(char h1, char h2) + { + int lowUnsigned = h1 & 0xFF; + int highUnsigned = h2 & 0xFF; + return (highUnsigned << 8) | lowUnsigned; + } + static void ReadConfigInit(){ + CCVar A = CText::ReadConfig(CfgPath.c_str()); + if(!A.empty()){ + CS_IP = A["C/S_IP"]; + CS_Port = A["C/S_PORT"]; + Web_IP = A["Sub_Control_IP"]; + Web_Port = A["Sub_Web_PORT"]; + Sub_IP = Web_IP; + Sub_Port = A["Sub_Control_PORT"]; + Sub_Audio_Port = A["Sub_Control_Audio_PORT"]; + Sub_Org = A["Origins"]; + Language = A["Language"]; + OpenSleep = A["OpenSleep"].to_int(); + State = A["State"]; + CORSEn = A["CORSEn"]; + FirstRun = A["FirstRun"].to_int(); + } + Configuration::Web_URL = "http://" + Web_IP + ":" + Web_Port + "/"; + } + static void ReadCSInfo(const std::function& fun = nullptr){ + CCUniqueLock lock(_mutex); + CSPortList.clear(); + CSIPList.clear(); + CCSocket UDP; + UDP.Socket(IPVX::IPV4,TORU::UDP,TYPE::DGRAM); + bool A = UDP.SetSockOpt(CCOpt::BROADCAST); + const CCString IP = Sub_IP; + bool F = UDP.Bind(IP.c_str(),0); + const char str[] = {0x55,static_cast(0xAA),0x48,0x00,0x00,0x00,0x00,0x00}; + sockaddr_in serverAddr{}; + serverAddr.sin_family = AF_INET; + serverAddr.sin_port = htons(10060); + serverAddr.sin_addr.s_addr = INADDR_BROADCAST; + UDP.SendData(str,serverAddr); + int AS = 0; + while (true){ + char buf[1024] = {0}; + CCHostInfo info; + if(UDP.isDataAvailable()){ + CCVar length = UDP.UDPRecvData(buf, 1024,&info); + if(length > 0){ + if(buf[2] == 0x48){ + int P = GetInt(buf[4],buf[5]); + CSIPList.emplace_back(info.IPAddress); + CSPortList.emplace_back(P); + } + } + else{ + if(length == -1) + { + break; + } + } + } + else{ + AS++; + CCThread::Sleep(1000 * 10); + if(AS == 10){ + break; + } + } + } + UDP.Close(); + if(fun){ + fun(); + } + } + static void ReadSub_IP(){ + SubIPList.clear(); + foreach (QHostAddress ptr , QNetworkInterface::allAddresses()) { + // 获取ipv4地址 + if (ptr.protocol() == QAbstractSocket::IPv4Protocol) { + // 过滤本地回环127.0.0.1 + if (!ptr.isLoopback()) { + CCString A = ptr.toString().toStdString(); + SubIPList.emplace_back(A); + } + } + } + } + static void CfgInit(){ + while (true){ + CCThread::Sleep(1000 * 500); + ReadSub_IP(); + if(!SubIPList.empty()){ + Sub_IP = SubIPList[0]; + break; + } + else{ + QMessageBox::StandardButton reply = QMessageBox::question(nullptr, "提示", + "未检测到合法IPV4地址,请检查网络,是否继续检测?", + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) { + continue; + } else { + Sub_IP = ""; + break; + } + } + } + while (true){ + CCThread::Sleep(1000 * 500); + ReadCSInfo(); + if(!CSIPList.empty()){ + CS_IP = CSIPList[0]; + CS_Port = CSPortList[0].to_String(); + break; + } + else{ + CS_IP = ""; + CS_Port = ""; + QMessageBox::StandardButton reply = QMessageBox::question(nullptr, "提示", + "在局域网未检测到可用的C/S服务器,请先启动C/S服务器,是否继续检测?", + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) { + continue; + } else { + CS_IP = ""; + CS_Port = ""; + break; + } + } + } + CCVar Ports = getAvailablePorts(3,5417); + Sub_Port = Ports[0].to_String(); + Sub_Audio_Port = Ports[1].to_String(); + Web_Port = Ports[2].to_String(); + Web_IP = Sub_IP; + Sub_Org = "['http://" + Sub_IP + ":" + Sub_Port + "']"; + } + static bool isPortAvailable(int port) + { + CCSocket sock; + sock.Socket(IPV4,TCP,TYPE::STREAM); + const bool F = sock.Bind("127.0.0.1", port); + try{ + sock.Close(); + } + catch (CCException& e){} + return F; + } + static std::vector getAvailablePorts(int count, int startPort = 1024, int endPort = 65535) + { + std::vector availablePorts; + for (int port = startPort; port <= endPort && availablePorts.size() < count; ++port) { + if (isPortAvailable(port)) { + availablePorts.push_back(port); + } + } + return availablePorts; + } + static void OpenSub_Server(){ + CCString cmd = "cd " + ExePath + "SubControl/" + " && "; + SubRun.AddCommand(cmd); + // cmd = "start "" " + JavaPath + " -jar " + jarPath; + cmd = JavaPath + " -jar " + jarPath; + SubRun.AddCommand(cmd); + SubRun.Start(); + } + static void CloseSub_Server(){ + // CCProcess Close; + // Close.AddCommand("taskkill /f /t /im Sub_Server.exe"); + // Close.Start(); + QProcess::startDetached("taskkill /f /t /im Sub_Server.exe"); + } + static void OpenSub_Web(){ + CCString cmd = "cd " + ExePath + "SubControl/" + " && "; + WebRun.AddCommand(cmd); + cmd = WebPath; + WebRun.AddCommand(cmd); + WebRun.Start(); + Configuration::Web_URL = "http://" + Web_IP + ":" + Web_Port + "/"; + } + static void CloseSub_Web(){ + // CCProcess Close; + // Close.AddCommand("taskkill /f /t /im Sub_Web.exe"); + // Close.Start(); + QProcess::startDetached("taskkill /f /t /im Sub_Web.exe"); + } + static bool GetSub_Status(){ + bool F = false; + CCProcess P; +#ifdef _WIN32 + P.AddCommand("tasklist | findstr Sub_Server.exe"); +#elif __linux__ +#endif + P.Start(true); + while (true){ + CCString str = P.ReadLineBuffer(); + if(str.empty()){ + break; + } + else{ + F = str.find("Sub_Server") != CCString::npos; + if(F){ + break; + } + } + } + P.Stop(); + return F; + } + static bool GetSub_Web_Status(){ + bool F = false; + CCProcess P; +#ifdef _WIN32 + P.AddCommand("tasklist | findstr Sub_Web.exe"); +#elif __linux__ +#endif + P.Start(true); + while (true){ + CCString str = P.ReadLineBuffer(); + if(str.empty()){ + break; + } + else{ + F = str.find("Sub_Web") != CCString::npos; + if(F){ + break; + } + } + } + P.Stop(); + return F; + } + static bool SaveJarCfg() { + CCString File = CCFile::GetnormalizePath(CfgPath); + FILE *fp = fopen(File.c_str(), "w"); + if(fp == nullptr){ + return false; + } + fprintf(fp, "C/S_IP:%s\n",CS_IP.c_str()); + fprintf(fp, "C/S_PORT:%s\n",CS_Port.c_str()); + fprintf(fp, "Sub_Control_IP:%s\n",Sub_IP.c_str()); + fprintf(fp, "Sub_Control_PORT:%s\n",Sub_Port.c_str()); + fprintf(fp, "Sub_Control_Audio_PORT:%s\n",Sub_Audio_Port.c_str()); + fprintf(fp, "Sub_Web_PORT:%s\n",Web_Port.c_str()); + fprintf(fp, "Origins:%s\n",Sub_Org.c_str()); + fprintf(fp, "#中文简体,English\n"); + fprintf(fp, "Language:%s\n",Language.c_str()); + fprintf(fp, "OpenSleep:%d\n",OpenSleep); + fprintf(fp, "State:%s\n",Configuration::State.c_str()); + fprintf(fp, "CORSEn:%s\n",Configuration::CORSEn.c_str()); + fprintf(fp, "FirstRun:%d\n",0); + fclose(fp); + return true; + } + static bool SaveWebCfg(){ + CCString File = CCFile::GetnormalizePath(WebCfgPath); + CCVar fp = fopen(File.c_str(), "w"); + if (fp == nullptr) { + return false; + } + // 写入配置数据 + fprintf(fp, "worker_processes 1;\n" + "events {\n" + " worker_connections 1024;\n" + "}\n" + "http {\n" + " include mime.types;\n" + " default_type application/octet-stream;\n" + " sendfile on;\n" + " keepalive_timeout 65;\n" + " client_max_body_size 500m;\n" + " server {\n" + " listen %s;\n" + " server_name %s;\n" + " location / {\n" + " root html;\n" + " index index.html index.htm;\n" + " try_files $uri $uri/ /index.html;\n" + " # try_files $uri $uri/ @router;\n" + " }\n" + " location /api/ {\n" + " #rewrite ^.+api/?(.*)$ /$1 break; \n" + " rewrite ^/api/(.*)$ /$1 break; \n" + " proxy_pass http://%s:%s/;\n" + " proxy_redirect off;\n" + " proxy_set_header Host $host;\n" + " proxy_set_header X-Real-IP $remote_addr;\n" + " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n" + " }\n" + " error_page 500 502 503 504 /50x.html;\n" + " location = /50x.html {\n" + " root html;\n" + " }\n" + " }\n" + "}",Web_Port.c_str(),Web_IP.c_str(), + Sub_IP.c_str(),Sub_Port.c_str()); + fclose(fp); + return true; + } + static void IPBS_NSSMF(bool F){ + if(F){ + CCString cmd = "cd " + ExePath + " && " + IPBS_NSSMPath; + QProcess::startDetached(cmd.c_str()); + } + else{ + QProcess::startDetached("taskkill /f /t /im IPBS_NSSM.exe"); + } + } +}; + +#endif diff --git a/SDK/CCServlet/include/CCRequest.h b/SDK/CCServlet/include/CCRequest.h index f1eb150..e3534a5 100644 --- a/SDK/CCServlet/include/CCRequest.h +++ b/SDK/CCServlet/include/CCRequest.h @@ -8,7 +8,13 @@ #include "../../include/CCJSONObject.h" #include "../../include/CCFile.h" #include "../../include/CCSocket.h" +#include "../../include/CCThread.h" +#include "../../include/CCThreadPool.h" +#include "CCObject.h" +#include "../../include/CCFileOutStream.h" +#define Buffer_Max 1024 +class CCRequest; enum RequestProcess { RequestProcess_First, @@ -22,6 +28,7 @@ struct BufferReader CCString Method; CCString Path; CCString Version; + std::vector Buffer; }; struct BufferFile @@ -58,8 +65,31 @@ public: void SetHost(const CCString& host); void SetBufferBody(CCString body); void Send(); + CCSocket GetSocket(); }; +class InPutStream:public CCFileOutStream +{ +public: + +private: + std::vector Buffer; + BufferReader bufferReader; + CCSocket Socket; + std::map FileHeaders; + std::map Headers; +public: + InPutStream() = default; + InPutStream(CCRequest* Res); + void WriteBufferToFile(const CCString& Path); + CCObject Get(CCString key); +private: + void DeleteTailOf(CCString Path,CCString str); + std::string readTailOfFile(const std::string& filepath, size_t bufferSize); + bool filterAndPrint(const std::string& tail, const std::string& filter); +}; + + class CCRequest { private: @@ -67,7 +97,7 @@ private: public: std::map Headers; - + std::map FileHeaders; public: CCRequest() = default; CCRequest(CCSocket& sc); @@ -76,16 +106,19 @@ public: unsigned int GetFileSize(const char* path); void SetBuffer(BufferReader& buffer); BufferReader GetReader(); - JSON GetJson(const BufferReader& instr); + static JSON GetJson(const BufferReader& instr); BufferFile GetFile(BufferReader in); CCString GetParameter(CCString string); - OutPutStream GetWiter(); + BufferReader ReaderFileData(); + OutPutStream GetWriter(); + void GetFormData(CCString& input,CCString& key,CCString& value); + CCString GetFileDateHeader(BufferReader in,std::map& map); + CCString GetFileDateHeader(CCString& in,std::map& map); + std::vector ReaderFormData(BufferReader in, std::map &map); + InPutStream GetInputStream(); private: std::map parseKeyValuePairs(const std::string& input); - void GetFormData(CCString& input,CCString& key,CCString& value); - CCString GetFileDateHeader(BufferReader in,std::map& map); - std::vector ReaderFormData(BufferReader in, std::map &map); CCSocket Socket; }; diff --git a/SDK/CCServlet/include/CCResponse.h b/SDK/CCServlet/include/CCResponse.h index f55c66c..28f6d5f 100644 --- a/SDK/CCServlet/include/CCResponse.h +++ b/SDK/CCServlet/include/CCResponse.h @@ -6,6 +6,11 @@ #include "../../include/CCSocket.h" #include "CCString.h" #include "mutex" +#include +#include +#include +#include + class HTTPResponse: public CCRequest, public CORS { public: @@ -14,16 +19,26 @@ public: void HtmlTextWrite(const CCString& str); bool HtmlWrite(const CCString& str); void Write(const CCString& str,const char* type = "text/plain"); - bool WriteFile(const CCString& Path); + void Write(char * data,size_t length); + void HTTPWrite(const CCString& str); + bool WriteMultipart(const CCString& Path); + bool FileDownload(const CCString& Path); void Send(const CCString& string); void ResponseOK(); - + CCString ResopenseWebSocket(const CCString& Key); + void SetHeader(const CCString& Key,CCString Value); + bool IsConnect(); + std::map GetHeaders(); private: bool SendResources(const char* Path, const char* Mode = "rb"); + CCString base64_encode(const unsigned char *data, size_t length); + CCString sha1(const CCString& input); CCSocket Client; std::mutex Mutex; CORS CORSConfig; + std::map Headers; + std::streamoff getFileSize(const std::string& filePath); private: @@ -39,7 +54,7 @@ public: public: CCResponse() = default; CCResponse(CCSocket& socket,CORS& cors); - HTTPResponse GetWiter(); + HTTPResponse GetWriter(); private: CCSocket Client; diff --git a/SDK/CCServlet/include/CCString.h b/SDK/CCServlet/include/CCString.h deleted file mode 100644 index d5c90b9..0000000 --- a/SDK/CCServlet/include/CCString.h +++ /dev/null @@ -1,106 +0,0 @@ -#ifndef STM32API_CCSTRING_H -#define STM32API_CCSTRING_H -#include "../../include/CCVector.hpp" -#include - -#define PC -#ifdef PC -#include -#include "strstream" -#include "sstream" -using CCString = std::string; -using CCStream = std::strstream; -#else -class CCString -{ -public: - CCString() = default; - CCString(const char* str); - CCString(const CCString& str); - CCString(CCVector str); - - //---------------------------------------------------------------- - const char* c_str(); - unsigned int length(); - float to_float(); - int to_int(); - void append(char str); - void append(const char* str); - void append(CCString str); - void append(CCVector str); - void clear(); - //---------------------------------------------------------------- - bool operator==(const char* str); - bool operator==(const CCString str); - bool operator!=(const char* str); - bool operator!=(const CCString& str); - //---------------------------------------------------------------- - CCString operator+(const char* str); - void erase(int index,int len); - unsigned int find(char str); - unsigned int find(const char* str); - unsigned int find(CCString str); - void replace(int index,char str); - void replace(int index,const char* str); - void replace(int index,int index2, const char *str); - //---------------------------------------------------------------- -#ifdef __JSON__ - JSONObject to_json() - { - return JSONObject::Parse(c_str()); - } -#endif - -private: - CCVector data; - void copy(const char* str); - void copy(char* str,const char* str2,int len); - void copy(char* str,CCVector str2,int len); - int strlenth(const char* str); - -}; - -namespace CCTools -{ - inline CCString To_CCString(int index) - { - char str[100] = {0}; - sprintf(str,"%d",index); - return str; - } - - inline CCString To_CCString(float index) - { - char str[100] = {0}; - sprintf(str,"%.5f",index); - return str; - } - - inline CCString To_CCString(double index) - { - char str[100] = {0}; - sprintf(str,"%lf",index); - return str; - } - template - inline CCString To_CCString(const char* l,T num) - { - char str[100] = {0}; - sprintf(str,l,num); - return str; - } - -#ifdef __JSON__ - inline CCString To_CCString(JSONObject a) - { - return ""; - } -#endif - enum Error_type - { - Lengtherror = -1, - }; -} -#endif - -#endif diff --git a/SDK/CCServlet/include/CCWeb.h b/SDK/CCServlet/include/CCWeb.h deleted file mode 100644 index cfcd7b7..0000000 --- a/SDK/CCServlet/include/CCWeb.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef DEMO_CCWEB_H -#define DEMO_CCWEB_H - -#include "../../include/CCSocket.h" -#include "../../include/CCThread.h" -#include "functional" -#include -#include "map" -#include "mutex" -#include "nlohmann/json.hpp" -#include "fstream" -#include "sstream" - -#define UserMAX 20 -#define BufferSize 4096 - -enum RequestProcess -{ - RequestProcess_First, - RequestProcess_Header, - RequestProcess_Body, -}; - -struct HTTPRequestFile -{ - std::string Name; - std::string Type; - std::vector Buffer; - std::map Headers; - bool Save(std::string Path) const; -}; - - -struct HTTPRequest -{ - unsigned int ID = 0; - std::string Method; - std::string Path; - std::string Version; - std::string Data; - std::string Buffer; - std::vector Bufferstr; - std::map Headers; - std::map BodyData; - HTTPRequestFile FileData; -}; - - - -class CCWeb -{ -private: - using RequestFunc = std::function; - std::map RequestFun; - std::vector PathSix; - bool PrintBool = false; - std::mutex mutexs; - std::string BUFFER; - -public: - CCWeb() = default; - //---------------------------------------------------------------- - HTTPRequest HTTPRequests; - //---------------------------------------------------------------- - bool HTTPStart(const char * IP, int port); - bool SendResources(unsigned int ID, const char* Path, const char* Mode = "rb"); - bool SendResourcesData(unsigned int ID, const char* Data); - bool SendData(unsigned int ID, const char* Data,const char* type = "text/plain"); - std::string GetPath(const char* Path); - std::string GetMethod(const char* str); - std::string GetFileSuffix(const std::string& filePath); - std::string GetFileType(const std::string& str); - std::string GetData(std::string name,HTTPRequest request); - std::string FilterString(const char * str,char Begin,char End); - std::string GetRequestData(const char * str); - std::string GetIP(IPVX port = IPVX::IPV4); - std::string StrSplicing(const char *__restrict _format,...); - void HTTPStop(); - void SetAddRootPath(const std::string& rootPath); - void SetPrint(bool print); - void SetRequestFunction(std::string RootPath,RequestFunc RFunc); - unsigned int GetFileSize(const char* path); - //---------------------------------------------------------------- - template - std::string ReviseHTMLData(const char * Path, const char* Flags,Data&& data); - template - std::string ReviseData(const char * Date, const char* Flags,Data&& data); - template - name GetHTTPRequestData(const char * Date,std::string Request); - std::string GetHTTPRequestData(const char * Date,std::string Request); - std::string Getboundary(std::string& FileData); - //---------------------------------------------------------------- - -private: - std::string Filtration(const char * buf); - std::string FiltrationJson(const char *buf); - //---------------------------------------------------------------- - CCSocket Server,Client[UserMAX] = { }; - CCThread Threadappect,Thread[UserMAX] = { }; - unsigned int ThreadCount = 0,lent = 0; - CC_Thread Appect(); - CC_Thread ReadThread(unsigned int ID); - - -}; -template -inline std::string CCWeb::ReviseHTMLData(const char *Path, const char *Flags, Data&& data) -{ - std::string str,Flag = std::string("{{") + Flags + "}}"; - std::ifstream file(Path,std::ios::in); - if (file.is_open()) - { - char buf[BufferSize] = {0}; - while (file.getline(buf,BufferSize)) - { - str.append(buf); - memset(buf,'\000',BufferSize); - } - file.close(); - } - else - { - return "Not found file"; - } - size_t i = str.find(Flag); - if(i != std::string::npos) - { - str.replace(i,Flag.length(),data); - } - return str; -} - -template -inline std::string CCWeb::ReviseData(const char *Date, const char *Flags, Data&& data) -{ - std::string str = Date,Flag = std::string("{{") + Flags + "}}"; - size_t i = str.find(Flag); - if(i != std::string::npos) - { - str.replace(i,Flag.length(),data); - } - return str; -} - -#endif diff --git a/SDK/CCServlet/include/CCWebServlet.h b/SDK/CCServlet/include/CCWebServlet.h index 399270c..97ba395 100644 --- a/SDK/CCServlet/include/CCWebServlet.h +++ b/SDK/CCServlet/include/CCWebServlet.h @@ -2,47 +2,71 @@ #define CCWeb_Servlet_H #pragma once -#include "CCSocket.h" -#include "../../include/CCJSONObject.h" -#include "../../include/CCThread.h" -#include "../../include/CCThreadPool.h" -#include "CCString.h" #include "CCResponse.h" +#include "CCTimeData.h" +#include "CCWebSocketInfo.h" -#define Buffer_Max 1024 +#define CC_ServletFunClass(Fun) [this](auto && PH1, auto && PH2) { Fun(std::forward(PH1), std::forward(PH2)); } +#define CC_WSFunClass(Fun) [this](auto && PH1) { Fun(std::forward(PH1)); } +#define CC_ServletFun(Fun) Fun +#define CC_WSFun(Fun) Fun + +enum PromptLevel +{ + ERROR_t = 0, + WARNING, + INFO, + DEBUG +}; class CCWebServlet:public CCResponse { private: using RequestFunc = std::function; + using RecvDataFunc = std::function; std::map RequestFun; CCString ServerIP; CCSocket m_Socket; - int numThreads = 5,ListenMax = 50,RootLen = 0; + int numThreads = 5,ListenMax = 50,RootLen = 0,ServerPort; bool FlagRun = true; + PromptLevel Print = DEBUG; CCThread m_Thread; - CCThreadPool m_ThreadPool; std::vector PathSix; CORS CORSConfig; std::mutex m_Mutex; - + std::function WebSocketSignal; + RequestFunc WebSignalFun; + CCThreadPool m_ThreadPool; + RecvDataFunc MFunc,CFunc,IFunc,EFunc; public: public: CCWebServlet() = default; void SetThreadNumber(int headcount); - void SetWebServlet(CCString RootPath,RequestFunc RFunc); + void SetWebServlet(CCString UrlPath,RequestFunc RFunc); void SetAddRootPath(const CCString& rootPath); + void SetWebServletFun(RequestFunc RFunc); bool Sign() const; bool Start(CCString IP,int port); + bool Init(CCString IP,int port,bool ChokeUpSock = true); + int Running(); void Close(); void SetCorsConfig(CORS& cors); + void SetWSOnMessage(RecvDataFunc RFunc); + void SetWSOnClose(RecvDataFunc CFunc); + void SetWSOnOpen(RecvDataFunc IFunc); + void SetWSOnError(RecvDataFunc EFunc); + void SetPrint(PromptLevel level); + CCThreadPool GetServletThreadPool(); + std::vector GetIPS(); private: + void MessagePrompt(const CCString& message); void ProcessRequest(); void ResponseData(CCSocket & socket); - - + CCString GetFileHeaders(CCString& str,CCSocket &socket,std::map &map); + int unPackingWSFrameData(char *msg,int msgLen,std::vector &outBuf,CCWebSocketInfo& wsInfo); + void constructCloseFrame(unsigned char *frame, int status_code, const char *reason); }; diff --git a/SDK/CCServlet/src/CCRequest.cpp b/SDK/CCServlet/src/CCRequest.cpp index 44ad675..d6c42d0 100644 --- a/SDK/CCServlet/src/CCRequest.cpp +++ b/SDK/CCServlet/src/CCRequest.cpp @@ -3,7 +3,6 @@ #include #include - CCString CCRequest::GetFileType(const CCString &str) { std::string suffix = GetFileSuffix(str); if(suffix == "html") @@ -177,31 +176,8 @@ void CCRequest::GetFormData(CCString &input, CCString &key, CCString &value) { } CCString CCRequest::GetFileDateHeader(BufferReader in, std::map &map) { - CCString str = in.Body,A,B; - auto len = str.find("\r\n"); - CCString Boundary = str.substr(0,len); - str.erase(0,len+2); - map["Boundary"] = Boundary; - std::stringstream ss(str); - ss >> A; - ss >> B; - len = A.length() + B.length(); - A.erase(A.length()-1,A.length()); - B.erase(B.length()-1,B.length()); - map[A] = B; - str.erase(0,len+2); - GetFormData(str,A,B); - map[A] = B; - len = A.length() + B.length(); - str.erase(0,len + 5); - len = str.find("\r\n\r\n"); - CCString str2 = str.substr(0,len+4); - str.erase(0,len+4); - auto m = parseKeyValuePairs(str2); - for (const auto& i : m) { - map[i.first] = i.second; - } - return str; + CCString A = GetFileDateHeader(in.Body,map); + return A; } std::vector CCRequest::ReaderFormData(BufferReader in, std::map &map) { @@ -239,7 +215,7 @@ CCString CCRequest::GetParameter(CCString string) { return str; } -OutPutStream CCRequest::GetWiter() { +OutPutStream CCRequest::GetWriter() { return this->Socket; } @@ -247,6 +223,73 @@ CCRequest::CCRequest(CCSocket &sc) { this->Socket = sc; } +BufferReader CCRequest::ReaderFileData() { + auto OutPutSteam = GetWriter().GetSocket(); + std::vector BF; + while(true){ + char buffer[1024] = {0}; + if(OutPutSteam.isDataAvailable()){ + auto length = OutPutSteam.RecvData(buffer,1024); + if(length > 0){ + for (auto i : buffer) { + BF.push_back(i); + } + } + else { + break; + } + } + else{ + break; + } + } + auto F = GetReader(); + CCString str(BF.begin(), BF.end()); + F.Body = str; + return F; +} + +CCString CCRequest::GetFileDateHeader(CCString& in, map &map) { + CCString str = in,A,B; + auto len = str.find("\r\n"); + while (true){ + CCString Boundary = str.substr(0,len); + if(Boundary.empty()){ + str.erase(0,len+2); + } + else { + str.erase(0,len+2); + map["Boundary"] = Boundary; + break; + } + len = str.find("\r\n"); + } + std::stringstream ss(str); + ss >> A; + ss >> B; + len = A.length() + B.length(); + A.erase(A.length()-1,A.length()); + B.erase(B.length()-1,B.length()); + map[A] = B; + str.erase(0,len+2); + GetFormData(str,A,B); + map[A] = B; + len = A.length() + B.length(); + str.erase(0,len + 5); + len = str.find("\r\n\r\n"); + CCString str2 = str.substr(0,len+4); + str.erase(0,len+4); + auto m = parseKeyValuePairs(str2); + for (const auto& i : m) { + map[i.first] = i.second; + } + return str; +} + +InPutStream CCRequest::GetInputStream() { + return {this}; +} + void OutPutStream::SetMethod(MethodType method) { if(method == MethodType_GET){ this->SendHeaders["Method"] = "GET"; @@ -293,7 +336,11 @@ void OutPutStream::Send() { } str.append("\r\n"); str.append(this->RBody); - Socket.Sendbyte(str.c_str(),(int)str.length()); + Socket.SendByte(str.c_str(),(int)str.length()); +} + +CCSocket OutPutStream::GetSocket() { + return Socket; } bool BufferFile::Save(const CCString &Path) { @@ -310,3 +357,118 @@ bool BufferFile::Save(const CCString &Path) { CCString BufferFile::GetFileName() { return this->Headers["filename"]; } +InPutStream::InPutStream(CCRequest* Res) { + this->Socket = Res->GetWriter().GetSocket(); + this->bufferReader = Res->GetReader(); + this->FileHeaders = Res->FileHeaders; + this->Headers = Res->Headers; +} +void InPutStream::WriteBufferToFile(const CCString& Path) { + CCFile(Path.c_str(),CC::ios::wb,false).Deleted(); + CCString str = "\r\n" + FileHeaders["Boundary"] + "--\r\n"; + auto strlength = str.length(); + auto S = Headers["Content-Length"]; + if(S.empty()){ + S = Headers["content-length"]; + } + long long Maxlength = std::stoll(S); + std::vector data = bufferReader.Buffer; + int F = 0; + CCFileOutStream file(Path, std::ios::app | std::ios::binary); + // 检查文件是否成功打开 + if (!file.is_open()) { + std::cerr << "无法打开文件: " << Path << std::endl; + return; + } + while (true){ + if(Socket.isDataAvailable()){ + char buffer[Buffer_Max] = {0}; + auto l = Socket.RecvData(buffer, Buffer_Max); + if(l > 0 && F == 0){ + if(l != Buffer_Max){ + for (int i = 0; i < l; ++i) { + data.push_back(buffer[i]); + } + } + else { + for (auto i : buffer) { + data.push_back(i); + } + } + Maxlength = Maxlength - data.size(); + if(Maxlength < Buffer_Max * 2){ + CCString DB = CCString(data.begin(),data.end()); + auto len = DB.find(str); + if(len != std::string::npos){ + data = std::vector(data.begin(),data.begin() + len); + F = 1; + } + } + file.write(data.data(), data.size()); + data.clear(); + } + else { + file.close(); + CCFile(Path.c_str(),CC::ios::wb,false).Deleted(); + std::cout << "连接中断" << std::endl; + return; + } + } + else { + break; + } + } + file.close(); +} + +CCObject InPutStream::Get(CCString key) { + return FileHeaders[key].c_str(); +} + +void InPutStream::DeleteTailOf(CCString Path, CCString str) { + // 读取文件尾部数据 + std::string tail = readTailOfFile(Path, Buffer_Max); + if (!tail.empty()) { + if (filterAndPrint(tail, str)) { + std::cout << "文件: " << Path << std::endl; + } + } +} + +std::string InPutStream::readTailOfFile(const string &filepath, size_t bufferSize) { + std::ifstream file(filepath, std::ios::binary); + if (!file.is_open()) { + std::cerr << "无法打开文件: " << filepath << std::endl; + return ""; + } + + // 获取文件大小 + file.seekg(0, std::ios::end); + std::streampos fileSize = file.tellg(); + file.seekg(0, std::ios::beg); + + // 计算从文件末尾读取的字节数 + size_t bytesToRead = static_cast(fileSize); + if (bytesToRead > bufferSize) { + bytesToRead = bufferSize; + } + + // 读取文件尾部数据 + std::vector buffer(bytesToRead); + file.seekg((size_t)fileSize - bytesToRead, std::ios::beg); + file.read(buffer.data(), bytesToRead); + + // 将缓冲区转换为字符串 + std::string tail(buffer.begin(), buffer.end()); + return tail; +} + +bool InPutStream::filterAndPrint(const string &tail, const string &filter) { + size_t pos = tail.find(filter); + if (pos != std::string::npos) { + std::cout << "找到指定数据: " << filter << std::endl; + std::cout << "尾部数据: " << tail << std::endl; + return true; + } + return false; +} diff --git a/SDK/CCServlet/src/CCResponse.cpp b/SDK/CCServlet/src/CCResponse.cpp index b333a3b..5772023 100644 --- a/SDK/CCServlet/src/CCResponse.cpp +++ b/SDK/CCServlet/src/CCResponse.cpp @@ -1,27 +1,23 @@ #include "CCResponse.h" +#include + CCResponse::CCResponse(CCSocket &socket,CORS& cors) { this->Client = socket; Cors = cors; } - -HTTPResponse CCResponse::GetWiter() +HTTPResponse CCResponse::GetWriter() { return HTTPResponse(Client,Cors); } - - - void HTTPResponse::HtmlTextWrite(const CCString& str) { this->Write(str, "text/html"); } - HTTPResponse::HTTPResponse(CCSocket &socket,CORS& cors) { Client = socket; CORSConfig = cors; } - -void HTTPResponse::Write(const CCString& str, const char *type) { +void HTTPResponse::Write(const CCString& str, const char *type){ char buf[200] = {0}; Client.Send("HTTP/1.1 200 OK\r\n"); Client.Send("Server:HTTP->CCWebServlet->OK\r\n"); @@ -63,11 +59,44 @@ void HTTPResponse::Write(const CCString& str, const char *type) { Client.Send(str.c_str()); //Client.Send("\r\n\r\n"); } - bool HTTPResponse::HtmlWrite(const CCString &str) { +// CCFile file = CCFile(str.c_str()); +// if (file.IsOpen()) { +// CCVar info = file.GetFileInfo(); +// size_t fileSize = info.Size; +// file.Close(); +// SetHeader("Content-Type", GetFileType(str)); +// SetHeader("Content-Length", std::to_string(fileSize)); +// // 获取文件流 +// std::ifstream inputFile(info.Path, std::ios::binary); +// if (!inputFile.is_open()) { +// std::cerr << "无法打开文件" << std::endl; +// return false; +// } +// +// // 开始发送文件数据 +// const size_t bufferSize = 4096; +// char buffer[bufferSize]; +// size_t remaining = fileSize; +// HTTPWrite(""); // 初始化 HTTP 写入 +// while (remaining > 0) { +// size_t bytesToRead = std::min(remaining, bufferSize); +// inputFile.read(buffer, bytesToRead); +// size_t bytesRead = inputFile.gcount(); +// // 将读取的数据写入 HTTP 响应 +// if(IsConnect()){ +// Write(buffer,bytesRead); +// } +// remaining -= bytesRead; +// } +// inputFile.close(); +// return true; +// } +// else { +// return false; +// } return SendResources(str.c_str()); } - bool HTTPResponse::SendResources(const char *Path, const char *Mode) { Mutex.lock(); FILE *file = fopen(Path, Mode); // 替换为你的文件名 @@ -106,11 +135,9 @@ bool HTTPResponse::SendResources(const char *Path, const char *Mode) { Mutex.unlock(); return true; } - void HTTPResponse::Send(const CCString &string) { Client.Send(string.c_str()); } - void HTTPResponse::ResponseOK() { char buf[200] = {0}; Client.Send("HTTP/1.1 200 OK\r\n"); @@ -136,46 +163,170 @@ void HTTPResponse::ResponseOK() { Client.Send("Access-Control-Allow-Methods:GET,POST,PUT,DELETE,OPTIONS\r\n"); Client.Send("\r\n"); } +CCString HTTPResponse::ResopenseWebSocket(const CCString& Key) { + CCString acceptValue = sha1(Key); + CCString st = "HTTP/1.1 101 Switching Protocols\r\n"; + st.append("Upgrade: websocket\r\n"); + st.append("Connection: Upgrade\r\n"); + st.append("Sec-WebSocket-Accept:" + acceptValue + "\r\n"); + st.append("\r\n"); + Client.Send(st.c_str()); + return acceptValue; +} +CCString HTTPResponse::base64_encode(const unsigned char *data, size_t length) { + BIO *bio, *b64; + BUF_MEM *bufferPtr; -bool HTTPResponse::WriteFile(const CCString &Path) { - Mutex.lock(); - FILE *file = fopen(Path.c_str(), "rb"); // 替换为你的文件名 - if (file == NULL) - { - Mutex.unlock(); + b64 = BIO_new(BIO_f_base64()); + bio = BIO_new(BIO_s_mem()); + bio = BIO_push(b64, bio); + + BIO_write(bio, data, (int)length); + BIO_flush(bio); + BIO_get_mem_ptr(bio, &bufferPtr); + BIO_set_close(bio, BIO_NOCLOSE); + BIO_free_all(bio); + CCString ret(bufferPtr->data, bufferPtr->length-1); + return ret; +} +CCString HTTPResponse::sha1(const CCString &input) { + CCString str = input + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; + unsigned char hash[SHA_DIGEST_LENGTH]; + SHA_CTX sha1; + SHA1_Init(&sha1); + SHA1_Update(&sha1, str.c_str(), str.length()); + SHA1_Final(hash, &sha1); + return base64_encode(hash, SHA_DIGEST_LENGTH); +} + +std::streamoff HTTPResponse::getFileSize(const string &filePath) { + std::ifstream file(filePath, std::ios::binary | std::ios::ate); + if (!file.is_open()) { + return -1; // 文件打开失败 + } + + // 获取文件指针当前位置,即文件大小 + std::streamoff fileSize = file.tellg(); + + // 将文件指针移回文件开头 + file.seekg(0, std::ios::beg); + + file.close(); + return fileSize; +} + +bool HTTPResponse::WriteMultipart(const CCString &path) { + // 打开文件 + std::ifstream file(path, std::ios::binary); + if (!file.is_open()) { + Client.Send("HTTP/1.1 404 Not Found\r\n"); + Client.Send("Content-Length: 0\r\n"); + Client.Send("\r\n"); return false; } - Client.Send("HTTP/1.1 200 OK\r\n"); - Client.Send("Server:HTTP->CCWeb->OK\r\n"); - char buf[50] = {0}; - sprintf(buf, "Content-type:text/plain\r\n"); - Client.Send(buf); - memset(buf,0,sizeof buf); - CCFile file2 = CCFile(Path.c_str(),CC::ios::rb,false); - sprintf(buf, "Content-Disposition: attachment; filename=\"%s\"\r\n",file2.GetFileInfo().Name.c_str()); - Client.Send(buf); - memset(buf,0,sizeof buf); - sprintf(buf, "Content-Length:%ld\r\n", file2.GetFileInfo().Size); - Client.Send(buf);//Content-Length: + + // 获取文件大小 + std::streamoff fileSize = getFileSize(path); + + // 设置响应头 + std::string boundary = "----WebKitFormBoundary7MA4YWxkTrZu0gW"; + std::stringstream response; + + // 发送 HTTP 响应头 + response << "HTTP/1.1 200 OK\r\n"; + response << "Content-Type: multipart/form-data; boundary=" << boundary << "--\r\n"; + response << "Content-Length: " << (fileSize + boundary.length() + 128) << "\r\n"; + response << "\r\n"; + + // 发送 multipart/form-data 数据 + response << "--" << boundary << "\r\n"; + response << R"(Content-Disposition: form-data; name="file"; filename=")" << path << "\"\r\n"; + response << "Content-Type: application/octet-stream\r\n"; + response << "\r\n"; + + // 发送文件内容 + char buffer[4096]; + while (file.read(buffer, sizeof(buffer))) { +// size_t bytesRead = file.gcount(); + Client.Send(buffer); + } + + // 发送文件末尾 Client.Send("\r\n"); + CCString end = "--" + boundary + "--\r\n"; + Client.Send(end.c_str()); + + file.close(); - int cout = 0; - char bufs[4096] = { 0 }; - int fpId = -1; - struct stat st; - fpId = fileno( file ); - if( fstat( fpId ,&st) == -1 ) - { - Mutex.unlock(); - return false; - } - while (!feof(file)) - { - int ret = fread(bufs,sizeof(char),sizeof bufs,file); - Client.Send(bufs,sizeof bufs,0); - cout += ret; - } - fclose(file); - Mutex.unlock(); return true; } + +bool HTTPResponse::FileDownload(const CCString &path) { + CCFile file = CCFile(path.c_str()); + if (file.IsOpen()) { + CCVar info = file.GetFileInfo(); + size_t fileSize = info.Size; + file.Close(); + SetHeader("Content-Type", "application/octet-stream; charset=utf-8"); + SetHeader("Content-Disposition", "attachment; filename=" + info.Name); + SetHeader("Content-Length", std::to_string(fileSize)); + + // 获取文件流 + std::ifstream inputFile(info.Path, std::ios::binary); + if (!inputFile.is_open()) { + std::cerr << "无法打开文件" << std::endl; + return false; + } + + // 开始发送文件数据 + const size_t bufferSize = 4096; + char buffer[bufferSize]; + size_t remaining = fileSize; + HTTPWrite(""); // 初始化 HTTP 写入 + + while (remaining > 0) { + size_t bytesToRead = std::min(remaining, bufferSize); + inputFile.read(buffer, bytesToRead); + size_t bytesRead = inputFile.gcount(); + // 将读取的数据写入 HTTP 响应 + if(IsConnect()){ + Write(buffer,bytesRead); + } + remaining -= bytesRead; + } + + inputFile.close(); + return true; + } + else { + return false; + } +} + +void HTTPResponse::SetHeader(const CCString& Key, CCString Value) { + Headers[Key] = std::move(Value); +} + +std::map HTTPResponse::GetHeaders() { + return Headers; +} + +void HTTPResponse::HTTPWrite(const CCString &str) { + CCString SData; + SData.append("HTTP/1.1 200 OK\r\n"); + SData.append("CCWebServlet: HTTP->CCWeb->OK\r\n"); + for (CCVar i : Headers) { + SData.append(i.first + ": " + i.second + "\r\n"); + } + SData.append("\r\n"); + SData.append(str); + Client.Send(SData.c_str()); +} + +void HTTPResponse::Write(char *data, size_t length) { + Client.Send(data, length,0); +} + +bool HTTPResponse::IsConnect() { + return Client.isConnectionAlive(); +} diff --git a/SDK/CCServlet/src/CCString.cpp b/SDK/CCServlet/src/CCString.cpp deleted file mode 100644 index 215c8f6..0000000 --- a/SDK/CCServlet/src/CCString.cpp +++ /dev/null @@ -1,308 +0,0 @@ -#include -#include "CCString.h" -#define PC -#ifdef PC - -#else -void CCString::copy(const char* str) -{ - data.clear(); - for (int i = 0; i < strlenth(str); i++) - { - data.push_back(str[i]); - } -} - -int CCString::strlenth(const char* str) -{ - int count = 0; - while (str[count] != '\0') - { - count++; - } - return count; -} - -CCString::CCString(const char *str) -{ - data.clear(); - for (int i = 0; i < strlenth(str); i++) - { - data.push_back(str[i]); - } -} - -CCString::CCString(const CCString &str) -{ - data = str.data; -} - -CCString::CCString(CCVector str) -{ - data = str; -} - -const char *CCString::c_str() -{ - char* c = (char*)malloc(data.size()); - for (int i = 0; i < data.size();i++) - { - c[i] = '\0'; - } - for (int i = 0; i < data.size(); ++i) - { - c[i] = data[i]; - } - c[data.size()] = '\0'; - return c; -} - -unsigned int CCString::length() -{ - return data.size(); -} - -float CCString::to_float() -{ - char* str = (char*)malloc(data.size()); - copy(str,data,data.size()); - str[data.size()] = '\0'; - char *endptr; // 用于存储解析结束的位置 - double d_value = strtod(str, &endptr); // 将字符串转换为double - if (endptr == str || *endptr != '\0') - { - return 0; - } - else - { - float f_value = (float)d_value; // 将double转换为float - return f_value; - } -} - -int CCString::to_int() -{ - char* str = (char*)malloc(data.size()); - copy(str,data,data.size()); - str[data.size()] = '\0'; - char *endptr; // 用于存储解析结束的位置 - double d_value = strtod(str, &endptr); // 将字符串转换为double - if (endptr == str || *endptr != '\0') - { - return 0; - } - else - { - int f_value = (float)d_value; // 将double转换为float - return f_value; - } -} - -void CCString::append(const char str) -{ - data.push_back(str); -} - -void CCString::clear() -{ - data.clear(); -} - -void CCString::append(const char *str) -{ - - for (int i = 0; i < strlenth(str); i++) - { - data.push_back(str[i]); - } -} - -void CCString::append(CCString str) -{ - for (int i = 0; i < str.data.size(); i++) - { - data.push_back(str.data[i]); - } -} - -void CCString::append(CCVector str) -{ - for (int i = 0; i < str.size(); i++) - { - data.push_back(str[i]); - } -} - -void CCString::copy(char *str, const char *str2, int len) -{ - for (int i = 0; i < len; i++) - { - str[i] = str2[i]; - } -} - -void CCString::copy(char *str, CCVector str2, int len) -{ - for (int i = 0; i < len; i++) - { - str[i] = str2[i]; - } -} - -bool CCString::operator==(const char *str) -{ - if(data.size() != strlenth(str)) - { - return false; - } - for (int i = 0; i < strlenth(str); i++) - { - if (data[i] != str[i]) - { - return false; - } - } - return true; -} - -bool CCString::operator==(CCString str) -{ - if(data.size() != str.length()) - { - return false; - } - for (int i = 0; i < str.length(); i++) - { - if (data[i] != str.data[i]) - { - return false; - } - } - return true; -} - -bool CCString::operator!=(const char *str) -{ - return !this->operator==(str); -} - -bool CCString::operator!=(const CCString &str) -{ - return !this->operator==(str); -} - -CCString CCString::operator+(const char *str) -{ - CCString newStr(*this); - newStr.append(str); - return newStr; -} - -void CCString::erase(int index, int len) -{ - data.erase(index, len); -} - -unsigned int CCString::find(char str) -{ - for (int i = 0; i < data.size(); i++) - { - if (data[i] == str) - { - return i; - } - } - return -1; -} - -unsigned int CCString::find(const char *str) -{ - for (int i = 0; i < data.size(); i++) - { - if (data[i] == str[0]) - { - bool flag = true; - for (int j = 0; j < strlenth(str); j++) - { - if (data[i + j] != str[j]) - { - flag = false; - break; - } - } - if (flag) - { - return i; - } - } - } - return -1; -} - -unsigned int CCString::find(CCString str) -{ - for (int i = 0; i < data.size(); i++) - { - if (data[i] == str.data[0]) - { - bool flag = true; - for (int j = 0; j < str.length(); j++) - { - if (data[i + j] != str.data[j]) - { - flag = false; - break; - } - } - if (flag) - { - return i; - } - } - } - return -1; -} - -void CCString::replace(int index, char str) -{ - data.revise(index,str); -} - -void CCString::replace(int index, const char *str) -{ - CCVector newStr; - for (int i = 0; i < index; i++) - { - newStr.push_back(data[i]); - } - for (int i = 0; i < strlenth(str); i++) - { - newStr.push_back(str[i]); - } - for (int i = index + strlenth(str); i < data.size(); i++) - { - newStr.push_back(data[i]); - } - data = newStr; -} - -void CCString::replace(int index,int index2, const char *str) -{ - CCVector newStr; - for (int i = 0; i < index; i++) - { - newStr.push_back(data[i]); - } - for (int i = 0; i < strlenth(str); i++) - { - newStr.push_back(str[i]); - } - for (int i = index2; i < data.size(); i++) - { - newStr.push_back(data[i]); - } - data = newStr; -} - - -#endif \ No newline at end of file diff --git a/SDK/CCServlet/src/CCWeb.cpp b/SDK/CCServlet/src/CCWeb.cpp deleted file mode 100644 index 2dcc3c6..0000000 --- a/SDK/CCServlet/src/CCWeb.cpp +++ /dev/null @@ -1,743 +0,0 @@ -#include "CCWeb.h" -#include - -std::string CCWeb::GetMethod(const char* str) -{ - char buf[10] = { 0 }; - for (int i = 0; i < strlen(str); ++i) - { - if(str[i] != ' ') - { - buf[i] = str[i]; - } - else - { - break; - } - } - return buf; -} - -std::string CCWeb::GetPath(const char* Path) -{ - bool ret = false; - char buf[50] = { 0 }; - int len = 0; - for (int i = 0; i < strlen(Path); ++i) - { - if(Path[i] == '/' && !ret) - { - ret = true; - } - else if(ret) - { - if(Path[i] != ' ') - { - buf[len] = Path[i]; - ++len; - } - else - { - break; - } - } - - } - return buf; -} - -bool CCWeb::SendResources(unsigned int ID, const char *Path, const char *Mode) -{ - FILE *file = fopen(Path, Mode); // 替换为你的文件名 - if (file == NULL) - { - return false; - } - Client[ID].Send("HTTP/1.1 200 OK\r\n"); - Client[ID].Send("Server:HTTP->CCWeb->OK\r\n"); - char buf[50] = {0}; - sprintf(buf, "Content-type:%s\r\n", GetFileType(Path).c_str()); - Client[ID].Send(buf); - sprintf(buf, "Content-Length:%d\r\n", GetFileSize(Path)); - Client[ID].Send(buf);//Content-Length: - Client[ID].Send("\r\n"); - - int cout = 0; - char bufs[4096] = { 0 }; - int fpId = -1; - struct stat st; - fpId = fileno( file ); - if( fstat( fpId ,&st) == -1 ) - { - return false; - } - - while (!feof(file)) - { - int ret = fread(bufs,sizeof(char),sizeof bufs,file); - Client[ID].Send(bufs,sizeof bufs,0); - cout += ret; - } - //Client[ID].Send("\r\n",sizeof "\r\n",0); - if(PrintBool) - { - printf("Send to Clent len:%d\r\n",cout); - } - fclose(file); - return true; -} - -bool CCWeb::HTTPStart(const char *IP, int port) -{ - this->SetAddRootPath(""); - lent = PathSix.size(); - Server.Socket(IPVX::IPV4,TORU::TCP); - if(!Server.Bind(IP,port)) - { - return false; - } - if(!Server.Listen(UserMAX)) - { - return false; - } - Threadappect.SetThread(&CCWeb::Appect,this); - Threadappect.Start(); - return true; -} - -CC_Thread CCWeb::Appect() -{ - while (Threadappect.Sign()) - { - - Client[ThreadCount] = Server.Accept(); - Thread[ThreadCount].SetThread(&CCWeb::ReadThread,this,ThreadCount); - Thread[ThreadCount].Start(); - ThreadCount++; - if(ThreadCount >= UserMAX) - { - ThreadCount = 0; - } - } - std::cout << "END" << std::endl; - return Threadappect.Stop(); -} - -CC_Thread CCWeb::ReadThread(unsigned int ID) -{ - mutexs.lock(); - bool ReadFlag = false; - ByteHander len = BufferSize; - char Buffer[BufferSize] = {0}; - HTTPRequests.Bufferstr.clear(); - HTTPRequests.BodyData.clear(); - HTTPRequests.Headers.clear(); - HTTPRequests.FileData.Buffer.clear(); - HTTPRequests.FileData.Headers.clear(); - while (len >= BufferSize) - { - len = Client[ID].RecvData(Buffer, sizeof(Buffer)); - for (int i = 0; i < len; ++i) { - HTTPRequests.Bufferstr.push_back(Buffer[i]); - } - memset(Buffer,0, BufferSize); - } - std::string RecvMessage(HTTPRequests.Bufferstr.begin(), HTTPRequests.Bufferstr.end()); - HTTPRequests.Bufferstr.clear(); - if (len > 0) - { - if (PrintBool) - { - std::cout << Buffer << std::endl; - std::cout<< "ThreadID:" << ID << std::endl; - } - RequestProcess Stuart = RequestProcess_First; - while(true) - { - auto strlen = RecvMessage.find("\r\n"); - std::istringstream stream(RecvMessage.substr()); - if(strlen == 0) - { - Stuart = RequestProcess_Body; - } - if(strlen != std::string::npos) - { - if(Stuart == RequestProcess_First) - { - stream >> HTTPRequests.Method; - stream >> HTTPRequests.Path; - stream >> HTTPRequests.Version; - RecvMessage.erase(0,strlen + 2); - Stuart = RequestProcess_Header; - } - else if(Stuart == RequestProcess_Header) - { - std::string Key,Value; - stream >> Key; - stream >> Value; - Key.erase(remove(Key.begin(),Key.end(),':'),Key.end()); - HTTPRequests.Headers.insert(std::pair(Key,Value)); - RecvMessage.erase(0,strlen + 2); - } - else if(Stuart == RequestProcess_Body) - { - if(HTTPRequests.Headers["Content-Type"] == "multipart/form-data;") - { - auto lenstr = HTTPRequests.Headers["Content-Length"]; - auto FileSize = atoi(lenstr.c_str()); - while (FileSize > 0) - { - len = Client[ID].RecvData(Buffer, sizeof(Buffer)); - for (int i = 0; i < len; ++i) { - HTTPRequests.Bufferstr.push_back(Buffer[i]); - } - memset(Buffer,0, BufferSize); - FileSize = FileSize - len; - } - std::string FileData(HTTPRequests.Bufferstr.begin(), HTTPRequests.Bufferstr.end()); - auto END = Getboundary(FileData); - std::string name,filename; - strlen = FileData.find("name=\""); - for(int i = strlen + 6;i < FileData.length(); i++) - { - if(FileData[i] != '\"') - { - name += FileData[i]; - } - else - { - break; - } - } - HTTPRequests.FileData.Headers.insert(std::pair("name",name)); - strlen = FileData.find("filename=\""); - for(int i = strlen + 10;i < FileData.length(); i++) - { - if(FileData[i] != '\"') - { - filename += FileData[i]; - } - else - { - break; - } - } - HTTPRequests.FileData.Headers.insert(std::pair("filename",filename)); - while(true) - { - strlen = FileData.find("\r\n"); - std::string Key,Value; - std::istringstream stra(FileData.substr()); - stra >> Key; - stra >> Value; - Key.erase(remove(Key.begin(),Key.end(),':'),Key.end()); - HTTPRequests.FileData.Headers.insert(std::pair(Key,Value)); - FileData.erase(0,strlen + 2); - if(strlen == 0) - { - break; - } - } - strlen = FileData.find("\r\n" + END + "--"); - for (int i = 0; i < strlen; ++i) { - HTTPRequests.FileData.Buffer.push_back(FileData[i]); - } - HTTPRequests.FileData.Name = HTTPRequests.FileData.Headers["filename"]; - HTTPRequests.FileData.Type = HTTPRequests.FileData.Headers["name"]; - break; - } - else if(HTTPRequests.Headers["Content-Type"] == "application/json") - { - - } - else - { - std::string str; - stream >> str;//"username=admin&password=123456" - while(true) - { - strlen = str.find('&'); - std::string Key,Value; - bool FA = false,ENDF = false; - if(strlen == std::string::npos) - { - strlen = str.length(); - ENDF = true; - } - for (int i = 0; i < strlen; ++i) - { - if(str[i] != '=') - { - if(FA) - { - Value += str[i]; - } - else - { - Key += str[i]; - } - } - else - { - FA = true; - } - } - HTTPRequests.BodyData.insert(std::pair(Key,Value)); - str.erase(0,strlen + 1); - if(ENDF) - { - break; - } - } - break; - } - - } - } - else - { - break; - } - } - HTTPRequests.ID = ID; - if (HTTPRequests.Method == "GET" || HTTPRequests.Method == "POST" || HTTPRequests.Method == "PUT") - { - std::map::iterator t; - for (t = RequestFun.begin(); t != RequestFun.end(); t++) - { - if (t->first == HTTPRequests.Path) - { - t->second(HTTPRequests, this); - ReadFlag = false; - break; - } - else - { - ReadFlag = true; - } - } - if (ReadFlag) - { - bool da = false; - for (int i = 0; i < lent; ++i) - { - if (this->SendResources(ID, std::string(PathSix[i] + HTTPRequests.Path).c_str())) - { - da = true; - break; - } - } - if (!da) - { - char bufsa[100] = {0}; - sprintf(bufsa, "无法打开文件%s\n", HTTPRequests.Path.c_str()); - perror(bufsa); - } - } - - } - - } - else - { - Thread[ID].Stop(); - } - mutexs.unlock(); - Client[ID].Close(); - return Thread[ID].Stop(); -} - -std::string CCWeb::GetFileSuffix(const std::string& filePath) -{ - size_t dotPosition = filePath.rfind('.'); // 从右向左查找最后一个'.'的位置 - if (dotPosition == std::string::npos) - { - return ""; // 如果没有找到'.',则返回空字符串 - } - return filePath.substr(dotPosition + 1); // 返回'.'之后的部分,即文件后缀名 -} - -std::string CCWeb::GetFileType(const std::string &str) -{ - std::string suffix = GetFileSuffix(str); - if(suffix == "html") - { - return "text/html"; - } - else if(suffix == "css") - { - return "text/css"; - } - else if(suffix == "js") - { - return "text/javascript"; - } - else if(suffix == "png") - { - return "image/png"; - } - else if(suffix == "jpg") - { - return "image/jpg"; - } - else if(suffix == "jpeg") - { - return "image/jpeg"; - } - else if(suffix == "gif") - { - return "image/gif"; - } - else if(suffix == "ico") - { - return "image/x-icon"; - } - else if(suffix == "svg") - { - return "image/svg+xml"; - } - else if(suffix == "txt") - { - return "text/plain"; - } - else if(suffix == "xml") - { - return "text/xml"; - } - else if(suffix == "json") - { - return "application/json"; - } - else if(suffix == "pdf") - { - return "application/pdf"; - } - else if(suffix == "zip") - { - return "application/zip"; - } - else - { - return suffix; - } -} - -void CCWeb::SetAddRootPath(const std::string& rootPath) -{ - PathSix.push_back(rootPath); -} - -void CCWeb::SetPrint(bool print) -{ - PrintBool = print; -} - -std::string CCWeb::Filtration(const char *buf) -{ - char Date[BufferSize] = {0}; - std::string buffer; - bool Flag = false; - int len = 0; - std::string le = buf; - auto d = le.length(); - for (int i = 0; i < d; ++i) - { - if(buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && !Flag) - { - i = i+2; - Flag = true; - } - else if(Flag && buf[i] != '\0') - { - Date[len] = buf[i]; - len++; - if(len == sizeof Date) - { - buffer.append(Date); - memset(Date,'\000',BufferSize); - len = 0; - } - } - - } - buffer.append(Date); - return buffer; -} - -std::string CCWeb::FiltrationJson(const char *buf) -{ - char Date[BufferSize] = {0}; - std::string buffer; - bool Flag = false; - int len = 0; - std::string le = buf; - auto d = le.length(); - for (int i = 0; i < d; ++i) - { - if(buf[i] == '\r' && buf[i+1] == '\n' && buf[i+2] == '\r' && !Flag) - { - i = i+2; - Flag = true; - } - else if(Flag) - { - Date[len] = buf[i]; - if(Date[len] == '}') - { - Date[len+1] = '\0'; - buffer.append(Date); - break; - } - len++; - if(len == sizeof Date) - { - buffer.append(Date); - len = 0; - } - } - - } - return buffer; -} - -std::string CCWeb::GetData(std::string name, HTTPRequest request) -{ - const HTTPRequest Date = request; - for(auto i : Date.BodyData) - { - if(i.first == name) - { - return i.second; - } - } - return "NO_Data"; -} - -std::string CCWeb::FilterString(const char *str, char Begin, char End) -{ - char Date[BufferSize] = {0}; - bool Flag = false; - int len = 0; - for (int i = 0; i < strlen(str); ++i) - { - if(str[i] == Begin && !Flag) - { - Flag = true; - } - if(Flag) - { - if(str[i] != End) - { - Date[len] = str[i]; - len++; - } - else - { - break; - } - } - } - return Date; -} - -void CCWeb::SetRequestFunction(std::string RootPath, RequestFunc RFunc) -{ - RequestFun.insert(std::pair(RootPath, RFunc)); -} - -void CCWeb::HTTPStop() -{ - Threadappect.Stop(); - Server.Close(); - for (int i = 0; i < ThreadCount; ++i) - { - Thread[i].Stop(); - CCSocket sc = {}; - if(Client[i] != sc) - { - Client[i].Close(); - } - } - //Threading::Sleep(1000*5000); - ThreadCount = 0; -} - -std::string CCWeb::GetIP(IPVX port) -{ - return Server.GetlocadIP(port).c_str(); -} - -std::string CCWeb::GetRequestData(const char * str) -{ - char Date[BufferSize] = {0}; - bool Flag = false; - int len = 0; - auto da = strlen(str); - for (int i = 0; i < da; ++i) - { - if(str[i] == '7' && str[i+1] == 'B' && str[i+2] == '%' && str[i+3] == '7' && str[i+4] == 'B' && !Flag) - { - Flag = true; - i = i+4; - } - else if(Flag) - { - if(str[i] != '%') - { - Date[len] = str[i]; - len++; - } - else - { - break; - } - } - } - return Date; -} - -bool CCWeb::SendResourcesData(unsigned int ID, const char *Data) -{ - Client[ID].Send("HTTP/1.1 200 OK\r\n"); - Client[ID].Send("Server:HTTP->CCWeb->OK\r\n"); - char buf[50] = {0}; - sprintf(buf, "Content-type:text/html\r\n"); - Client[ID].Send(buf); - sprintf(buf, "Content-Length:%d\r\n", (unsigned int)strlen(Data)); - Client[ID].Send(buf);//Content-Length: - Client[ID].Send("\r\n"); - Client[ID].Send(Data); - //Client[ID].Send("\r\n"); - return true; -} - -unsigned int CCWeb::GetFileSize(const char *Path) -{ - FILE *file = fopen(Path, "rb"); - if (file == nullptr) { - perror("Error opening file"); - return 1; - } - fclose(file); - struct stat fileStat{}; - if (stat(Path, &fileStat) == 0) - { - return fileStat.st_size; - } - else - { - perror("Error getting file size"); - return 0; - } - -} - -std::string CCWeb::StrSplicing(const char * format,...) -{ - char buf[BufferSize] = {0}; - va_list args; - va_start(args, format); - int l = vsnprintf(buf, sizeof(buf), format, args); - if (l < 0 || l >= sizeof(buf)) { - return "ERROR"; - } - va_end(args); - return buf; -} - -bool CCWeb::SendData(unsigned int ID, const char *Data,const char* type) -{ - Client[ID].Send("HTTP/1.1 200 OK\r\n"); - Client[ID].Send("Server:HTTP->CCWeb->OK\r\n"); - char buf[50] = {0}; - sprintf(buf, "Content-type:%s; charset=utf-8\r\n",type); - Client[ID].Send(buf); - sprintf(buf, "Content-Length:%zu\r\n", strlen(Data)); - Client[ID].Send(buf);//Content-Length: - Client[ID].Send("\r\n"); - Client[ID].Send(Data); - //Client[ID].Send("\r\n"); - return true; -} - -template -name CCWeb::GetHTTPRequestData(const char * Date,std::string Request) -{ - std::string Data = Date, RequestData; - auto len = Data.find(Request); - bool f = false; - for (int i = len; i < Data.length(); ++i) { - if(Data[i] == ' ' && !f) - { - f = true; - } - else if(f) - { - if(Data[i] != '\r') - { - RequestData += Data[i]; - } - else - { - break; - } - } - } - name n; - std::istringstream ss(RequestData); - ss >> n; - return n; -} - -std::string CCWeb::GetHTTPRequestData(const char * Date,std::string Request) -{ - std::string Data = Date, RequestData; - auto len = Data.find(Request); - bool f = false; - for (int i = len; i < Data.length(); ++i) { - if(Data[i] == ' ' && !f) - { - f = true; - } - else if(f) - { - if(Data[i] != '\r') - { - RequestData += Data[i]; - } - else - { - break; - } - } - } - return RequestData; -} - -std::string CCWeb::Getboundary(std::string& FileData) -{ - auto len = FileData.find("\r\n"); - std::string str; - for(int i = 0; i < len; ++i) - { - str += FileData[i]; - } - FileData.erase(0,len + 2); - return str; -} - - -bool HTTPRequestFile::Save(std::string Path) const -{ - std::ofstream file(Path,std::ios::out|std::ios::binary); // 如果文件不存在,则创建它 - // 检查文件是否成功打开 - if (!file.is_open()) { - std::cerr << "无法打开文件" << std::endl; - return false; - } - std::string str(Buffer.begin(),Buffer.end()); - file.write(str.c_str(),str.size()); - // 关闭文件 - file.close(); - return true; -} diff --git a/SDK/CCServlet/src/CCWebServlet.cpp b/SDK/CCServlet/src/CCWebServlet.cpp index 9916628..8b3e8b7 100644 --- a/SDK/CCServlet/src/CCWebServlet.cpp +++ b/SDK/CCServlet/src/CCWebServlet.cpp @@ -1,68 +1,217 @@ #include "CCWebServlet.h" bool CCWebServlet::Start(CCString IP,int port){ - FlagRun = true; - RootLen = this->PathSix.size(); - m_Socket.Socket(IPVX::IPV4,TORU::TCP); - m_Socket.SetSocketNonBlocking(); - m_ThreadPool.SetThreadTimeout(1000 * 16); - m_ThreadPool.InitStart(numThreads); - ServerIP = IP; - if(!m_Socket.Bind(ServerIP.c_str(), port)) - { - return false; - } - if(!m_Socket.Listen(ListenMax)) - { - return false; - } - m_Thread.SetThread(&CCWebServlet::ProcessRequest, this); + Init(IP,port); m_Thread.Start(); return true; } +bool CCWebServlet::Init(CCString IP, int port,bool ChokeUpSock){ + CC::CC_Print_Logo(); + FlagRun = true; + RootLen = PathSix.size(); //获取静态文件数; + MessagePrompt("CC_API : Number of static file directories -> " + CCInt(RootLen).to_String()); + m_Socket.Socket(IPVX::IPV4,TORU::TCP); + if(!ChokeUpSock){ + m_Socket.SetSocketNonBlocking(); + MessagePrompt("CC_API : Socket For Nonblocking"); + } + else{ + MessagePrompt("CC_API : Socket For blocking"); + } + int TA = 1000; + m_ThreadPool.SetThreadTimeout(TA); + MessagePrompt("CC_API : Thread pool delay -> " + CCInt(TA).to_String() + "us"); + m_ThreadPool.InitStart(numThreads); + MessagePrompt("CC_API : Number of core threads -> " + CCInt(numThreads).to_String()); + ServerIP = std::move(IP); + ServerPort = port; + if(!m_Socket.Bind(ServerIP.c_str(), ServerPort)) + { + MessagePrompt("CC_API : Service binding failure"); + return false; + } + MessagePrompt("CC_API : Service binding successful"); + if(!m_Socket.Listen(ListenMax)) + { + MessagePrompt("CC_API : Service listening failure"); + return false; + } + MessagePrompt("CC_API : Service listening succeeded"); + m_Thread.SetThread(&CCWebServlet::ProcessRequest, this); + return true; +} + +int CCWebServlet::Running() { + m_Thread.RunWait(); + return 0; +} + void CCWebServlet::ProcessRequest(){ while (m_Thread.Sign()){ CCSocket client = m_Socket.Accept(); - if(client.GetHost().Port != 0){ - m_ThreadPool.AddTask(&CCWebServlet::ResponseData, this, client); + if(m_Socket.isConnectionAlive()){ + if(client.GetClientHost().Port != 0){ + m_ThreadPool.AddTask(&CCWebServlet::ResponseData, this, client); + } + } + else{ + if(m_Socket.Bind(ServerIP.c_str(), ServerPort)){ + if(m_Socket.Listen(ListenMax)){ + MessagePrompt("CC_API : Socket restart succeeded. Procedure"); + } + else{ + MessagePrompt("CC_API : The Socket service was disconnected unexpectedly."); + Close(); + } + } + else{ + MessagePrompt("CC_API : The Socket service was disconnected unexpectedly."); + Close(); + } } } } void CCWebServlet::ResponseData(CCSocket &socket){ std::vector data; + int Error = 1; while (true){ - char buffer[Buffer_Max] = {0}; - if(socket.IsDataAvailable()){ + if(socket.isDataAvailable()){ + char buffer[Buffer_Max] = {0}; auto len = socket.RecvData(buffer,Buffer_Max); if(len > 0){ - for (int i = 0; i < len; ++i){ - data.push_back(buffer[i]); + for(auto i : buffer){ + data.push_back(i); + } + CCString string1(data.begin(), data.end()); + auto l = string1.find("\r\n\r\n"); + if(l != CCString::npos){ + break; + } + else { + socket.Close(); + return; } } else{ - break; + return; } } else{ - break; + if(Error >= 7){ + break; + } + CCThread::Sleep(1000 * Error * 10); + Error++; + continue; } } - CCString RecvMessage(data.begin(), data.end()); + if(data.empty()) { + if(Print >= PromptLevel::WARNING){ + CCTimeData time; + CCString str = "[" + time.to_String() + "] -> HTTPRequest Data is NULL"; + CC::Println(str); + } + socket.Close(); + return; + } + CCString RecvMessage = CCString(data.begin(), data.end()); data.clear(); RequestProcess Stuart = RequestProcess_First; - auto strlen = RecvMessage.find("\r\n"); std::istringstream stream(RecvMessage.substr()); CCRequest HTTPRequests(socket); BufferReader A; CCResponse HTTPResponse(socket,CORSConfig); - while (true){ + while (!RecvMessage.empty()){ auto strlen = RecvMessage.find("\r\n"); std::istringstream stream(RecvMessage.substr()); - if(strlen == 0) - { + if(strlen == 0){ Stuart = RequestProcess_Body; + for (const auto& str : HTTPRequests.Headers) { + if(str.first == "Sec-WebSocket-Key"){ + CCWebSocketInfo info; + CCString Key = str.second; + CCString s = HTTPResponse.GetWriter().ResopenseWebSocket(Key); + info.SetId(s); + info.SetSocket(socket); + if(IFunc){ + IFunc(info); + } + // 全局缓冲区 + std::vector recvBuffer; + while (socket.isConnectionAlive() && m_Thread.Sign()){ + if(socket.isDataAvailable() && m_Thread.Sign()){ + char buffer[Buffer_Max] = {0}; + auto len = socket.RecvData(buffer,Buffer_Max); + if (len > 0) { + // 合并新数据和未完全解析的数据 + recvBuffer.insert(recvBuffer.end(), buffer, buffer + len); + // 当前合并后的数据长度 + int totalLen = recvBuffer.size(); + while (totalLen > 0) { + std::vector Data; + int Flag = unPackingWSFrameData(recvBuffer.data(), totalLen, Data,info); + try{ + if (Flag == 0) { + // 解析成功,清空全局缓冲区 + Data.push_back('\0'); + info.Buffer = Data; + recvBuffer.erase(recvBuffer.begin(), recvBuffer.begin() + totalLen); + totalLen = 0; + if (MFunc) { + MFunc(info); + } + } + else if (Flag == -2) { + // 包长小于报文中记录的包长,说明数据不完整 + info.ErrorCode = WS_ErrorCode::WS_DATA_ERROR; + if(EFunc){ + EFunc(info); + } + break; + } + else if (Flag == -3) { + // 报文长度小于 2 字节,说明数据不完整 + info.ErrorCode = WS_ErrorCode::WS_DATA_ERROR; + if(EFunc){ + EFunc(info); + } + break; + } + else if (Flag == -1) { + // 断开连接类型的数据包 + Data.push_back('\0'); + info.Buffer = Data; + recvBuffer.erase(recvBuffer.begin(), recvBuffer.begin() + totalLen); + totalLen = 0; + if (CFunc) { + CFunc(info); + } + unsigned char frame[1024] = {0}; // 假设最大长度为 1024 字节 + constructCloseFrame(frame, 1000, "Normal closure"); + CCByteArray frameArray = CCByteArray::fromString((char*)frame); + info.SendMassage(frameArray); + socket.Close(); + break; + } + } + catch (CCException& e){ + if(Print >= PromptLevel::ERROR_t){ + MessagePrompt(e.what()); + } + } + // 更新当前合并后的数据长度 + totalLen -= totalLen; + } + } + else { + return; + } + } + } + } + } } if(strlen != std::string::npos) { if (Stuart == RequestProcess_First) { @@ -75,10 +224,10 @@ void CCWebServlet::ResponseData(CCSocket &socket){ A.Path = A.Path.substr(0, l); } stream >> A.Version; - RecvMessage.erase(0, strlen + 2); Stuart = RequestProcess_Header; - } else if (Stuart == RequestProcess_Header) { + } + else if (Stuart == RequestProcess_Header) { std::string Key, Value; stream >> Key; stream >> Value; @@ -86,40 +235,68 @@ void CCWebServlet::ResponseData(CCSocket &socket){ HTTPRequests.Headers.insert(std::pair(Key, Value)); RecvMessage.erase(0, strlen + 2); } - else - { - RecvMessage.erase(0, strlen + 2); - A.Body = RecvMessage; + else{ + auto st = HTTPRequests.Headers["content-type"]; + if(st.empty()){ + st = HTTPRequests.Headers["Content-Type"]; + } + if(st != "multipart/form-data;" && st != "multipart/form-data"){ + A.Body = RecvMessage; + } + else { + RecvMessage = GetFileHeaders(RecvMessage,socket,HTTPRequests.FileHeaders); + for (auto i : RecvMessage) { + A.Buffer.push_back(i); + } + } + RecvMessage = ""; HTTPRequests.SetBuffer(A); break; } } } if(A.Method == "OPTIONS"){ - HTTPResponse.GetWiter().ResponseOK(); + HTTPResponse.GetWriter().ResponseOK(); } else{ - auto it = RequestFun[HTTPRequests.GetReader().Path]; - if(it) - { - it(HTTPRequests, HTTPResponse); + CCString SPath = HTTPRequests.GetReader().Path; + auto it = RequestFun[SPath]; + if(it){ + try { + it(HTTPRequests, HTTPResponse); + } + catch (const std::exception &e) { + if(Print >= ERROR_t){ + CCTimeData time; + CCString str = "[" + time.to_String() + "] -> " + CC::to_String(e.what()); + CC::Println(str); + } + } } - else - { + else{ bool da = false; - for (int i = 0; i < RootLen; ++i) - { - if (HTTPResponse.GetWiter().HtmlWrite(std::string(PathSix[i] + HTTPRequests.GetReader().Path).c_str())) - { + for (int i = 0; i < RootLen; ++i){ + CCString Path = PathSix[i] + HTTPRequests.GetReader().Path; + if (HTTPResponse.GetWriter().HtmlWrite(Path)){ + Threading::Sleep(1000); da = true; break; } } if (!da) { - char bufsa[100] = {0}; - sprintf(bufsa, "无法打开文件%s\n", HTTPRequests.GetReader().Path.c_str()); - perror(bufsa); + if(WebSignalFun){ + try { + WebSignalFun(HTTPRequests, HTTPResponse); + } + catch (const std::exception &e) { + if(Print >= ERROR_t){ + CCTimeData time; + CCString str = "[" + time.to_String() + "] -> " + CC::to_String(e.what()); + CC::Println(str); + } + } + } } } } @@ -141,8 +318,8 @@ bool CCWebServlet::Sign() const { return FlagRun; } -void CCWebServlet::SetWebServlet(std::string RootPath, CCWebServlet::RequestFunc RFunc) { - RequestFun.insert(std::pair(RootPath, RFunc)); +void CCWebServlet::SetWebServlet(CCString UrlPath, CCWebServlet::RequestFunc RFunc) { + RequestFun.insert(std::pair(UrlPath, RFunc)); } void CCWebServlet::SetAddRootPath(const CCString &rootPath) { @@ -152,3 +329,185 @@ void CCWebServlet::SetAddRootPath(const CCString &rootPath) { void CCWebServlet::SetCorsConfig(CORS &cors) { CORSConfig = cors; } + +CCString CCWebServlet::GetFileHeaders(CCString& str,CCSocket &socket,std::map &map) { + std::vector data; + CCString A,B = str; + while (true){ + if(socket.isDataAvailable()){ + char Buffer[1] = {0}; + auto l = socket.RecvData(Buffer, 1); + if(l > 0){ + for(auto i : Buffer){ + data.push_back(i); + } + A = B + std::string(data.begin(), data.end()); + if(A.find("\r\n\r\n") != std::string::npos){ + break; + } + } + } + else { + break; + } + } + CCString C = GetFileDateHeader(A, map); + return C; +} + +void CCWebServlet::SetWebServletFun(CCWebServlet::RequestFunc RFunc) { + WebSignalFun = std::move(RFunc); +} + +CCThreadPool CCWebServlet::GetServletThreadPool() { + return m_ThreadPool; +} + +std::vector CCWebServlet::GetIPS(){ + return m_Socket.GetLocalIP(); +} + +int CCWebServlet::unPackingWSFrameData(char *msg, int msgLen, std::vector &outBuf,CCWebSocketInfo& wsInfo) { + //报文长度一定大于2字节,对于小于的,做返回处理 + if(msgLen < 2) + { + return -3; + } + + uint8_t opcode_ = 0; + uint8_t mask_ = 0; + uint8_t masking_key_[4] = {0,0,0,0}; + uint64_t payload_length_ = 0; + int pos = 0; + + //Opcode + opcode_ = msg[pos] & 0x0f; + pos++; + //MASK + mask_ = (unsigned char)msg[pos] >> 7; + //Payload length + payload_length_ = msg[pos] & 0x7f; + pos++; + if(payload_length_ == 126) + { + uint16_t length = 0; + memcpy(&length, msg + pos, 2); + pos += 2; + payload_length_ = ntohs(length); + } + else if(payload_length_ == 127) + { + uint32_t length = 0; + memcpy(&length, msg + pos, 8); + pos += 8; + payload_length_ = ntohl(length); + } + //Masking-key + if(mask_ == 1) + { + for(int i = 0; i < 4; i++) + { + masking_key_[i] = msg[pos + i]; + } + pos += 4; + } + + memcpy(wsInfo.Frame.MaskingKey, masking_key_, 4); + wsInfo.Frame.mask = mask_; + wsInfo.Frame.payload_len = payload_length_; + wsInfo.Frame.opcode = opcode_; + //取出消息数据 + if (msgLen >= pos + payload_length_ ) + { + outBuf.clear(); + if(mask_ != 1) + { + char* dataBegin = msg + pos; + outBuf.insert(outBuf.begin(), dataBegin, dataBegin+payload_length_); + } + else + { + for(unsigned int i = 0; i < payload_length_; i++) + { + int j = i % 4; + outBuf.push_back(msg[pos + i] ^ masking_key_[j]); + } + } + + } + else + { + //此时包长小于报文中记录的包长 + return -2; + } + + //断开连接类型数据包 + if ((int)opcode_ == 0x8) + return -1; + + return 0; +} + +void CCWebServlet::SetWSOnMessage(CCWebServlet::RecvDataFunc RFunc) { + MFunc = std::move(RFunc); +} + +void CCWebServlet::SetWSOnClose(CCWebServlet::RecvDataFunc CFunc) { + this->CFunc = std::move(CFunc); +} + +void CCWebServlet::SetWSOnOpen(CCWebServlet::RecvDataFunc IFunc) { + this->IFunc = std::move(IFunc); +} + +void CCWebServlet::constructCloseFrame(unsigned char *frame, int status_code, const char *reason) { +// 设置 Fin Bit 和 Opcode + frame[0] = 0x80 | 0x08; // Fin Bit (1) + Opcode (8) + + // 设置 Payload Length + int payload_length = 2 + strlen(reason); + if (payload_length <= 125) { + frame[1] = static_cast(payload_length); + } else if (payload_length <= 65535) { + frame[1] = 126; + frame[2] = static_cast(payload_length >> 8); + frame[3] = static_cast(payload_length & 0xFF); + payload_length += 2; + } else { + frame[1] = 127; + frame[2] = static_cast(payload_length >> 56); + frame[3] = static_cast(payload_length >> 48); + frame[4] = static_cast(payload_length >> 40); + frame[5] = static_cast(payload_length >> 32); + frame[6] = static_cast(payload_length >> 24); + frame[7] = static_cast(payload_length >> 16); + frame[8] = static_cast(payload_length >> 8); + frame[9] = static_cast(payload_length & 0xFF); + payload_length += 8; + } + + // 设置 Payload Data + memcpy(frame + 2 + (payload_length > 125 ? 2 : 0), &status_code, 2); + memcpy(frame + 4 + (payload_length > 125 ? 2 : 0), reason, strlen(reason)); + + // 设置 Masking Key (假设为固定值 0x00) + unsigned char masking_key[4] = {0x00, 0x00, 0x00, 0x00}; + for (int i = 0; i < payload_length; ++i) { + frame[2 + (payload_length > 125 ? 2 : 0) + i] ^= masking_key[i % 4]; + } +} + +void CCWebServlet::SetWSOnError(CCWebServlet::RecvDataFunc EFunc) { + this->EFunc = std::move(EFunc); +} + +void CCWebServlet::SetPrint(PromptLevel level){ + Print = level; +} + +void CCWebServlet::MessagePrompt(const CCString& message){ + const CCTimeData Time; + const CCString str = "[" + Time.to_String() + "] -> " + message; + CC::Println(str); +} + diff --git a/SDK/CMakeLists.txt b/SDK/CMakeLists.txt index 9072ee9..51c8f56 100644 --- a/SDK/CMakeLists.txt +++ b/SDK/CMakeLists.txt @@ -3,17 +3,40 @@ cmake_minimum_required(VERSION 3.0) add_subdirectory(Depend/portaudio) add_subdirectory(Depend/CSerialPort) add_subdirectory(Depend/mirrors_nlohmann_json) +add_subdirectory(Depend/cppp-reiconv) +add_subdirectory(Environment) +find_path(MYSQL_ROOT_DIR ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1) +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(mysql REQUIRED_VARS MYSQL_ROOT_DIR) +set(INC_DIR ${PROJECT_SOURCE_DIR}/SDK/CCServlet/include) +set(LINK_DIR ${PROJECT_SOURCE_DIR}/SDK/Depend/Lib/libs) +set(LINK_DLL_DIR ${PROJECT_SOURCE_DIR}/SDK/Depend/Bin/bin) +set(CC_API_INC ${PROJECT_SOURCE_DIR}/SDK/Depend/CSerialPort/include + ${PROJECT_SOURCE_DIR}/SDK/Depend/mirrors_nlohmann_json/include + ${PROJECT_SOURCE_DIR}/SDK/Depend/mirrors_nlohmann_json/include/nlohmann + ${PROJECT_SOURCE_DIR}/SDK/Depend/portaudio/include + ${PROJECT_SOURCE_DIR}/SDK/Multimedia + ${PROJECT_SOURCE_DIR}/SDK/CCServlet/SQL + ${PROJECT_SOURCE_DIR}/SDK/CCServlet/include + ${PROJECT_SOURCE_DIR}/SDK/CCServlet/SQL include + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/Control + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/Drive + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/ImGui + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/WindowOS + ${PROJECT_SOURCE_DIR}/SDK/Environment/glfw/include + ${INC_DIR} + ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1/include +) option(UIAPIS "APIS" ON) if (UIAPIS) add_library(CC_API STATIC src/CCThread.cpp src/CCSocket.cpp - CCServlet/src/CCString.cpp + src/CCString.cpp src/CCSerialPort.cpp - CCServlet/src/CCWeb.cpp src/CCAudio.cpp src/CCThreadPool.cpp include/CCThreadPool.h @@ -30,19 +53,67 @@ if (UIAPIS) CCServlet/src/CCSQLite3.cpp CCServlet/include/CCSQLite3.h src/CCEpoll.cpp + src/CCByte.cpp include/CCEpoll.h + include/CCObject.h + src/CCFileOutStream.cpp + src/CCEncode.cpp + include/CCFileOutStream.h + src/CCByteArray.cpp + include/CCByteArray.h + src/CCFIleInStream.cpp + include/CCFIleInStream.h + include/CC.h + src/CCNetwork.cpp + include/CCNetwork.h + src/CCTimeData.cpp + include/CCTimeData.h + src/CCMySql.cpp + include/CCMySql.h + include/CCArray.h + CCServlet/src/CCWebSocketInfo.cpp + CCServlet/include/CCWebSocketInfo.h + src/CCProcess.cpp + include/CCProcess.h + CCServlet/src/CCHttpClient.cpp + ) + target_include_directories(CC_API PUBLIC + ${PROJECT_SOURCE_DIR}/SDK/Depend/CSerialPort/include + ${PROJECT_SOURCE_DIR}/SDK/Depend/mirrors_nlohmann_json/include + ${PROJECT_SOURCE_DIR}/SDK/Depend/mirrors_nlohmann_json/include/nlohmann + ${PROJECT_SOURCE_DIR}/SDK/Depend/portaudio/include + ${PROJECT_SOURCE_DIR}/SDK/Multimedia + ${PROJECT_SOURCE_DIR}/SDK/CCServlet/SQL + ${PROJECT_SOURCE_DIR}/SDK/CCServlet/include + ${PROJECT_SOURCE_DIR}/SDK/CCServlet/SQL include + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/Control + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/Drive + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/ImGui + ${PROJECT_SOURCE_DIR}/SDK/Environment/IMUI/WindowOS + ${PROJECT_SOURCE_DIR}/SDK/Environment/glfw/include + ${INC_DIR} + ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1/include/ + ) - target_include_directories(CC_API PUBLIC Depend/CSerialPort/include Depend/mirrors_nlohmann_json/include - Depend/portaudio/include Multimedia CCServlet/SQL CCServlet/include CCServlet/SQL include) if(CMAKE_HOST_UNIX) target_link_libraries(CC_API PRIVATE libcserialport sqlite3 nlohmann_json PortAudio ${CMAKE_CURRENT_SOURCE_DIR}/Depend/Lib/libs/x86_64/libbass.so + ${LINK_DIR}/libcppp-reiconv.static.a + GUIAPI crypto +# ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1/lib/LinuxLib/libmysqlclient.so + ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1/lib/LinuxLib/libmysqlcppconn.so + ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1/lib/LinuxLib/libmysqlcppconnx.so ) elseif(CMAKE_HOST_WIN32) target_link_libraries(CC_API PRIVATE ws2_32 libcserialport nlohmann_json ${CMAKE_CURRENT_SOURCE_DIR}/Depend/Bin/bin/sqlite3.dll PortAudio ${CMAKE_CURRENT_SOURCE_DIR}/Depend/Lib/libs/x86_64/bass.lib + GUIAPI + ${LINK_DIR}/VC/X64/MD/openssl.lib + ${LINK_DIR}/VC/X64/MD/libcrypto.lib + ${LINK_DIR}/libcppp-reiconv.static-win.a + ${PROJECT_SOURCE_DIR}/SDK/Depend/mysql-9.0.1/lib/libmysql.lib ) else() diff --git a/SDK/Depend/Bin/bin/sqlite3.def b/SDK/Depend/Bin/bin/sqlite3.def deleted file mode 100644 index 140aac0..0000000 --- a/SDK/Depend/Bin/bin/sqlite3.def +++ /dev/null @@ -1,361 +0,0 @@ -EXPORTS -sqlite3_aggregate_context -sqlite3_aggregate_count -sqlite3_auto_extension -sqlite3_autovacuum_pages -sqlite3_backup_finish -sqlite3_backup_init -sqlite3_backup_pagecount -sqlite3_backup_remaining -sqlite3_backup_step -sqlite3_bind_blob -sqlite3_bind_blob64 -sqlite3_bind_double -sqlite3_bind_int -sqlite3_bind_int64 -sqlite3_bind_null -sqlite3_bind_parameter_count -sqlite3_bind_parameter_index -sqlite3_bind_parameter_name -sqlite3_bind_pointer -sqlite3_bind_text -sqlite3_bind_text16 -sqlite3_bind_text64 -sqlite3_bind_value -sqlite3_bind_zeroblob -sqlite3_bind_zeroblob64 -sqlite3_blob_bytes -sqlite3_blob_close -sqlite3_blob_open -sqlite3_blob_read -sqlite3_blob_reopen -sqlite3_blob_write -sqlite3_busy_handler -sqlite3_busy_timeout -sqlite3_cancel_auto_extension -sqlite3_changes -sqlite3_changes64 -sqlite3_clear_bindings -sqlite3_close -sqlite3_close_v2 -sqlite3_collation_needed -sqlite3_collation_needed16 -sqlite3_column_blob -sqlite3_column_bytes -sqlite3_column_bytes16 -sqlite3_column_count -sqlite3_column_database_name -sqlite3_column_database_name16 -sqlite3_column_decltype -sqlite3_column_decltype16 -sqlite3_column_double -sqlite3_column_int -sqlite3_column_int64 -sqlite3_column_name -sqlite3_column_name16 -sqlite3_column_origin_name -sqlite3_column_origin_name16 -sqlite3_column_table_name -sqlite3_column_table_name16 -sqlite3_column_text -sqlite3_column_text16 -sqlite3_column_type -sqlite3_column_value -sqlite3_commit_hook -sqlite3_compileoption_get -sqlite3_compileoption_used -sqlite3_complete -sqlite3_complete16 -sqlite3_config -sqlite3_context_db_handle -sqlite3_create_collation -sqlite3_create_collation_v2 -sqlite3_create_collation16 -sqlite3_create_filename -sqlite3_create_function -sqlite3_create_function_v2 -sqlite3_create_function16 -sqlite3_create_module -sqlite3_create_module_v2 -sqlite3_create_window_function -sqlite3_data_count -sqlite3_data_directory -sqlite3_database_file_object -sqlite3_db_cacheflush -sqlite3_db_config -sqlite3_db_filename -sqlite3_db_handle -sqlite3_db_mutex -sqlite3_db_name -sqlite3_db_readonly -sqlite3_db_release_memory -sqlite3_db_status -sqlite3_declare_vtab -sqlite3_deserialize -sqlite3_drop_modules -sqlite3_enable_load_extension -sqlite3_enable_shared_cache -sqlite3_errcode -sqlite3_errmsg -sqlite3_errmsg16 -sqlite3_error_offset -sqlite3_errstr -sqlite3_exec -sqlite3_expanded_sql -sqlite3_expired -sqlite3_extended_errcode -sqlite3_extended_result_codes -sqlite3_file_control -sqlite3_filename_database -sqlite3_filename_journal -sqlite3_filename_wal -sqlite3_finalize -sqlite3_free -sqlite3_free_filename -sqlite3_free_table -sqlite3_get_autocommit -sqlite3_get_auxdata -sqlite3_get_clientdata -sqlite3_get_table -sqlite3_global_recover -sqlite3_hard_heap_limit64 -sqlite3_initialize -sqlite3_interrupt -sqlite3_is_interrupted -sqlite3_keyword_check -sqlite3_keyword_count -sqlite3_keyword_name -sqlite3_last_insert_rowid -sqlite3_libversion -sqlite3_libversion_number -sqlite3_limit -sqlite3_load_extension -sqlite3_log -sqlite3_malloc -sqlite3_malloc64 -sqlite3_memory_alarm -sqlite3_memory_highwater -sqlite3_memory_used -sqlite3_mprintf -sqlite3_msize -sqlite3_mutex_alloc -sqlite3_mutex_enter -sqlite3_mutex_free -sqlite3_mutex_leave -sqlite3_mutex_try -sqlite3_next_stmt -sqlite3_open -sqlite3_open_v2 -sqlite3_open16 -sqlite3_os_end -sqlite3_os_init -sqlite3_overload_function -sqlite3_prepare -sqlite3_prepare_v2 -sqlite3_prepare_v3 -sqlite3_prepare16 -sqlite3_prepare16_v2 -sqlite3_prepare16_v3 -sqlite3_preupdate_blobwrite -sqlite3_preupdate_count -sqlite3_preupdate_depth -sqlite3_preupdate_hook -sqlite3_preupdate_new -sqlite3_preupdate_old -sqlite3_profile -sqlite3_progress_handler -sqlite3_randomness -sqlite3_realloc -sqlite3_realloc64 -sqlite3_release_memory -sqlite3_reset -sqlite3_reset_auto_extension -sqlite3_result_blob -sqlite3_result_blob64 -sqlite3_result_double -sqlite3_result_error -sqlite3_result_error_code -sqlite3_result_error_nomem -sqlite3_result_error_toobig -sqlite3_result_error16 -sqlite3_result_int -sqlite3_result_int64 -sqlite3_result_null -sqlite3_result_pointer -sqlite3_result_subtype -sqlite3_result_text -sqlite3_result_text16 -sqlite3_result_text16be -sqlite3_result_text16le -sqlite3_result_text64 -sqlite3_result_value -sqlite3_result_zeroblob -sqlite3_result_zeroblob64 -sqlite3_rollback_hook -sqlite3_rtree_geometry_callback -sqlite3_rtree_query_callback -sqlite3_serialize -sqlite3_set_authorizer -sqlite3_set_auxdata -sqlite3_set_clientdata -sqlite3_set_last_insert_rowid -sqlite3_shutdown -sqlite3_sleep -sqlite3_snprintf -sqlite3_soft_heap_limit -sqlite3_soft_heap_limit64 -sqlite3_sourceid -sqlite3_sql -sqlite3_status -sqlite3_status64 -sqlite3_step -sqlite3_stmt_busy -sqlite3_stmt_explain -sqlite3_stmt_isexplain -sqlite3_stmt_readonly -sqlite3_stmt_status -sqlite3_str_append -sqlite3_str_appendall -sqlite3_str_appendchar -sqlite3_str_appendf -sqlite3_str_errcode -sqlite3_str_finish -sqlite3_str_length -sqlite3_str_new -sqlite3_str_reset -sqlite3_str_value -sqlite3_str_vappendf -sqlite3_strglob -sqlite3_stricmp -sqlite3_strlike -sqlite3_strnicmp -sqlite3_system_errno -sqlite3_table_column_metadata -sqlite3_temp_directory -sqlite3_test_control -sqlite3_thread_cleanup -sqlite3_threadsafe -sqlite3_total_changes -sqlite3_total_changes64 -sqlite3_trace -sqlite3_trace_v2 -sqlite3_transfer_bindings -sqlite3_txn_state -sqlite3_update_hook -sqlite3_uri_boolean -sqlite3_uri_int64 -sqlite3_uri_key -sqlite3_uri_parameter -sqlite3_user_data -sqlite3_value_blob -sqlite3_value_bytes -sqlite3_value_bytes16 -sqlite3_value_double -sqlite3_value_dup -sqlite3_value_encoding -sqlite3_value_free -sqlite3_value_frombind -sqlite3_value_int -sqlite3_value_int64 -sqlite3_value_nochange -sqlite3_value_numeric_type -sqlite3_value_pointer -sqlite3_value_subtype -sqlite3_value_text -sqlite3_value_text16 -sqlite3_value_text16be -sqlite3_value_text16le -sqlite3_value_type -sqlite3_version -sqlite3_vfs_find -sqlite3_vfs_register -sqlite3_vfs_unregister -sqlite3_vmprintf -sqlite3_vsnprintf -sqlite3_vtab_collation -sqlite3_vtab_config -sqlite3_vtab_distinct -sqlite3_vtab_in -sqlite3_vtab_in_first -sqlite3_vtab_in_next -sqlite3_vtab_nochange -sqlite3_vtab_on_conflict -sqlite3_vtab_rhs_value -sqlite3_wal_autocheckpoint -sqlite3_wal_checkpoint -sqlite3_wal_checkpoint_v2 -sqlite3_wal_hook -sqlite3_win32_is_nt -sqlite3_win32_mbcs_to_utf8 -sqlite3_win32_mbcs_to_utf8_v2 -sqlite3_win32_set_directory -sqlite3_win32_set_directory16 -sqlite3_win32_set_directory8 -sqlite3_win32_sleep -sqlite3_win32_unicode_to_utf8 -sqlite3_win32_utf8_to_mbcs -sqlite3_win32_utf8_to_mbcs_v2 -sqlite3_win32_utf8_to_unicode -sqlite3_win32_write_debug -sqlite3changegroup_add -sqlite3changegroup_add_strm -sqlite3changegroup_delete -sqlite3changegroup_new -sqlite3changegroup_output -sqlite3changegroup_output_strm -sqlite3changegroup_schema -sqlite3changeset_apply -sqlite3changeset_apply_strm -sqlite3changeset_apply_v2 -sqlite3changeset_apply_v2_strm -sqlite3changeset_concat -sqlite3changeset_concat_strm -sqlite3changeset_conflict -sqlite3changeset_finalize -sqlite3changeset_fk_conflicts -sqlite3changeset_invert -sqlite3changeset_invert_strm -sqlite3changeset_new -sqlite3changeset_next -sqlite3changeset_old -sqlite3changeset_op -sqlite3changeset_pk -sqlite3changeset_start -sqlite3changeset_start_strm -sqlite3changeset_start_v2 -sqlite3changeset_start_v2_strm -sqlite3rbu_bp_progress -sqlite3rbu_close -sqlite3rbu_create_vfs -sqlite3rbu_db -sqlite3rbu_destroy_vfs -sqlite3rbu_open -sqlite3rbu_progress -sqlite3rbu_rename_handler -sqlite3rbu_savestate -sqlite3rbu_state -sqlite3rbu_step -sqlite3rbu_temp_size -sqlite3rbu_temp_size_limit -sqlite3rbu_vacuum -sqlite3rebaser_configure -sqlite3rebaser_create -sqlite3rebaser_delete -sqlite3rebaser_rebase -sqlite3rebaser_rebase_strm -sqlite3session_attach -sqlite3session_changeset -sqlite3session_changeset_size -sqlite3session_changeset_strm -sqlite3session_config -sqlite3session_create -sqlite3session_delete -sqlite3session_diff -sqlite3session_enable -sqlite3session_indirect -sqlite3session_isempty -sqlite3session_memory_used -sqlite3session_object_config -sqlite3session_patchset -sqlite3session_patchset_strm -sqlite3session_table_filter diff --git a/SDK/Install.sh b/SDK/Install.sh index 729c469..cecb637 100644 --- a/SDK/Install.sh +++ b/SDK/Install.sh @@ -1,15 +1,16 @@ -git clone https://gitee.com/itas109/CSerialPort.git -git clone https://gitee.com/learnlov/mirrors_nlohmann_json.git +sudo apt-get install libssl3-dev +sudo apt install libssl-dev +sudo apt-get install libcurl4-openssl-dev +sudo apt-get install libsqlite3-dev +sudo apt-get install libc6-dev +sudo apt-get install libglfw3-dev +sudo apt install plasma-workspace-wayland +sudo apt-get install libxkbcommon-dev +sudo apt-get install libx11-dev +sudo apt-get install libxinerama-dev +sudo apt-get install libxcursor-dev +sudo apt-get install libxi-dev +sudo apt install pkg-config +sudo dpkg -i ./Depend/mysql-community-server-core_8.4.2-1debian12_amd64.deb -git clone https://github.com/PortAudio/portaudio.git - -unzip ./Depend/sqlite-amalgamation-3450300.zip - -cd sqlite-amalgamation-3450300 - -./configure --prefix=/usr/local - -sudo make -j8 - -sudo make install diff --git a/SDK/include/CCEpoll.h b/SDK/include/CCEpoll.h index 7314a45..5d681c1 100644 --- a/SDK/include/CCEpoll.h +++ b/SDK/include/CCEpoll.h @@ -29,6 +29,7 @@ public: void Create(CCSocket& socket,int size = 10); CCSocket Accept(CCSocket& socket); bool Status(); + bool CompletionKey(); private: diff --git a/SDK/include/CCFile.h b/SDK/include/CCFile.h index 24a8044..d908d15 100644 --- a/SDK/include/CCFile.h +++ b/SDK/include/CCFile.h @@ -1,12 +1,15 @@ #ifndef IMGUICPPDEMO_CCIOS_H #define IMGUICPPDEMO_CCIOS_H +#include + #include "cstdio" -#include "dirent.h" #include "vector" #include "CCString.h" #include "mutex" -#include // 包含 _access 和 mkdir #include // 包含 mkdir 的权限模式 +#include "CCByteArray.h" +#include +#include namespace CC { @@ -32,7 +35,7 @@ struct FileInfo { CCString Path; CCString Name; - long Size = 0; + long long Size = 0; bool Directory = false; }; @@ -71,10 +74,10 @@ private: private: void rmtree(const char *path); int is_directory(const char *path); - long GetFileSize(const char *filename); + long long GetFileSize(const char *filename); const char *GetFileName(const char *path); std::vector GetFileList(const char *path); - static std::string normalizePath(const std::string &path); + static std::string normalizePath(const CCString &path); void move_file(const char *src, const char *dst); int copy_file(const char *source, const char *destination); static int create_fun(char*filepath); diff --git a/SDK/include/CCJSONObject.h b/SDK/include/CCJSONObject.h index 26c5bd7..02313c3 100644 --- a/SDK/include/CCJSONObject.h +++ b/SDK/include/CCJSONObject.h @@ -1,25 +1,22 @@ #ifndef THREADPOOLDEMO_CCJSONOBJECT_H #define THREADPOOLDEMO_CCJSONOBJECT_H #include "nlohmann/json.hpp" +#include "CC.h" using JSON = nlohmann::json; -namespace CCJSON -{ - JSON Parse(const char* str); -} - class CCJSONObject: public JSON { public: + using nlohmann::json::json; CCJSONObject() = default; CCJSONObject(JSON && j); - void Put(const char* key,nlohmann::json value); - JSON Get(const char* key); - std::string To_String(); + void put(const char* key,nlohmann::json value); + JSON get(const char* key); + std::string to_String(); + static CCJSONObject parse(const String& str); private: - JSON j; - + JSON J; }; -#endif //THREADPOOLDEMO_CCJSONOBJECT_H +#endif diff --git a/SDK/include/CCSocket.h b/SDK/include/CCSocket.h index c0e8374..1a9e3b1 100644 --- a/SDK/include/CCSocket.h +++ b/SDK/include/CCSocket.h @@ -1,8 +1,10 @@ #define __CCSocket__ +#include +#include #ifdef __CCSocket__ #pragma once -#include "iostream" +#include "CC.h" #include "string" struct CCHostInfo @@ -11,6 +13,11 @@ struct CCHostInfo unsigned short Port; }; +enum CCOpt +{ + BROADCAST, +}; + #ifdef _WIN32 #include @@ -18,11 +25,31 @@ struct CCHostInfo #include #pragma warning(disable : 4996) -#pragma comment(lib,"ws2_32.lib") //<2F><> 0 3 0 4 +#pragma comment(lib,"ws2_32.lib") typedef long long ByteHander; #define HanderSize sizeof(ByteHander) +class WinWSADWAInitAndClean +{ +public: + WSADATA wsd{}; + WinWSADWAInitAndClean(){ + if (WSAStartup(MAKEWORD(2, 2), &this->wsd)!=0){ + WSACleanup(); + } + } + ~WinWSADWAInitAndClean(){ + WSACleanup(); + } +}; + +inline WinWSADWAInitAndClean winsc; +// if (WSAStartup(MAKEWORD(2, 2), &this->wsd)!=0) +// { +// WSACleanup(); +// return sc; +// } enum IPVX { @@ -50,17 +77,20 @@ public: public: CCSocket() = default; CCSocket Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type = TYPE::STREAM); + bool SetSockOpt(CCOpt opt); void SetSocketNonBlocking(); - bool IsDataAvailable(); - std::string GetlocadIP(IPVX ipvx = IPVX::IPV4,int Number = 1); - CCHostInfo GetHost(); + bool isDataAvailable(); + static std::vector GetLocalIP(IPVX ipvx = IPVX::IPV4,int Number = 1); + CCHostInfo GetClientHost(); + CCHostInfo GetLocalHost(); bool Connect(const char* IP, unsigned short Port); bool Bind(const char* IP,unsigned short Port); bool Listen(unsigned short UserNum = 10); CCSocket Accept(); bool Send(const char* str); bool Send(const void *__buf, size_t __n, int __flags); - bool Sendbyte(const char* str,int len); + bool SendData(const char * str,sockaddr_in addr_in); + bool SendByte(const char* str,int len); bool UDPSend(const char* str,const char* IP,int Port); bool UDPSendByte(const char* str, ByteHander len, const char* IP, int Port); ByteHander RecvData(char* buffer,ByteHander lens); @@ -70,14 +100,13 @@ public: bool GetStrHead(char* data,ByteHander size); bool operator == (CCSocket socket); bool operator != (CCSocket socket); + bool isConnectionAlive(); private: - WSADATA wsd; - sockaddr_in client = {}; + sockaddr_in client = {}, server = {}; int IPVx = 0; int sock = -1; bool Stop = false; - }; @@ -122,17 +151,20 @@ public: public: CCSocket() = default; CCSocket Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type = TYPE::STREAM); + bool SetSockOpt(CCOpt opt); void SetSocketNonBlocking(); - bool IsDataAvailable(); - std::string GetlocadIP(IPVX ipvx = IPVX::IPV4,int Number = 1); - CCHostInfo GetHost(); + bool isDataAvailable(); + static std::vector GetLocalIP(IPVX ipvx = IPVX::IPV4,int Number = 1); + CCHostInfo GetClientHost(); + CCHostInfo GetLocalHost(); bool Connect(const char* IP, unsigned short Port); bool Bind(const char* IP,int Port); bool Listen(unsigned short UserNum = 10); CCSocket Accept(); bool Send(const char* str); bool Send(const void *__buf, size_t __n, int __flags); - bool Sendbyte(const char* str,int len); + bool SendData(const char * str,sockaddr_in addr_in); + bool SendByte(const char* str,int len); bool UDPSend(const char* str,const char* IP,int Port); bool UDPSendByte(const char* str, ByteHander len, const char* IP, int Port); ByteHander RecvData(char* buffer,ByteHander lens); @@ -143,10 +175,10 @@ public: //---------------------------------------------------------------------------------------- bool operator == (CCSocket socket); bool operator != (CCSocket socket); - + bool isConnectionAlive(); private: - sockaddr_in client = {}; + sockaddr_in client = {},server = {}; int IPVx = 0; int opt = 1; bool Stop = false; diff --git a/SDK/include/CCThread.h b/SDK/include/CCThread.h index afaf3b7..5bbc993 100644 --- a/SDK/include/CCThread.h +++ b/SDK/include/CCThread.h @@ -25,12 +25,13 @@ namespace Threading #define FUNA void* -class CCThread +class CCThread:public std::thread { public: CCThread(); CCThread(std::thread a); CCThread(CCThread&& other); + using std::thread::thread; ~CCThread(); template bool SetThread(Func&& fun, Args&&... args) @@ -50,10 +51,23 @@ public: Thread = std::thread(task); Thread.detach(); } + } + void RunWait() { + if (task) { + Flag = true; + Thread = std::thread(task); + Thread.join(); + } } void Stop(); bool Sign(); - + static void Sleep(unsigned int us){ + if(us!=0) + std::this_thread::sleep_for(std::chrono::microseconds(us)); + else{ + while (true); + } + }; private: std::thread Thread; diff --git a/SDK/include/CCThreadPool.h b/SDK/include/CCThreadPool.h index be19dd8..3533326 100644 --- a/SDK/include/CCThreadPool.h +++ b/SDK/include/CCThreadPool.h @@ -1,68 +1,100 @@ -#ifndef CCTHREADPOOL_H -#define CCTHREADPOOL_H +#ifndef __CC_ThreadPool_H__ +#define __CC_ThreadPool_H__ +#pragma once -#include +#include "iostream" #include -#include +#include "deque" #include #include #include #include "CCThread.h" - - +#include "CC.h" class CCThreadPool { public: struct TaskPool { - std::thread* thread; bool Running = false; + int ID = -1; + bool Sign = false; + bool Online = false; + std::function TaskFun = nullptr; }; public: CCThreadPool() = default; explicit CCThreadPool(int numThreads); - void InitStart(int numThreads); + CCThreadPool(CCThreadPool& other); + void InitStart(int corePoolSize); + void InitStart(int corePoolSize, int maximumPoolSize,int keepAliveTime); template void AddTask(Func && func, Args&&... args); - unsigned int GetThreadCount() const; - unsigned int GetUnusedCount(); - void SetThreadTimeout(unsigned int us); - std::vector GetThreadUnusedID(); - void Stop(); + int GetThreadCount() const; + int GetUnusedCount() const; + int GetCorePoolSize() const; + int GetPoolMaxSize() const; + int GetTaskRunningSize() const; + void SetPrint(bool F); + void SetThreadTimeout(int us); + void Stop(bool F = true); private: void worker(int ID); - std::vector m_thread; - TaskPool* T; + template + void AdHocTasks(Func && func, Args&&... args); std::vector> m_taskQueue; + std::map m_threads; std::mutex m_mutex; - bool m_running; - unsigned int m_threadCount, m_thread_Time = 1000 * 1000; - - + int m_corePoolSize = 5, m_maximumPoolSize = 30, m_keepAliveTime = 1000 * 1000 * 16; + int TaskRunningSize = 0,TemporaryThreads = 0; + bool Print = false; }; template inline void CCThreadPool::AddTask(Func && func, Args&&... args) { - m_mutex.lock(); + if(TaskRunningSize >= m_maximumPoolSize){ + CC::Println("CCThreadPool::AddTask: Threaded tasks exceed the maximum, wait!"); + return; + } std::function FUNS = std::bind(std::forward(func), std::forward(args)...); - if(FUNS) - { - for (int i = 0;i < m_threadCount;i++) - { - if(!m_thread[i]->Running) - { - m_taskQueue[i] = FUNS; - m_thread[i]->Running = true; - break; + if(FUNS){ + m_mutex.lock(); + CCVar Len = GetUnusedCount(); + if(Len > 0){ + for(auto &[fst, snd] : m_threads) { + if(!snd.Running) { + snd.TaskFun = FUNS; + snd.Running = true; + break; + } } } + else { + AdHocTasks(FUNS); + } + m_mutex.unlock(); + } + else { + CC::Println("CCThreadPool::AddTask: The task is empty!"); } - //Threading::Sleep(1000 * 16); - m_mutex.unlock(); } +template +inline void CCThreadPool::AdHocTasks(Func &&func, Args &&... args) { + CCThread([this,func](){ + TemporaryThreads++; + try { + func(); + } + catch (CCException& e) { + String str = "CCThreadPool::AdHocTasks: The temporary task failed -> " + CC::to_String(e.what()); + CC::Println(str); + } + TemporaryThreads--; + CCThread::Sleep(m_keepAliveTime); + }).detach(); +} -#endif //CCTHREADPOOL_H +#endif diff --git a/SDK/include/CCVector.hpp b/SDK/include/CCVector.hpp deleted file mode 100644 index 135f9f7..0000000 --- a/SDK/include/CCVector.hpp +++ /dev/null @@ -1,100 +0,0 @@ -#ifndef STM32API_CCVECTOR_HPP -#define STM32API_CCVECTOR_HPP - -#include - -template -class CCVector -{ -public: - typedef T value_type; - typedef T* iterator; - CCVector() : _start(nullptr), _finish(nullptr), _end(nullptr) - { - _buffer[ID] = 0; - } - void push_back(const value_type &x); - T pop_back(); - value_type operator[] (int id) const - { - return _buffer[id]; - } - void clear() - { - _buffer = (value_type*)malloc(sizeof(value_type) * 2); - ID = 0; - _buffer[ID] = 0; - } - unsigned int size() - { - return ID; - } - bool empty() - { - return ID == 0; - } - void reserve(unsigned int size) - { - _buffer = (value_type*)realloc(_buffer, sizeof(value_type) * size); - } - bool operator==(const value_type &x) - { - return _buffer[ID] == x; - } - void erase(int index,int len) - { - int a = ID - (len - index); - value_type* b = (value_type*)malloc(sizeof(value_type) * a); - for (int i = 0; i < index; ++i) - { - b[i] = _buffer[i]; - } - for (int i = index; i < a; ++i) - { - b[i] = _buffer[i+len]; - } - ID = ID - len; - _buffer = b; - } - void revise(int index,value_type x) - { - _buffer[index] = x; - } - void insert(int index, value_type x) - { - push_back(_buffer[ID-1]); - for(int i = index; i < ID; i++) - { - _buffer[i + 1] = _buffer[i]; - } - _buffer[index] = x; - } - - -private: - iterator _start; - iterator _finish; - iterator _end; - value_type* _buffer = (value_type*)malloc(sizeof(value_type) * 2); - unsigned int ID = 0; - - -}; - -template -T CCVector::pop_back() -{ - return _buffer[--ID]; -} - - -template -inline void CCVector::push_back(const value_type &x) -{ - _buffer[ID++] = x; - _buffer = (value_type*)realloc(_buffer, sizeof(value_type) * (ID + 1)); - _buffer[ID] = 0; -} - - -#endif diff --git a/SDK/src/CCEpoll.cpp b/SDK/src/CCEpoll.cpp index b44a702..5dce554 100644 --- a/SDK/src/CCEpoll.cpp +++ b/SDK/src/CCEpoll.cpp @@ -6,7 +6,7 @@ CCEpoll::CCEpoll(CCSocket& socket,int size) { void CCEpoll::Create(CCSocket &socket, int size) { #ifdef _WIN32 - this->hIoCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, 0); + this->hIoCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0); CreateIoCompletionPort((HANDLE)socket.Socketbit, hIoCompletionPort, (ULONG_PTR)socket.Socketbit, 0); #elif __linux__ @@ -35,3 +35,11 @@ bool CCEpoll::Status() { #endif } + +bool CCEpoll::CompletionKey() { +#ifdef _WIN32 + return completionKey == (ULONG_PTR)listenSocket.Socketbit; +#elif __linux__ + +#endif +} diff --git a/SDK/src/CCFile.cpp b/SDK/src/CCFile.cpp index 46ddb0f..7ddec84 100644 --- a/SDK/src/CCFile.cpp +++ b/SDK/src/CCFile.cpp @@ -1,18 +1,21 @@ #include -#include #include #include #include "../include/CCFile.h" - #include + CCFile::CCFile(const char *path, CC::RIos mode,bool load){ this->Open(path, mode,load); } void CCFile::Open(const char *path, CC::RIos mode,bool load) { +#ifdef _WIN32 + CCString A = CCByteArray::fromString(path).Format(); + path = A.c_str(); +#endif Mode = mode; if(mode == 3 || mode == 4 || mode == 5 || mode == 9 || mode == 10 || mode == 11){ bin = true; @@ -117,7 +120,7 @@ bool CCFile::IsDirectory() { return is_directory(info.Path.c_str()) != 0; } -long CCFile::GetFileSize(const char *filename) { +long long CCFile::GetFileSize(const char *filename) { mtx.lock(); FILE *file = fopen(filename, "rb"); if (file == NULL) { @@ -132,7 +135,7 @@ long CCFile::GetFileSize(const char *filename) { return -1; } // 获取文件指针的位置 - long size = ftell(file); + long long size = ftell(file); // 关闭文件 mtx.unlock(); fclose(file); @@ -190,7 +193,7 @@ std::vector CCFile::GetDirectoryList(bool F) { } } -std::string CCFile::normalizePath(const std::string &path) { +std::string CCFile::normalizePath(const CCString &path) { std::string normalized; bool lastWasSlash = false; // 标记上一个字符是否为斜杠 @@ -221,13 +224,13 @@ void CCFile::Move(CCString Path) { int CCFile::copy_file(const char *source, const char *destination) { FILE *in = fopen(source, "rb"); - if (in == nullptr) { + if (in == NULL) { perror("Failed to open source file"); return 1; } FILE *out = fopen(destination, "wb"); - if (out == nullptr) { + if (out == NULL) { perror("Failed to open destination file"); fclose(in); return 1; @@ -279,6 +282,7 @@ int CCFile::create_fun(char *filepath) { //创建文件夹 res = mkdir(filepath,0775);// 返回 0 表示创建成功,-1 表示失败 #endif + //remove(filename) 删除文件 else res = 1; diff --git a/SDK/src/CCJSONObject.cpp b/SDK/src/CCJSONObject.cpp index 412e597..f595e71 100644 --- a/SDK/src/CCJSONObject.cpp +++ b/SDK/src/CCJSONObject.cpp @@ -1,26 +1,27 @@ #include "../include/CCJSONObject.h" -void CCJSONObject::Put(const char *key, nlohmann::json value) { - j[key] = value; +void CCJSONObject::put(const char *key, nlohmann::json value) { + J[key] = value; } -JSON CCJSONObject::Get(const char *key) { - return j[key]; +JSON CCJSONObject::get(const char *key) { + return J[key]; } -JSON CCJSON::Parse(const char *str) { - try { - return nlohmann::json::parse(str); - } - catch (const std::exception& e) { - return nullptr; - } -} - -std::string CCJSONObject::To_String() { - return to_string(j); +std::string CCJSONObject::to_String() { + return J.dump(); } CCJSONObject::CCJSONObject(JSON &&j) { - this->j = j; + J = j; } + +CCJSONObject CCJSONObject::parse(const String &str) { + try { + return nlohmann::json::parse(str); + } + catch (...) { + return nullptr; + } +} + diff --git a/SDK/src/CCSocket.cpp b/SDK/src/CCSocket.cpp index ba4dee5..39e942a 100644 --- a/SDK/src/CCSocket.cpp +++ b/SDK/src/CCSocket.cpp @@ -7,17 +7,9 @@ CCSocket CCSocket::Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type) { - CCSocket sc; - WSACleanup(); - if (WSAStartup(MAKEWORD(2, 2), &this->wsd)!=0) - { - WSACleanup(); - return sc; - } + CCSocket sc{}; this->Socketbit = socket(IPV4orIPV6, Type, TCPorUDP); - if (this->Socketbit == INVALID_SOCKET) - { - WSACleanup(); + if (this->Socketbit == INVALID_SOCKET){ return sc; } this->sock = TCPorUDP; @@ -28,35 +20,38 @@ CCSocket CCSocket::Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type) return sc; } -std::string CCSocket::GetlocadIP(IPVX ipvx,int Number) -{ - WSADATA wsaData; - int result = WSAStartup(MAKEWORD(2, 2), &wsaData); - if (result != 0) { - std::cerr << "WSAStartup failed: " << result << std::endl; - return "Error"; +bool CCSocket::SetSockOpt(CCOpt opt){ + if(opt == CCOpt::BROADCAST) + { + int broadcastPermission = 1; + if (setsockopt(this->Socketbit, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcastPermission, sizeof(broadcastPermission)) < 0) { + return false; + } } + return true; +} +std::vector CCSocket::GetLocalIP(IPVX ipvx,int Number) +{ + std::vector IPList; + int result = 0; // 获取主机名 char hostName[NI_MAXHOST]; if (gethostname(hostName, NI_MAXHOST) != 0) { std::cerr << "gethostname failed" << std::endl; WSACleanup(); - return "Error"; + return {}; } - struct addrinfo hints, *info; ZeroMemory(&hints, sizeof(hints)); hints.ai_family = AF_UNSPEC; // AF_INET for IPv4 only hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; - // 获取地址信息 result = getaddrinfo(hostName, NULL, &hints, &info); if (result != 0) { std::cerr << "getaddrinfo failed: " << result << std::endl; - WSACleanup(); - return "Error"; + return {}; } char ipString[INET6_ADDRSTRLEN] = {0}; // 遍历所有地址信息并打印IPv4地址 @@ -73,15 +68,12 @@ std::string CCSocket::GetlocadIP(IPVX ipvx,int Number) // 将地址转换为字符串 inet_ntop(p->ai_family, addr, ipString, sizeof(ipString)); - + IPList.emplace_back(ipString); // std::cout << "IPv4 address: " << ipString << std::endl; } - // 释放地址信息 freeaddrinfo(info); - - WSACleanup(); - return ipString; + return IPList; } bool CCSocket::Connect(const char* IP, unsigned short Port) @@ -101,22 +93,17 @@ bool CCSocket::Connect(const char* IP, unsigned short Port) return true; } -bool CCSocket::Bind(const char* IP, unsigned short Port) -{ - sockaddr_in serveraddr; - memset(&serveraddr, 0, sizeof(serveraddr)); - serveraddr.sin_family = AF_INET; - serveraddr.sin_port = htons(Port); - serveraddr.sin_addr.s_addr = inet_addr(IP); - - int i = bind(this->Socketbit, (sockaddr*)&serveraddr, sizeof(serveraddr)); +bool CCSocket::Bind(const char* IP, unsigned short Port){ + memset(&server, 0, sizeof(server)); + server.sin_family = AF_INET; + server.sin_port = htons(Port); + server.sin_addr.s_addr = inet_addr(IP); + int i = bind(this->Socketbit, (sockaddr*)&server, sizeof(server)); if (i == SOCKET_ERROR) { closesocket(this->Socketbit); - WSACleanup(); return false; } - return true; } @@ -127,7 +114,6 @@ bool CCSocket::Listen(unsigned short UserNum) if (iLisRet == SOCKET_ERROR) { closesocket(this->Socketbit); - WSACleanup(); return false; } return true; @@ -156,7 +142,7 @@ bool CCSocket::Send(const char* str) return true; } -bool CCSocket::Sendbyte(const char* str, int len) +bool CCSocket::SendByte(const char* str, int len) { int ires = send(this->Socketbit, str, len, 0); //<2F><>ַȥ if (ires == -1) @@ -220,7 +206,6 @@ void CCSocket::Close() { Stop = false; closesocket(this->Socketbit); - //WSACleanup(); } bool CCSocket::GetDateHead(char* data, ByteHander* size) @@ -234,7 +219,6 @@ bool CCSocket::GetDateHead(char* data, ByteHander* size) return false; } - bool CCSocket::GetStrHead(char* data, ByteHander size) { for (int i = 0; i < HanderSize; i++) @@ -260,6 +244,11 @@ bool CCSocket::Send(const void *__buf, size_t __n, int __flags) return true; } +bool CCSocket::SendData(const char* str, sockaddr_in addr_in){ + bool F = sendto(this->Socketbit, str, strlen(str), 0, (sockaddr*)&addr_in, sizeof(addr_in)) != SOCKET_ERROR; + return F; +} + bool CCSocket::operator==(CCSocket socket) { if(socket.Socketbit == this->Socketbit) @@ -278,7 +267,7 @@ bool CCSocket::operator!=(CCSocket socket) return false; } -CCHostInfo CCSocket::GetHost() +CCHostInfo CCSocket::GetClientHost() { CCHostInfo hostInfo; char IP[INET_ADDRSTRLEN] = {0}; @@ -288,6 +277,15 @@ CCHostInfo CCSocket::GetHost() return hostInfo; } +CCHostInfo CCSocket::GetLocalHost(){ + CCHostInfo hostInfo; + char IP[INET_ADDRSTRLEN] = {0}; + inet_ntop(IPVx, &server.sin_addr, IP, INET_ADDRSTRLEN); + hostInfo.IPAddress = IP; + hostInfo.Port = ntohs(server.sin_port); + return hostInfo; +} + void CCSocket::SetSocketNonBlocking() { u_long mode = 1; @@ -297,7 +295,7 @@ void CCSocket::SetSocketNonBlocking() } } -bool CCSocket::IsDataAvailable() +bool CCSocket::isDataAvailable() { fd_set readfds; FD_ZERO(&readfds); @@ -312,6 +310,25 @@ bool CCSocket::IsDataAvailable() return FD_ISSET(this->Socketbit, &readfds); } +bool CCSocket::isConnectionAlive() { + fd_set fds; + FD_ZERO(&fds); + FD_SET(Socketbit, &fds); + timeval timeout = { 0, 0 }; // 非阻塞模式立即返回 + int ret = select(Socketbit + 1, &fds, NULL, &fds, &timeout); + if (ret < 0) { + // 错误处理 + return false; + } else if (ret > 0) { + if (FD_ISSET(Socketbit, &fds)) { + if (FD_ISSET(Socketbit, &fds)) { + // 检查异常条件 + return false; + } + } + } + return true; +} @@ -339,8 +356,20 @@ CCSocket CCSocket::Socket(IPVX IPV4orIPV6, TORU TCPorUDP, TYPE Type) return sc; } -std::string CCSocket::GetlocadIP(IPVX ipvx,int Number) +bool CCSocket::SetSockOpt(CCOpt opt){ + if(opt == CCOpt::BROADCAST) + { + int broadcastPermission = 1; + if (setsockopt(this->Socketbit, SOL_SOCKET, SO_BROADCAST, (const char*)&broadcastPermission, sizeof(broadcastPermission)) < 0) { + return false; + } + } + return true; +} + +std::vector CCSocket::GetLocalIP(IPVX ipvx,int Number) { + std::vector IPList; struct ifaddrs *ifAddrStruct = nullptr; struct ifaddrs *ifa = nullptr; void *tmpAddrPtr = nullptr; @@ -354,13 +383,14 @@ std::string CCSocket::GetlocadIP(IPVX ipvx,int Number) tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; inet_ntop(AF_INET, tmpAddrPtr, addressBuffer[d++], INET_ADDRSTRLEN); + IPList.emplace_back(addressBuffer[d-1]); //std::cout << "IPv4 Address: " << addressBuffer << std::endl; } } if (ifAddrStruct != nullptr) freeifaddrs(ifAddrStruct); - return addressBuffer[Number]; + return IPList; } bool CCSocket::Connect(const char* IP, unsigned short Port) @@ -387,11 +417,10 @@ bool CCSocket::Bind(const char* IP,int Port) { // 设置地址结构 struct sockaddr_in server_addr; - memset(&server_addr, '0', sizeof(server_addr)); + memset(&server_addr, 0, sizeof(server_addr)); server_addr.sin_family = IPVx; - server_addr.sin_port = htons(8080); - server_addr.sin_addr.s_addr = INADDR_ANY; - + server_addr.sin_port = htons(Port); + server_addr.sin_addr.s_addr = inet_addr(IP); // 绑定套接字到地址和端口 if (bind(this->Socketbit, (struct sockaddr *)&server_addr, sizeof(server_addr)) < 0) { std::cerr << "Bind failed" << std::endl; @@ -433,7 +462,7 @@ bool CCSocket::Send(const char* str) return true; } -bool CCSocket::Sendbyte(const char* str,int len) +bool CCSocket::SendByte(const char* str,int len) { int err = send(Socketbit, str, len, 0); if(err == -1) @@ -459,6 +488,11 @@ bool CCSocket::UDPSend(const char* str, const char* IP, int Port) } } +bool CCSocket::SendData(const char* str, sockaddr_in addr_in){ + bool F = sendto(this->Socketbit, str, strlen(str), 0, (sockaddr*)&addr_in, sizeof(addr_in)) != -1; + return F; +} + bool CCSocket::UDPSendByte(const char* str,ByteHander len ,const char* IP, int Port) { sockaddr_in serverAddr; @@ -553,7 +587,7 @@ bool CCSocket::operator!=(CCSocket socket) return false; } -CCHostInfo CCSocket::GetHost() +CCHostInfo CCSocket::GetClientHost() { CCHostInfo hostInfo; char IP[INET_ADDRSTRLEN] = {0}; @@ -562,7 +596,14 @@ CCHostInfo CCSocket::GetHost() hostInfo.Port = ntohs(client.sin_port); return hostInfo; } - +CCHostInfo CCSocket::GetLocalHost(){ + CCHostInfo hostInfo; + char IP[INET_ADDRSTRLEN] = {0}; + inet_ntop(IPVx, &server.sin_addr, IP, INET_ADDRSTRLEN); + hostInfo.IPAddress = IP; + hostInfo.Port = ntohs(server.sin_port); + return hostInfo; +} void CCSocket::SetSocketNonBlocking() { int flags = fcntl(this->Socketbit, F_GETFL, 0); @@ -578,7 +619,7 @@ void CCSocket::SetSocketNonBlocking() } } -bool CCSocket::IsDataAvailable() +bool CCSocket::isDataAvailable() { pollfd pfd{}; pfd.fd = this->Socketbit; @@ -592,7 +633,25 @@ bool CCSocket::IsDataAvailable() } return pfd.revents & POLLIN; } - +bool CCSocket::isConnectionAlive() { + fd_set fds; + FD_ZERO(&fds); + FD_SET(Socketbit, &fds); + timeval timeout = { 0, 0 }; // 非阻塞模式立即返回 + int ret = select(Socketbit + 1, &fds, NULL, &fds, &timeout); + if (ret < 0) { + // 错误处理 + return false; + } else if (ret > 0) { + if (FD_ISSET(Socketbit, &fds)) { + if (FD_ISSET(Socketbit, &fds)) { + // 检查异常条件 + return false; + } + } + } + return true; +} #else #endif diff --git a/SDK/src/CCThreadPool.cpp b/SDK/src/CCThreadPool.cpp index 774bba7..b564e99 100644 --- a/SDK/src/CCThreadPool.cpp +++ b/SDK/src/CCThreadPool.cpp @@ -1,100 +1,119 @@ -#include "../include/CCThreadPool.h" +#include "CCThreadPool.h" -CCThreadPool::CCThreadPool(int numThreads) -{ +CCThreadPool::CCThreadPool(int numThreads){ InitStart(numThreads); } -void CCThreadPool::InitStart(int numThreads) -{ - m_running = true; - m_threadCount = numThreads; - m_taskQueue.resize(numThreads,nullptr); - T = new TaskPool[numThreads]; - for (int i = 0;i < numThreads;i++) - { +void CCThreadPool::InitStart(int numThreads){ + InitStart(numThreads,30,1000 * 1000); +} - T->thread = new std::thread(&CCThreadPool::worker,this,i); - T->thread->detach(); - T->Running = false; - m_thread.push_back(&T[i]); +void CCThreadPool::InitStart(int corePoolSize, int maximumPoolSize, int keepAliveTime) { + m_corePoolSize = corePoolSize; + m_keepAliveTime = keepAliveTime; + m_maximumPoolSize = maximumPoolSize; + for (int i = 0; i < m_corePoolSize; ++i) { + TaskPool pool; + pool.ID = i; + pool.Sign = true; + pool.Running = false; + m_threads[i] = pool; + CCThread(&CCThreadPool::worker,this,i).detach(); } } - -void CCThreadPool::worker(int ID) -{ - while (m_running) - { - m_mutex.lock(); - std::function FUN = m_taskQueue[ID]; - m_mutex.unlock(); - if(FUN) - { - FUN(); - m_thread[ID]->Running = false; - m_taskQueue[ID] = nullptr; +void CCThreadPool::worker(int ID){ + auto& T = m_threads[ID]; + T.Online = true; + while (T.Sign) { + try { + m_mutex.lock(); + if(T.TaskFun && T.Running) { + if(Print) { + CC::Println("CCThreadPool Start ID: " + CCInt(ID).to_String()); + } + m_mutex.unlock(); + T.TaskFun(); + m_mutex.lock(); + T.Running = false; + if(Print) { + CC::Println("CCThreadPool End ID: " + CCInt(ID).to_String()); + } + } + else { + m_mutex.unlock(); + CCThread::Sleep(m_keepAliveTime); + } + m_mutex.unlock(); } - else - { - Threading::Sleep(m_thread_Time); + catch (CCException& exception) { + m_mutex.unlock(); + CC::Println("CCThreadPool Error -> ID: " + CCInt(ID).to_String() + " -> " + exception.what()); } } + T.Online = false; + if(Print) { + CC::Println("CCThreadPool Stop ID: " + CCInt(ID).to_String()); + } } -unsigned int CCThreadPool::GetThreadCount() const -{ - return m_threadCount; +int CCThreadPool::GetThreadCount() const{ + return m_threads.size() + TemporaryThreads; } -unsigned int CCThreadPool::GetUnusedCount() -{ - m_mutex.lock(); - unsigned int count = 0; - for(int i = 0;i < m_threadCount;i++) - { - if(!m_thread[i]->Running) - { - count++; +int CCThreadPool::GetUnusedCount() const{ + int A = 0; + for(auto &[fst, snd] : m_threads) { + if(!snd.Running) { + A++; } } - m_mutex.unlock(); - return count; + return A; } -void CCThreadPool::SetThreadTimeout(unsigned int us) -{ - m_thread_Time = us; +void CCThreadPool::SetThreadTimeout(int us){ + m_keepAliveTime = us; } -void CCThreadPool::Stop() -{ - m_running = false; - while (GetUnusedCount() != m_threadCount); - for(int i = 0;i < m_threadCount;i++) - { - T[i].thread->join(); - m_taskQueue[i] = nullptr; - delete T[i].thread; - } - m_thread.clear(); -} - -std::vector CCThreadPool::GetThreadUnusedID() -{ - m_mutex.lock(); - std::vector ID; - for(int i = 0;i < m_threadCount;i++) - { - if(!m_thread[i]->Running) - { - ID.push_back(i); +void CCThreadPool::Stop(bool F){ + for (auto&[fst, snd] : m_threads) { + snd.Sign = false; + if(F) { + while (snd.Online); } + CCThread::Sleep(1000); } - m_mutex.unlock(); - return ID; + m_threads.clear(); +} + +CCThreadPool::CCThreadPool(CCThreadPool &other) { + m_corePoolSize = other.m_corePoolSize; + m_keepAliveTime = other.m_keepAliveTime; + m_taskQueue = other.m_taskQueue; + m_threads = other.m_threads; +} + +int CCThreadPool::GetCorePoolSize() const { + return m_corePoolSize; +} + +int CCThreadPool::GetPoolMaxSize() const { + return m_maximumPoolSize; +} + +void CCThreadPool::SetPrint(bool F) { + Print = F; +} + +int CCThreadPool::GetTaskRunningSize() const { + return TaskRunningSize; } + + + + + diff --git a/Tools/CText.h b/Tools/CText.h index 6f486e7..4391f27 100644 --- a/Tools/CText.h +++ b/Tools/CText.h @@ -73,8 +73,8 @@ namespace CText{ fclose(fp); return true; } - inline std::map ReadConfig(const char * filePath){ - std::map config; + inline std::map ReadConfig(const char * filePath){ + std::map config; FILE *fp; char line[MAX_LINE_LENGTH] = {0}; ConfigPair configs; diff --git a/UI/W1/widget.cpp b/UI/W1/widget.cpp new file mode 100644 index 0000000..7587d20 --- /dev/null +++ b/UI/W1/widget.cpp @@ -0,0 +1,941 @@ +#include +#include "widget.h" +#include "./ui_widget.h" + +Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ + ui->setupUi(this); + //------------------------------------------------------------------------------------------------ + //COPYFile(WebSubPaths,""); + Configuration::ReadConfigInit(); + InitUi(); + setAttribute(Qt::WA_TranslucentBackground); //设置窗口背景透明 + setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint); //去掉窗口边框 + setAreaMovable(ui->widget_3->rect()); + this->setWindowIcon(QIcon(":logo.png")); + CCString logopath = Configuration::ExePath + "logo.png"; + QIcon trayIconIcon(logopath.c_str()); // 使用你的图标路径 + trayIcon->setIcon(trayIconIcon); + connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); + connect(showAction, &QAction::triggered, this, &Widget::show); + trayIconMenu->addAction(showAction); + trayIconMenu->addAction(quitAction); + trayIcon->setContextMenu(trayIconMenu); + trayIcon->show(); + SetPage(0); + Btns.emplace_back(ui->HomeBtn); + Btns.emplace_back(ui->SettingsBtn); + Initlogo(); + //------------------------------------------------------------------------------------------------ + connect(ui->HomeBtn, &QPushButton::clicked, this, &Widget::on_pushButton_clicked); + connect(ui->SelectSub_IPBtn, &QPushButton::clicked, this, &Widget::ReadSub_IP); + connect(ui->SettingsBtn, &QPushButton::clicked, this, &Widget::on_pushButton_clicked2); + connect(ui->CloseBtn, &QPushButton::clicked, this, [this](){this->close();}); + connect(ui->MinBtn, &QPushButton::clicked, this, [this](){this->showMinimized();}); + connect(ui->OpenServerBtn, &QPushButton::clicked, this, &Widget::OpenServerClick); + connect(ui->RestBtn, &QPushButton::clicked, this, &Widget::ServerConfigInit); + connect(ui->SetSaveBtn, &QPushButton::clicked, this, &Widget::SetSaveBtn); + connect(ui->ReadCSInfoBtn, &QPushButton::clicked, this, &Widget::ReadCSInfoFun); + connect(ui->Web_Port, &QLineEdit::textChanged,this, &Widget::onTextChanged); + connect(ui->OpenPCStart, &QCheckBox::stateChanged,this, &Widget::slotCheckedChanged); + connect(ui->RapidDeployment, &QPushButton::clicked, this, &Widget::Deploy); + if(Configuration::CORSEn == "true"){ + ui->CORSEn->setChecked(true); + } + ui->Sub_Origins->setEnabled(ui->CORSEn->isChecked()); + connect(ui->CORSEn, &QCheckBox::stateChanged,this, [this]() + { + ui->Sub_Origins->setEnabled(ui->CORSEn->isChecked()); + SetState(ServerFlag); + }); + connect(ui->GJSZBtn, &QPushButton::clicked,this, [this]() + { + auto* window = new widgetYZ(this); + int w = this->width() / 2 - (window->width() / 2); + int h = this->height() / 2 - (window->height() / 2); + window->move(w,h); + window->show(); + }); + ui->HomeBtn->setFocusPolicy(Qt::NoFocus); + ui->SettingsBtn->setFocusPolicy(Qt::NoFocus); + ui->CloseBtn->setFocusPolicy(Qt::NoFocus); + ui->MinBtn->setFocusPolicy(Qt::NoFocus); + ui->OpenServerBtn->setFocusPolicy(Qt::NoFocus); + //------------------------------------------------------------------------------------------------ + ui->ServerConsele->append("Path:" + QApplication::applicationDirPath()); + SetBtn(0); + Configuration::IPBS_NSSMF(false); + Configuration::CloseSub_Server(); + Configuration::CloseSub_Web(); + Configuration::IPBS_NSSMF(true); + CCThread([this](){ + CCString State = Configuration::State; + CCString CORSEn = Configuration::CORSEn; + int Op = Configuration::OpenSleep; + if(Op > 0){ + OpenSleepValue = Op; + } + if(State == "Open"){ + while (OpenSleepValue > 0){ + Threading::Sleep(1000 * 1000); + QMetaObject::invokeMethod(this, [this]() { + ui->ServerConsele->append(CCString(std::to_string(OpenSleepValue) + "秒后自动启动服务").c_str()); + }); + OpenSleepValue--; + if(ServerFlag){ + break; + } + } + if(!ServerFlag){ + OpenServerClick(); + OpenFlagBtn(true); + } + } + if(CORSEn == "true"){ + ui->CORSEn->setChecked(true); + } + else{ + ui->CORSEn->setChecked(false); + } + while (ServerThread.Sign()){ + if(ServerFlag){ + char bus[1024] = {0}; + sprintf(bus,"%d天%d小时%d分%d秒",t,h,f,s); + s++; + if(s >= 60){ + f++; + s = 0; + if(f >= 60){ + f = 0; + if(h >= 24){ + t++; + h = 0; + } + h++; + } + } + QMetaObject::invokeMethod(this,[this,bus]() + { + QString str = bus; + ui->RunTime->setText(str); + }); + } + QMetaObject::invokeMethod(this, [this](){ + // 获取当前的日期和时间 + QDateTime currentDateTime = QDateTime::currentDateTime(); + // 将日期时间对象转换为字符串格式 + QString currentTime = currentDateTime.toString("yyyy-MM-dd-hh:mm:ss"); + ui->NowTime->setText(currentTime); + + }); + CCThread::Sleep(1000 * 1000); + } + }).detach(); + if(Configuration::FirstRun == 1){ + CCThread([this]() + { + PrintMessage("检测到首次运行,正在部署IP-Web分控服务,请耐心等待..."); + CCThread::Sleep(1000 * 1000 * 5); + Deploy(); + // try{ + // QMetaObject::invokeMethod(this, [this]() + // { + // QMessageBox::StandardButton reply = QMessageBox::question(nullptr, "提示", + // "是否现在开始快速部署IP-Web分控?",QMessageBox::Yes | QMessageBox::No); + // if (reply == QMessageBox::Yes) { + // Deploy(); + // } else { + // + // } + // }); + // } + // catch (...){} + }).detach(); + } + ui->OpenPCStart->setCheckState(checkAutoStartEntry("IPBS_Station(Web)") ? Qt::Checked:Qt::Unchecked); + ServerThread.SetThread(&Widget::ServerListening,this); + ServerThread.Start(); + OpenSerice(true); + //------------------------------------------------------------------------------------------------ +} + +Widget::~Widget(){ + delete ui; +} + +void Widget::on_pushButton_clicked() { + SetBtn(0); + SetPage(0); +} + +void Widget::on_pushButton_clicked2() { + SetBtn(1); + SetPage(1); +} + +void Widget::WebThreadRun() { + Configuration::OpenSub_Server(); + while (Configuration::SubRun.IsRunning()){ + CCString Line = Configuration::SubRun.ReadLineBuffer(); + if(!Line.empty()){ + PrintMessage(Line); + } + Threading::Sleep(1000 * 50); + } + // PrintMessage("Sub Close!"); +} + +void Widget::closeEvent(QCloseEvent *event) { + QMessageBox msgBox; + msgBox.setWindowTitle(tr("退出程序")); + msgBox.setText(tr("你确定要退出吗?")); + QPushButton *yesButton = msgBox.addButton(tr("结束程序"), QMessageBox::YesRole); + msgBox.addButton(tr("到托盘"), QMessageBox::NoRole); + msgBox.exec(); + if (msgBox.clickedButton() == yesButton) + { + Configuration::IPBS_NSSMF(false); + Configuration::CloseSub_Server(); + Configuration::CloseSub_Web(); + Configuration::State = "Close"; + SetServerConfig(); + ServerThread.Stop(); + WebThread.Stop(); + event->accept(); + QCoreApplication::quit(); + } + else + { + this->hide(); + event->ignore(); // 阻止窗口关闭 + } +} + +bool Widget::WebRunFun() { + if(!ServerFlag){ + if(!WebThread.Sign()){ + ServerFlag = true; + SetState(ServerFlag); + CCThread(WebThreadRun,this).detach(); + CCThread([this]() + { + Configuration::OpenSub_Web(); + while (Configuration::WebRun.IsRunning()){ + CCString Line = Configuration::WebRun.ReadLineBuffer(); + if(!Line.empty()){ + PrintMessage(Line); + } + else{ + break; + } + CCThread::Sleep(1000 * 1000); + } + PrintMessage("网址: " + Configuration::Web_URL); + }).detach(); + } + } + return true; +} + +void Widget::SetPage(int i) { +// ui->ServerConsele->append(ServerSttingsPath.c_str()); + ui->stackedWidget->setCurrentIndex(i); + if(i == 1){ + InitUi(); + } +} + +void Widget::SetBtn(int i) { + for (auto & Btn : Btns) { + Btn->setStyleSheet("QPushButton{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(255, 255, 255, 0);\n" + "}\n" + "\n" + "QPushButton:hover{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(74,89,146, 255);\n" + "}"); + } + Btns[i]->setStyleSheet("QPushButton{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(74,89,146, 255);\n" + "}\n" + "\n" + "QPushButton:hover{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(74,89,146, 255);\n" + "}"); +} + +void Widget::OpenServerClick() { + auto A = CText::ReadConfig(Configuration::CfgPath.c_str()); + if(A.size() >= 8){ + try { + ServerReRun(); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + } + else{ + QMessageBox::information(this,"提示","启动参数错误,请先配置服务器参数!"); + } +} + +void Widget::OpenFlagBtn(bool F) { + if(!F){ + ui->OpenServerBtn->setStyleSheet("QPushButton{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(255,68,138,255);\n" + "}\n" + "\n" + "QPushButton:hover{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(255,100,150, 255);\n" + "}"); + ui->OpenServerBtn->setText("打开服务"); + } + else{ + ui->OpenServerBtn->setStyleSheet("QPushButton{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(255,0,0,255);\n" + "}\n" + "\n" + "QPushButton:hover{\n" + "\tborder-radius:10px;\n" + "\tcolor: rgb(255, 255, 255);\n" + "\tbackground-color: rgba(255,100,150, 255);\n" + "}"); + ui->OpenServerBtn->setText("关闭服务"); + } +} + +void Widget::ServerListening() { + bool F = false,S = false; + while (ServerThread.Sign()){ + Threading::Sleep(1000 * 1000 * 5); + try { + F = Configuration::GetSub_Status(); + S = Configuration::GetSub_Web_Status(); + QMetaObject::invokeMethod(this,[this,F,S]() + { + SetSuBState(F); + SetWebState(S); + }); + if(!F && ServerFlag){ + QMetaObject::invokeMethod(this, [this,&F](){ + if(!F){ + Configuration::OpenSub_Server(); + PrintMessage("Sub Res Start OK!"); + } + Threading::Sleep(1000 * 1000 * 5); + }); + } + if(!S && ServerFlag){ + try{ + if(!S){ + Configuration::OpenSub_Web(); + PrintMessage("Web Res Start OK!"); + PrintMessage("网址: " + Configuration::Web_URL); + } + Threading::Sleep(1000 * 1000 * 5); + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + } + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + } +} + +bool Widget::isJarRunning(const char *jarName) { +#ifdef _WIN32 + CCString str = jarName; + str.append(".exe"); + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) { + return false; + } + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + if (Process32First(hSnapshot, &pe32)) { + do { + if (_tcsstr(pe32.szExeFile, str.c_str()) != nullptr) { + CloseHandle(hSnapshot); + return true; + } + } while (Process32Next(hSnapshot, &pe32)); + } + + CloseHandle(hSnapshot); + return false; +#elif __linux__ +#endif +} + +bool Widget::terminateProcessByName(const char *processName) { +#ifdef _WIN32 + CCString str = processName; + str.append(".exe"); + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + if (hSnapshot == INVALID_HANDLE_VALUE) { + return false; + } + PROCESSENTRY32 pe32; + pe32.dwSize = sizeof(PROCESSENTRY32); + if (Process32First(hSnapshot, &pe32)) { + do { + if (_tcscmp(pe32.szExeFile, str.c_str()) == 0) { + HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID); + if (hProcess != NULL) { + TerminateProcess(hProcess, 0); + CloseHandle(hProcess); + } + } + } while (Process32Next(hSnapshot, &pe32)); + } + CloseHandle(hSnapshot); + return true; +#elif __linux__ + +#endif +} + +void Widget::ServerReRun() { + if(ServerFlag){ + try { + Configuration::CloseSub_Server(); + Configuration::CloseSub_Web(); + if(ServerFlag){ + WebThread.Stop(); + PrintMessage("Server Close"); + OpenFlagBtn(false); + ServerFlag = false; + SetState(ServerFlag); + ui->RunTime->setVisible(false); + t = 0;h = 0;f = 0;s = 0; + } + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + } + else{ + WebRunFun(); + OpenFlagBtn(true); + t = 0;h = 0;f = 0;s = 0; + ui->RunTime->setVisible(true); + } +} + +void Widget::onCurrentIndexChanged(int index) { + ui->Web_IP->setText(ui->Sub_IP->text()); + CCString URL = ui->Sub_IP->text().toStdString()+":"+ui->Web_Port->text().toStdString(); + Configuration::Web_URL = "http://" + URL + '/'; + QString str = CCString("['http://" + ui->Sub_IP->text().toStdString() + ":" + Configuration::Web_Port + "']").c_str(); + ui->Sub_Origins->setText(str); +} + +void Widget::onCurrentIndexChangedCSIP(int index) +{ + try + { + if(CSPortList.empty()) + { + return; + } + CCVar str = CCInt(CSPortList[index]).to_String().c_str(); + ui->CS_Port->setText(str); + } + catch (CCException& exception){} +} + +void Widget::SetSuBState(bool F) { + if(F){ + ui->SubLabel->setStyleSheet("color: rgb(0, 255, 0);"); + ui->SubLabel->setText("后端:在线"); + } + else{ + ui->SubLabel->setStyleSheet("color: rgb(255, 0, 0);"); + ui->SubLabel->setText("后端:离线"); + } +} + +void Widget::SetWebState(bool F) { + if(F){ + ui->WebLabel->setStyleSheet("color: rgb(0, 255, 0);"); + ui->WebLabel->setText("前端:在线"); + } + else{ + ui->WebLabel->setStyleSheet("color: rgb(255, 0, 0);"); + ui->WebLabel->setText("前端:离线"); + } +} + +void Widget::onTextChanged(const QString &text) { + ui->Web_IP->setText(ui->Sub_IP->text()); + CCString URL = ui->Sub_IP->text().toStdString()+":"+ui->Web_Port->text().toStdString(); + Configuration::Web_URL = "http://" + URL + '/'; + QString str = CCString("['http://" + ui->Web_IP->text().toStdString() + ":" + text.toStdString() + "']").c_str(); + ui->Sub_Origins->setText(str); +} + +void Widget::SetSaveBtn() { + if(ui->CS_IP->text().isEmpty()){ + QMessageBox::information(this, "Error", "C/S_IP不能为空"); + return; + } + if(ui->CS_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "C/S_Port不能为空"); + return; + } + if(ui->Sub_IP->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_IP不能为空"); + return; + } + if(ui->Sub_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_Port不能为空"); + return; + } + if(ui->Web_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "Web_Port不能为空"); + return; + } + if(ui->Web_IP->text().isEmpty()){ + QMessageBox::information(this, "Error", "Web_IP不能为空"); + return; + } + if(ui->Sub_Audio_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_Audio_Port不能为空"); + return; + } + if(ui->Sub_Origins->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_Origins不能为空"); + return; + } + SetServerConfig(); + QMessageBox::StandardButton reply = QMessageBox::question(this, "提示", "保存成功是否现在启动?", + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) { + // 用户点击了“是”按钮 + try { + Configuration::CloseSub_Server(); + Configuration::CloseSub_Web(); + if(ServerFlag){ + WebThread.Stop(); + ui->ServerConsele->append("Server Close"); + OpenFlagBtn(false); + ServerFlag = false; + SetState(ServerFlag); + ui->RunTime->setVisible(false); + t = 0;h = 0;f = 0;s = 0; + } + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + OpenServerClick(); + } else { + // 用户点击了“否”按钮 + } +} + +void Widget::ServerConfigInit() { + Configuration::CfgInit(); + SetPage(1); + QMessageBox::information(this, "提示", "初始化已完成!"); +} + +void Widget::Initlogo() { + CCString str = Configuration::ExePath + Sub_Logo; + QPixmap pixmap(str.c_str()); // 替换为你的图片路径 + ui->logoIMG->setPixmap(pixmap); + ui->logoIMG->setScaledContents(true); // 图片自动缩放以适应 QLabel 大小 + ui->logoIMG->setMaximumSize(111,61); // 设置 QLabel 最小尺寸 + ui->logoIMG->setMaximumSize(320,180); // 设置 QLabel 最小尺寸 + ImGLoad = ui->logoIMG; +} + +void Widget::SetServerConfig() { + // FILE *fp = fopen(Configuration::CfgPath.c_str(), "w"); + // if (fp == nullptr) { + // QMessageBox::information(this, "Error", "Failed to open ServerSttings file"); + // return; + // } + // // 写入配置数据 + // fprintf(fp, "C/S_IP:%s\n",ui->CS_IP->text().toStdString().c_str()); + // fprintf(fp, "C/S_PORT:%s\n",ui->CS_Port->text().toStdString().c_str()); + // fprintf(fp, "Sub_Control_IP:%s\n",ui->Sub_IP->text().toStdString().c_str()); + // fprintf(fp, "Sub_Control_PORT:%s\n",ui->Sub_Port->text().toStdString().c_str()); + // fprintf(fp, "Sub_Control_Audio_PORT:%s\n",ui->Sub_Audio_Port->text().toStdString().c_str()); + // fprintf(fp, "Sub_Web_PORT:%s\n",ui->Web_Port->text().toStdString().c_str()); + // fprintf(fp, "Origins:%s\n",ui->Sub_Origins->text().toStdString().c_str()); + // fprintf(fp, "#中文简体,English\n"); + // fprintf(fp, "Language:%s\n",ui->LabguageBox->currentText().toStdString().c_str()); + // fprintf(fp, "OpenSleep:%d\n",ui->OpenSleep->value()); + // fprintf(fp, "State:%s\n",Configuration::State.c_str()); + // fprintf(fp, "CORSEn:%s\n",Configuration::CORSEn.c_str()); + // fprintf(fp, "FirstRun:%d\n",0); + // fclose(fp); + // fp = fopen(Configuration::WebCfgPath.c_str(), "w"); + // if (fp == nullptr) { + // QMessageBox::information(this, "Error", "Failed to open NginxSttings file"); + // return; + // } + // // 写入配置数据 + // fprintf(fp, "worker_processes 1;\n" + // "events {\n" + // " worker_connections 1024;\n" + // "}\n" + // "http {\n" + // " include mime.types;\n" + // " default_type application/octet-stream;\n" + // " sendfile on;\n" + // " keepalive_timeout 65;\n" + // " client_max_body_size 500m;\n" + // " server {\n" + // " listen %s;\n" + // " server_name %s;\n" + // " location / {\n" + // " root html;\n" + // " index index.html index.htm;\n" + // " try_files $uri $uri/ /index.html;\n" + // " # try_files $uri $uri/ @router;\n" + // " }\n" + // " location /api/ {\n" + // " #rewrite ^.+api/?(.*)$ /$1 break; \n" + // " rewrite ^/api/(.*)$ /$1 break; \n" + // " proxy_pass http://%s:%s/;\n" + // " proxy_redirect off;\n" + // " proxy_set_header Host $host;\n" + // " proxy_set_header X-Real-IP $remote_addr;\n" + // " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n" + // " }\n" + // " error_page 500 502 503 504 /50x.html;\n" + // " location = /50x.html {\n" + // " root html;\n" + // " }\n" + // " }\n" + // "}",ui->Web_Port->text().toStdString().c_str(),ui->Web_IP->text().toStdString().c_str(), + // ui->Sub_IP->text().toStdString().c_str(),ui->Sub_Port->text().toStdString().c_str()); + // fclose(fp); + Configuration::CS_IP = ui->CS_IP->text().toStdString(); + Configuration::CS_Port = ui->CS_Port->text().toStdString(); + Configuration::Sub_IP = ui->Sub_IP->text().toStdString(); + Configuration::Sub_Port = ui->Sub_Port->text().toStdString(); + Configuration::Sub_Audio_Port = ui->Sub_Audio_Port->text().toStdString(); + Configuration::Web_IP = ui->Web_IP->text().toStdString(); + Configuration::Web_Port = ui->Web_Port->text().toStdString(); + Configuration::Sub_Org = ui->Sub_Origins->text().toStdString(); + Configuration::Language = ui->LabguageBox->currentText().toStdString(); + Configuration::OpenSleep = ui->OpenSleep->value(); + Configuration::SaveJarCfg(); + Configuration::SaveWebCfg(); + Configuration::ReadConfigInit(); +} + +void Widget::SetState(bool F) { + Configuration::State = F ? "Open" : "Close"; + Configuration::CORSEn = ui->CORSEn->isChecked() ? "true" : "false"; + SetServerConfig(); +} + +void Widget::SetAutoStart(const QString &path, bool enable) { + QSettings startupSettings("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows", QSettings::NativeFormat); + if (enable) { + startupSettings.setValue("IPBS_Station(Web)", path); + } else { + startupSettings.remove("IPBS_Station(Web)"); + } +} + +void Widget::OpenSerice(bool F) { +#ifdef _WIN32 + +#elif __linux__ + +#endif +} + +void Widget::slotCheckedChanged(int i) { + CCString str = "IPBS_Start"; + if(ui->OpenPCStart->isChecked()){ + SetAutoStart(str.c_str(),true); + } else{ + SetAutoStart(str.c_str(),false); + } + str = Configuration::ExePath + QApplication::applicationName().toStdString() + ".exe.lnk"; + if(ui->OpenPCStart->isChecked()){ + CreateShortO(); + CCString A = OpenKit + QApplication::applicationName().toStdString() + ".exe.lnk"; + CCFile file = CCFile(str.c_str(), CC::ios::w,false); + file.Copy(A); + file.Deleted(); + } + else{ + str = OpenKit + QApplication::applicationName().toStdString() + ".exe.lnk"; + CCFile file = CCFile(str.c_str(), CC::ios::w,false); + file.Deleted(); + } +} + +void Widget::ReadCSInfoFun(){ + CCVar* cs4 = new CSInfoW4(this); + int w = this->width() / 2 - (cs4->width() / 2); + int h = this->height() / 2 - (cs4->height() / 2); + cs4->move(w,h); + cs4->IPEdit1 = ui->CS_IP; + cs4->IPEdit2 = ui->CS_Port; + cs4->exec(); +} + +void Widget::PrintMessage(CCString str) +{ + QMetaObject::invokeMethod(this,[this,str]() + { + CCTimeData time; + CCString S = "[" + time.to_String() + "] -> " + str; + ui->ServerConsele->append(S.c_str()); + }); +} + +void Widget::ReadSub_IP(){ + CCVar* sub = new Sub_IPUI(this); + int w = this->width() / 2 - (sub->width() / 2); + int h = this->height() / 2 - (sub->height() / 2); + sub->move(w,h); + sub->IPEdit = ui->Sub_IP; + sub->show(); +} + +void Widget::Deploy(){ + boolean F1 = false,F2 = false; + PrintMessage("正在配置IP-Web分控IP地址..."); + while (true){ + CCThread::Sleep(1000 * 500); + Configuration::ReadSub_IP(); + if(!Configuration::SubIPList.empty()){ + if(Configuration::SubIPList.size() > 1){ + PrintMessage("检测到多个IP地址,请选择要使用的IP地址!"); + CCVar* sub = new Sub_IPUI(this); + int w = this->width() / 2 - (sub->width() / 2); + int h = this->height() / 2 - (sub->height() / 2); + sub->move(w,h); + sub->IPEdit = ui->Sub_IP; + sub->exec(); + PrintMessage("Web分控IP地址配置完成!"); + } + else{ + Configuration::Sub_IP = Configuration::SubIPList[0]; + PrintMessage("Web分控IP地址配置完成!"); + } + F2 = true; + break; + } + else{ + bool A1 = false; + QMetaObject::invokeMethod(this,[this,&F2,&A1]() + { + QMessageBox::StandardButton reply = QMessageBox::question(nullptr, "提示", + "未检测到合法IPV4地址,请检查网络,是否继续检测?", + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) { + A1 = true; + } else { + Configuration::Sub_IP = ""; + F2 = false; + PrintMessage("Web分控IP地址配置跳过!"); + } + }); + if(A1){ + continue; + } + else{ + break; + } + } + } + PrintMessage("正在配置C/S服务器参数..."); + while (true){ + PrintMessage("尝试搜索C/S服务器中..."); + CCThread::Sleep(1000 * 500); + Configuration::ReadCSInfo(); + if(!Configuration::CSIPList.empty()){ + if(Configuration::CSIPList.size() > 1){ + PrintMessage("在局域网检测到多个C/S服务器,请选择需要使用的C/S服务器!"); + CCVar* cs4 = new CSInfoW4(this); + int w = this->width() / 2 - (cs4->width() / 2); + int h = this->height() / 2 - (cs4->height() / 2); + cs4->move(w,h); + cs4->IPEdit1 = ui->CS_IP; + cs4->IPEdit2 = ui->CS_Port; + cs4->exec(); + PrintMessage("C/S服务器信息配置完成"); + } + else{ + Configuration::CS_IP = Configuration::CSIPList[0]; + Configuration::CS_Port = Configuration::CSPortList[0].to_String(); + PrintMessage("C/S服务器信息配置完成"); + } + F1 = true; + break; + } + else{ + bool A1 = false; + Configuration::CS_IP = ""; + Configuration::CS_Port = ""; + QMetaObject::invokeMethod(this,[this,&F1,&A1]() + { + QMessageBox::StandardButton reply = QMessageBox::question(nullptr, "提示", + "在局域网未检测到可用的C/S服务器,请先启动C/S服务器,是否继续检测?", + QMessageBox::Yes | QMessageBox::No); + if (reply == QMessageBox::Yes) { + A1 = true; + } + else { + Configuration::CS_IP = ""; + Configuration::CS_Port = ""; + F1 = false; + PrintMessage("C/S服务器信息配置跳过!"); + A1 = false; + } + }); + if(A1){ + continue; + } + else{ + break; + } + } + } + PrintMessage("正在分配IP-Web分控服务端口..."); + CCVar Ports = Configuration::getAvailablePorts(3,5417); + Configuration::Sub_Port = Ports[0].to_String(); + Configuration::Sub_Audio_Port = Ports[1].to_String(); + Configuration::Web_Port = Ports[2].to_String(); + Configuration::Web_IP = Configuration::Sub_IP; + PrintMessage("IP-Web分控服务端口分配完成!"); + PrintMessage("IP-Web分控服务正在设置跨域..."); + Configuration::Sub_Org = "['http://" + Configuration::Web_IP + ":" + Configuration::Web_Port + "']"; + PrintMessage("IP-Web分控服务跨域设置完成!"); + ui->CS_IP->setText(Configuration::CS_IP.c_str()); + ui->CS_Port->setText(Configuration::CS_Port.c_str()); + ui->Sub_IP->setText(Configuration::Sub_IP.c_str()); + ui->Sub_Port->setText(Configuration::Sub_Port.c_str()); + ui->Sub_Audio_Port->setText(Configuration::Sub_Audio_Port.c_str()); + ui->Sub_Origins->setText(Configuration::Sub_Org.c_str()); + if(Configuration::Language == "English"){ + ui->LabguageBox->setCurrentIndex(1); + } + else{ + ui->LabguageBox->setCurrentIndex(0); + } + ui->Web_Port->setText(Configuration::Web_Port.c_str()); + ui->Web_IP->setText(ui->Sub_IP->text()); + ui->OpenSleep->setValue(Configuration::OpenSleep); + PrintMessage("IP-Web分控服务部署设置已完成!"); + PrintMessage("正在保存IP-Web分控服务设置..."); + SetServerConfig(); + PrintMessage("IP-Web分控服务设置保存完成"); + if(F1 && F2){ + try { + terminateProcessByName("java"); + terminateProcessByName("nginx"); + if(ServerFlag){ + WebThread.Stop(); + ui->ServerConsele->append("Server Close"); + OpenFlagBtn(false); + ServerFlag = false; + SetState(ServerFlag); + ui->RunTime->setVisible(false); + t = 0;h = 0;f = 0;s = 0; + } + } + catch (const std::exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + } + if(ui->CS_IP->text().isEmpty()){ + QMessageBox::information(this, "Error", "C/S_IP不能为空"); + return; + } + if(ui->CS_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "C/S_Port不能为空"); + return; + } + if(ui->Sub_IP->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_IP不能为空"); + return; + } + if(ui->Sub_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_Port不能为空"); + return; + } + if(ui->Web_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "Web_Port不能为空"); + return; + } + if(ui->Web_IP->text().isEmpty()){ + QMessageBox::information(this, "Error", "Web_IP不能为空"); + return; + } + if(ui->Sub_Audio_Port->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_Audio_Port不能为空"); + return; + } + if(ui->Sub_Origins->text().isEmpty()){ + QMessageBox::information(this, "Error", "Sub_Origins不能为空"); + return; + } + PrintMessage("正在启动IP-Web分控服务..."); + OpenServerClick(); + } + else{ + QMetaObject::invokeMethod(this,[this,F1,F2]() + { + if(!F1){ + PrintMessage("在局域网未检测到C/S服务器,请检查C/S服务器!"); + } + if(!F2){ + PrintMessage("未检测到合法IPV4地址,请检查网络!"); + } + PrintMessage("部署未完成!"); + }); + } +} + +void Widget::InitUi(){ + ui->CS_IP->setText(Configuration::CS_IP.c_str()); + ui->CS_Port->setText(Configuration::CS_Port.c_str()); + ui->Sub_IP->setText(Configuration::Sub_IP.c_str()); + ui->Sub_Port->setText(Configuration::Sub_Port.c_str()); + ui->Sub_Audio_Port->setText(Configuration::Sub_Audio_Port.c_str()); + ui->Sub_Origins->setText(Configuration::Sub_Org.c_str()); + if(Configuration::Language == "English"){ + ui->LabguageBox->setCurrentIndex(1); + } + else{ + ui->LabguageBox->setCurrentIndex(0); + } + ui->Web_Port->setText(Configuration::Web_Port.c_str()); + ui->Web_IP->setText(ui->Sub_IP->text()); + ui->OpenSleep->setValue(Configuration::OpenSleep); +} + +bool Widget::checkAutoStartEntry(const QString &appName) { + QSettings startupSettings("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows", QSettings::NativeFormat); + return startupSettings.contains(appName); +} + + + + diff --git a/widget.h b/UI/W1/widget.h similarity index 90% rename from widget.h rename to UI/W1/widget.h index f8d5db9..efc7d5f 100644 --- a/widget.h +++ b/UI/W1/widget.h @@ -32,6 +32,12 @@ #include #include #include +#include "CCSocket.h" +#include "vector" +#include "CCTimeData.h" +#include "widgetyz.h" +#include "csinfow4.h" +#include "W5/sub_ipui.h" #ifdef _WIN32 #include @@ -50,18 +56,12 @@ class Widget : public QWidget { Q_OBJECT private: - //E:/project/UDate/Project/QtProject/WebDeploy/ - const CCString WebSubPaths = QApplication::applicationDirPath().toStdString() + "/"; - const CCString ServerSttingsPath = WebSubPaths + "src/main/resources/ServerSettings/ServerSettings.CText"; - const CCString NginxSttingsPath = WebSubPaths + "conf/nginx.conf"; CCThread WebThread, ServerThread; + std::vector CSPortList; #ifdef _WIN32 const CCString OpenKit = "C:/ProgramData/Microsoft/Windows/Start Menu/Programs/StartUp/"; - const CCString NginxExe = WebSubPaths + "nginx.exe"; - const CCString JavaExe = "WebSub/jreWin/bin/java.exe"; #elif __linux__ - const CCString NginxExe = "./WebSub/nginx"; - const CCString JavaExe = "WebSub/jreLinux/bin/java"; + #endif QRect m_areaMovable;//可移动窗口的区域,鼠标只有在该区域按下才能移动窗口 bool m_bPressed,closeflag = false;//鼠标按下标志(不分左右键) @@ -71,7 +71,6 @@ private: QMenu *trayIconMenu = new QMenu(this); QAction *quitAction = new QAction(tr("&退出"), this); QAction *showAction = new QAction(tr("&显示"), this); - std::map ServerSettings; int t = 0,h = 0,f = 0,s = 0; int OpenSleepValue = 10; @@ -89,13 +88,17 @@ public: bool terminateProcessByName(const char* processName); void ServerReRun(); void onCurrentIndexChanged(int index); + void onCurrentIndexChangedCSIP(int index); void SetSuBState(bool F); void SetWebState(bool F); void SetSaveBtn(); void Initlogo(); - void SelectFile(); void slotCheckedChanged(int i); - + void ReadCSInfoFun(); + void PrintMessage(CCString str); + void ReadSub_IP(); + void Deploy(); + void InitUi(); private: Ui::Widget *ui; diff --git a/widget.ui b/UI/W1/widget.ui similarity index 82% rename from widget.ui rename to UI/W1/widget.ui index 15ca0c0..ed2823f 100644 --- a/widget.ui +++ b/UI/W1/widget.ui @@ -273,13 +273,13 @@ QPushButton:hover{ - IP广播分控启动器 + IP广播Web分控启动器 - 250 + 260 10 351 41 @@ -363,7 +363,7 @@ QPushButton:hover{ } - 打开服务 + 开启服务 @@ -423,6 +423,41 @@ QPushButton:hover{ + + + + 150 + 20 + 111 + 41 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 快速部署 + + @@ -500,7 +535,7 @@ border-radius:10px; - C/S服务器端口 + C/S服务器端口: @@ -530,7 +565,7 @@ color: rgb(0, 0, 0); 10 160 - 311 + 221 51 @@ -538,12 +573,12 @@ color: rgb(0, 0, 0); - Sub分控后端服务器IP + 分控后端服务器IP: - + 0 @@ -556,64 +591,11 @@ color: rgb(0, 0, 0); - QComboBox{ - background-color: rgb(77,85,104); - border-radius: 10px; /* 与父控件保持一致 */ - border-style: inset; /* 与父控件保持一致 */ - border-width: 1px; /* 设置边框宽度 */ - border-color: white; /* 设置边框颜色 */ - color: rgb(255, 255, 255); -} - -QComboBox::drop-down { - subcontrol-origin: padding; - subcontrol-position: top right;/*放于右方顶部*/ - width: 50px;/*设置按钮范围宽度*/ - /*border-radius: 15px; - border-left-width: 1px; - border-left-color: darkgray; - border-left-style: solid;*/ - - border-top-right-radius: 3px;/*设置边框圆角*/ - border-bottom-right-radius: 3px; -/*padding-right: 50px;*/ -} - - - -QComboBox QAbstractItemView { - border: 2px solid #f3f3f3;/*边框宽度、线形、颜色*/ - background-color: rgba(237, 242, 255, 1);/*背景颜色*/ - border-radius: 10px;/*圆角*/ - padding: 1px 2px 1px 2px; /*针对于组合框中的文本内容*/ - min-width: 9em; /*# 组合框的最小宽度*/ - font-size: 15px; - color:rgb(0,0,0); -} - -/* 下拉后,整个下拉窗体每项的样式 */ -QComboBox QAbstractItemView::item { - border-radius: 10px;/*圆角*/ - height: 50px; /* 项的高度(设置pComboBox->setView(new QListView());后,该项才起作用) */ - background-color: rgb(0, 0, 0); - - -} - -/*以下部分不知为何不生效,有待调试*/ -/* 下拉后,整个下拉窗体越过每项的样式 */ -QComboBox QAbstractItemView::item:hover { - color: #FFFFF0; - /* 整个下拉窗体越过每项的背景色 */ - background-color: rgb(237, 242, 255); -} - -/* 下拉后,整个下拉窗体被选择的每项的样式 */ -QComboBox QAbstractItemView::item:selected { - color: #FFFFF0; - background-color: rgb(77, 85, 101); - font-size: 30px; -} + background-color: rgba(255, 255, 255, 200); +color: rgb(0, 0, 0); + + + @@ -632,7 +614,7 @@ QComboBox QAbstractItemView::item:selected { - Sub分控后端端口 + 分控后端端口: @@ -663,14 +645,14 @@ color: rgb(0, 0, 0); 10 280 311 - 51 + 61 - Sub-IP音频端口 + 分控音频采集端口: @@ -689,44 +671,6 @@ color: rgb(0, 0, 0); background-color: rgba(255, 255, 255, 200); -color: rgb(0, 0, 0); - - - - - - - - - 10 - 340 - 311 - 51 - - - - - - - Sub-Origins[跨域] - - - - - - - - 0 - 30 - - - - - 15 - - - - background-color: rgba(255, 255, 255, 200); color: rgb(0, 0, 0); @@ -737,7 +681,7 @@ color: rgb(0, 0, 0); 10 - 400 + 410 311 51 @@ -746,7 +690,7 @@ color: rgb(0, 0, 0); - Language[语言] + Language[语言]: @@ -841,16 +785,16 @@ QComboBox QAbstractItemView::item:selected { 10 - 40 - 311 - 51 + 30 + 221 + 61 - C/S服务器IP + C/S服务器IP: @@ -878,11 +822,59 @@ color: rgb(0, 0, 0); - + 10 - 460 + 470 + 111 + 41 + + + + 秒/自启延时(0为无) + + + + + + 240 + 60 + 81 + 31 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 选择 + + + + + + 140 + 470 181 41 @@ -897,17 +889,88 @@ color: rgb(0, 0, 0); color: rgb(0, 0, 0); - + - 200 - 460 - 111 - 41 + 11 + 350 + 311 + 53 + + + + + + + 分控后端IP地址白名单-[跨域]: + + + + + + + 启用 + + + + + + + + + + 0 + 30 + + + + + 15 + + + + background-color: rgba(255, 255, 255, 200); +color: rgb(0, 0, 0); + + + + + + + + + 240 + 180 + 81 + 31 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + - 自启延时(0为无) + 选择 @@ -938,7 +1001,7 @@ color: rgb(0, 0, 0); - Web前端端口 + 分控前端端口: @@ -976,7 +1039,7 @@ color: rgb(0, 0, 0); - Web前端IP + 分控前端IP: @@ -1004,11 +1067,11 @@ color: rgb(0, 0, 0); - + - 0 - 220 + 130 + 170 111 41 @@ -1036,79 +1099,44 @@ QPushButton:hover{ } - 更换WebLogo + 高级设置 - + 0 - 280 - 320 - 180 - - - - - - - - - - 130 - 220 - 181 + 170 + 111 41 - 12 + Bahnschrift Light + 13 + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + - 图片必须是100x40的大小 + 初始化设置 - - - - 0 - 160 - 311 - 51 - - - - - - - - 15 - - - - URL - - - - - - - - 15 - - - - - - - true - - - - - @@ -1132,26 +1160,32 @@ QPushButton:hover{ background-color: rgb(10,22,53); border-radius:10px; - - - - 560 - 20 - 111 - 41 - - - - - Bahnschrift Light - 13 - - - - Qt::TabFocus - - - QPushButton{ + + + + + + 120 + 45 + + + + + 120 + 45 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ border-radius:10px; color: rgb(255, 255, 255); background-color: rgba(255,68,138,255); @@ -1162,67 +1196,47 @@ QPushButton:hover{ color: rgb(255, 255, 255); background-color: rgba(255,100,150, 255); } - - - 初始化设置 - - - - - - 440 - 20 - 111 - 41 - - - - - Bahnschrift Light - 13 - - - - Qt::TabFocus - - - QPushButton{ - border-radius:10px; - color: rgb(255, 255, 255); - background-color: rgba(255,68,138,255); -} - -QPushButton:hover{ - border-radius:10px; - color: rgb(255, 255, 255); - background-color: rgba(255,100,150, 255); -} - - - 保存 - - - - - - 280 - 20 - 151 - 41 - - - - - 15 - - - - color: rgb(255, 255, 255); - - - 设置开机自启 - - + + + 保存 + + + + + + + + 0 + 45 + + + + + 15 + + + + color: rgb(255, 255, 255); + + + 设置开机自启 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + @@ -1242,7 +1256,7 @@ QPushButton:hover{ - + diff --git a/UI/W2/widgetyz.cpp b/UI/W2/widgetyz.cpp new file mode 100644 index 0000000..28c5cd9 --- /dev/null +++ b/UI/W2/widgetyz.cpp @@ -0,0 +1,44 @@ +#include "widgetyz.h" + +#include + +#include "ui_widgetYZ.h" +#include +#include + +widgetYZ::widgetYZ(QWidget *parent) :QWidget(parent), ui(new Ui::widgetYZ) { + ui->setupUi(this); + setWindowFlags(this->windowFlags() &~ Qt::WindowMaximizeButtonHint); + connect(ui->YZQRBtn, &QPushButton::clicked,this, &widgetYZ::QRBtnFun); + connect(ui->YZQXBtn, &QPushButton::clicked,this, &widgetYZ::QXBtnFun); +} + +widgetYZ::~widgetYZ() { + delete ui; +} + +void widgetYZ::QRBtnFun() +{ + if(ui->YZMMInput->text() == "123456") + { + auto* win = new widget3(); + // 获取屏幕的几何尺寸 + QScreen *screen = QGuiApplication::primaryScreen(); + QRect screenGeometry = screen->geometry(); + int x = (screenGeometry.width() - width()) / 2; + int y = (screenGeometry.height() - height()) / 2; + // 移动窗口到计算出的中心位置 + win->move(x, y); + win->show(); + this->close(); + } + else + { + QMessageBox::warning(this, "提示", "密码错误!"); + } +} + +void widgetYZ::QXBtnFun() +{ + this->close(); +} diff --git a/UI/W2/widgetyz.h b/UI/W2/widgetyz.h new file mode 100644 index 0000000..cc6988a --- /dev/null +++ b/UI/W2/widgetyz.h @@ -0,0 +1,25 @@ +#ifndef WIDGETYZ_H +#define WIDGETYZ_H + +#include +#include "widget3.h" + +QT_BEGIN_NAMESPACE +namespace Ui { class widgetYZ; } +QT_END_NAMESPACE + +class widgetYZ : public QWidget { +Q_OBJECT + +public: + explicit widgetYZ(QWidget *parent = nullptr); + ~widgetYZ() override; + void QRBtnFun(); + void QXBtnFun(); + +private: + Ui::widgetYZ *ui; +}; + + +#endif //WIDGETYZ_H diff --git a/UI/W2/widgetyz.ui b/UI/W2/widgetyz.ui new file mode 100644 index 0000000..1e6b379 --- /dev/null +++ b/UI/W2/widgetyz.ui @@ -0,0 +1,174 @@ + + + widgetYZ + + + + 0 + 0 + 367 + 184 + + + + 管理员验证 + + + background-color: rgba(10, 23, 53, 200); + + + + + + + + + + 16777215 + 50 + + + + + 15 + + + + Qt::LeftToRight + + + background-color: rgba(255, 255, 255, 0); +color: rgb(255, 255, 255); + + + 管理员密码 + + + Qt::AlignCenter + + + + + + + + + + 0 + 30 + + + + + 15 + + + + background-color: rgb(202,205,211); +color: rgb(0, 0, 0); +border-radius:8px; + + + QLineEdit::Password + + + 密码 + + + + + + + 10 + + + 20 + + + 15 + + + 20 + + + + + + 0 + 35 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 确定 + + + + + + + + 0 + 35 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 取消 + + + + + + + + + + + + + + + diff --git a/UI/W3/widget3.cpp b/UI/W3/widget3.cpp new file mode 100644 index 0000000..faa1171 --- /dev/null +++ b/UI/W3/widget3.cpp @@ -0,0 +1,64 @@ +#include "widget3.h" + +#include +#include +#include + +#include "ui_widget3.h" + + +widget3::widget3(QWidget *parent) :QWidget(parent), ui(new Ui::widget3) { + ui->setupUi(this); + setWindowFlags(this->windowFlags() &~ Qt::WindowMaximizeButtonHint); + connect(ui->LogoBtn, &QPushButton::clicked,this, &widget3::SelectFile); +} + +widget3::~widget3() { + delete ui; +} + +void widget3::SelectFile() { + try { + //定义文件对话框类 + QFileDialog *fileDialog = new QFileDialog(this); + //定义文件对话框标题 + fileDialog->setWindowTitle(QStringLiteral("选择文件")); + //设置打开的文件路径 + fileDialog->setDirectory("./"); + //设置文件过滤器,只显示.ui .cpp 文件,多个过滤文件使用空格隔开 + fileDialog->setNameFilter(tr("File(*.png*)")); + //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles + fileDialog->setFileMode(QFileDialog::ExistingFile); + //设置视图模式 + fileDialog->setViewMode(QFileDialog::Detail); + //获取选择的文件的路径 + QStringList fileNames; + if (fileDialog->exec()) { + fileNames = fileDialog->selectedFiles(); + } + if(!fileNames.isEmpty()){ + CCString fileName = fileNames[0].toStdString(); + CCFile file = CCFile(fileName.c_str(), CC::ios::rb, false); + CCString str = WebSubPaths + "html/assets/logo-CuXNbvLG.png"; + bool F = file.Copy(str); + if(F){ + CCString str = WebSubPaths + "html/assets/logo-CuXNbvLG.png"; + QPixmap pixmap(str.c_str()); // 替换为你的图片路径 + if(ImGLoad != nullptr) + { + ImGLoad->setPixmap(pixmap); + ImGLoad->setScaledContents(true); // 图片自动缩放以适应 QLabel 大小 + ImGLoad->setMaximumSize(111,61); // 设置 QLabel 最小尺寸 + ImGLoad->setMaximumSize(320,180); // 设置 QLabel 最小尺寸 + } + QMessageBox::information(this, "Success", "Copy OK!"); + } + else{ + QMessageBox::information(this, "Error", "Failed to copy file,Chinese is not supported"); + } + } + } + catch (const std::exception& e) { + + } +} \ No newline at end of file diff --git a/UI/W3/widget3.h b/UI/W3/widget3.h new file mode 100644 index 0000000..693e882 --- /dev/null +++ b/UI/W3/widget3.h @@ -0,0 +1,31 @@ +#ifndef WIDGET3_H +#define WIDGET3_H + +#include +#include +#include +#include "CCString.h" + +inline QLabel* ImGLoad = nullptr; + +QT_BEGIN_NAMESPACE +namespace Ui { class widget3; } +QT_END_NAMESPACE + +class widget3 : public QWidget { +Q_OBJECT + +private: + const CCString WebSubPaths = QApplication::applicationDirPath().toLocal8Bit().toStdString() + "/"; + +public: + explicit widget3(QWidget *parent = nullptr); + ~widget3() override; + void SelectFile(); + +private: + Ui::widget3 *ui; +}; + + +#endif //WIDGET3_H diff --git a/UI/W3/widget3.ui b/UI/W3/widget3.ui new file mode 100644 index 0000000..887cba9 --- /dev/null +++ b/UI/W3/widget3.ui @@ -0,0 +1,119 @@ + + + widget3 + + + + 0 + 0 + 481 + 333 + + + + 高级设置 + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + 170 + 10 + 181 + 41 + + + + + 12 + + + + background-color: rgba(255, 255, 255, 0); + + + + 图片必须是100x40的大小 + + + + + + 60 + 80 + 341 + 211 + + + + background-color: rgba(255, 255, 255, 0); + + + + + + + + + 30 + 10 + 121 + 41 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 更改logo图片 + + + + + + + + + diff --git a/UI/W4/csinfow4.cpp b/UI/W4/csinfow4.cpp new file mode 100644 index 0000000..e041a46 --- /dev/null +++ b/UI/W4/csinfow4.cpp @@ -0,0 +1,46 @@ +#include "csinfow4.h" + +#include + +#include "ui_CSInfoW4.h" + + +CSInfoW4::CSInfoW4(QWidget *parent) :QDialog(parent), ui(new Ui::CSInfoW4) { + ui->setupUi(this); + setAttribute(Qt::WA_TranslucentBackground); + setWindowFlags(Qt::FramelessWindowHint); + connect(ui->QueRBtn1, &QPushButton::clicked, this, &CSInfoW4::QueRBtn1); + connect(ui->QuXiaoBtn1, &QPushButton::clicked, this, &CSInfoW4::QuXiaoBtn1); + Configuration::ReadCSInfo([this]() + { + model = new QStringListModel(this); + QStringList data; + for(auto& i:Configuration::CSIPList){ + data.push_back(i.c_str()); + } + model->setStringList(data); + ui->listViewCS_IP->setModel(model); + ui->listViewCS_IP->setFocusPolicy(Qt::NoFocus); + }); + +} + +CSInfoW4::~CSInfoW4() { + delete model; + delete ui; +} + +void CSInfoW4::QueRBtn1(){ + QString ip = ui->listViewCS_IP->currentIndex().data().toString(); + int port = ui->listViewCS_IP->currentIndex().row(); + QString P = CCInt(Configuration::CSPortList[port]).to_String().c_str(); + this->IPEdit1->setText(ip); + this->IPEdit2->setText(P); + Configuration::CS_IP = ip.toStdString(); + Configuration::CS_Port = P.toStdString(); + accept(); // 关闭对话框并返回 Accepted +} + +void CSInfoW4::QuXiaoBtn1(){ + reject(); // 关闭对话框并返回 Rejected +} diff --git a/UI/W4/csinfow4.h b/UI/W4/csinfow4.h new file mode 100644 index 0000000..03efb71 --- /dev/null +++ b/UI/W4/csinfow4.h @@ -0,0 +1,31 @@ +#ifndef CSINFOW4_H +#define CSINFOW4_H + +#include +#include +#include "Configuration.h" +#include +#include + +QT_BEGIN_NAMESPACE +namespace Ui { class CSInfoW4; } +QT_END_NAMESPACE + +class CSInfoW4 : public QDialog { +Q_OBJECT + +public: + explicit CSInfoW4(QWidget *parent = nullptr); + ~CSInfoW4() override; + void QueRBtn1(); + void QuXiaoBtn1(); + QLineEdit *IPEdit1 = nullptr; + QLineEdit *IPEdit2 = nullptr; + +private: + Ui::CSInfoW4 *ui; + QStringListModel *model; +}; + + +#endif //CSINFOW4_H diff --git a/UI/W4/csinfow4.ui b/UI/W4/csinfow4.ui new file mode 100644 index 0000000..9e7fecd --- /dev/null +++ b/UI/W4/csinfow4.ui @@ -0,0 +1,170 @@ + + + CSInfoW4 + + + + 0 + 0 + 374 + 300 + + + + 选择局域网CS服务器 + + + background-color: rgba(10, 23, 53, 200); +border:none; +border-radius:20px; + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + 13 + + + + QListView { + background-color: rgba(255, 255, 255,0); + border-radius:10px; +} + +QListView::item{ + border-radius:10px; + color: rgb(255, 255, 255); + padding:10px; + margin-top:8px; +} + +QListView::item:hover{ + border-radius:10px; + background-color: rgba(255, 255, 255,50); + color: rgb(0, 0, 0); + font-size:18px; +} +QListView::item:selected { + border-left: 4px solid #009688; + background-color: rgba(182, 210, 255,100); +} + + + + + + + + + + + + 120 + 45 + + + + + 120 + 45 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(200,68,138,0); + border: 2px solid rgba(200,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 取消 + + + + + + + + 120 + 45 + + + + + 120 + 45 + + + + + Bahnschrift Light + 13 + + + + Qt::TabFocus + + + QPushButton{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,68,138,255); +} + +QPushButton:hover{ + border-radius:10px; + color: rgb(255, 255, 255); + background-color: rgba(255,100,150, 255); +} + + + 确认 + + + + + + + + + + + + + + diff --git a/widget.cpp b/widget.cpp deleted file mode 100644 index d94a3a9..0000000 --- a/widget.cpp +++ /dev/null @@ -1,668 +0,0 @@ -#include -#include "widget.h" -#include "./ui_widget.h" - -Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget){ - ui->setupUi(this); - //------------------------------------------------------------------------------------------------ -// COPYFile(WebSubPaths,""); - setAttribute(Qt::WA_TranslucentBackground); //设置窗口背景透明 - setWindowFlags(Qt::FramelessWindowHint | Qt::WindowMinMaxButtonsHint); //去掉窗口边框 - setAreaMovable(ui->widget_3->rect()); - this->setWindowIcon(QIcon(":logo.png")); - CCString logopath = WebSubPaths + "logo.png"; - QIcon trayIconIcon(logopath.c_str()); // 使用你的图标路径 - trayIcon->setIcon(trayIconIcon); - QObject::connect(quitAction, &QAction::triggered, qApp, &QCoreApplication::quit); - QObject::connect(showAction, &QAction::triggered, this, &Widget::show); - trayIconMenu->addAction(showAction); - trayIconMenu->addAction(quitAction); - trayIcon->setContextMenu(trayIconMenu); - trayIcon->show(); - SetPage(0); - Btns.emplace_back(ui->HomeBtn); - Btns.emplace_back(ui->SettingsBtn); - Initlogo(); - //------------------------------------------------------------------------------------------------ - connect(ui->Sub_IP, QOverload::of(&QComboBox::currentIndexChanged),this, &Widget::onCurrentIndexChanged); - connect(ui->HomeBtn, &QPushButton::clicked, this, &Widget::on_pushButton_clicked); - connect(ui->SettingsBtn, &QPushButton::clicked, this, &Widget::on_pushButton_clicked2); - connect(ui->CloseBtn, &QPushButton::clicked, this, [this](){this->close();}); - connect(ui->MinBtn, &QPushButton::clicked, this, [this](){this->showMinimized();}); - connect(ui->OpenServerBtn, &QPushButton::clicked, this, &Widget::OpenServerClick); - connect(ui->RestBtn, &QPushButton::clicked, this, &Widget::ServerConfigInit); - connect(ui->SetSaveBtn, &QPushButton::clicked, this, &Widget::SetSaveBtn); - connect(ui->LogoBtn, &QPushButton::clicked, this, &Widget::SelectFile); - connect(ui->Web_Port, &QLineEdit::textChanged,this, &Widget::onTextChanged); - connect(ui->OpenPCStart, &QCheckBox::stateChanged,this, &Widget::slotCheckedChanged); - ui->HomeBtn->setFocusPolicy(Qt::NoFocus); - ui->SettingsBtn->setFocusPolicy(Qt::NoFocus); - ui->CloseBtn->setFocusPolicy(Qt::NoFocus); - ui->MinBtn->setFocusPolicy(Qt::NoFocus); - ui->OpenServerBtn->setFocusPolicy(Qt::NoFocus); - //------------------------------------------------------------------------------------------------ - ui->ServerConsele->append("Path:" + QApplication::applicationDirPath()); - SetBtn(0); - terminateProcessByName("IPBS_NSSM"); - terminateProcessByName("java"); - terminateProcessByName("nginx"); - QProcess::startDetached("./IPBS_NSSM.exe"); - std::thread([this](){ - CCString s = WebSubPaths + "State.cfg"; - auto AS = CText::ReadConfig(s.c_str()); - auto ASD = CText::ReadConfig(ServerSttingsPath.c_str()); - if(!AS.empty()) { - CCString State = AS["State"]; - int Op = QString(ASD["OpenSleep"].c_str()).toInt(); - if(Op > 0){ - OpenSleepValue = Op; - } - if(State == "Open"){ - while (OpenSleepValue > 0){ - Threading::Sleep(1000 * 1000); - QMetaObject::invokeMethod(this, [this]() { - ui->ServerConsele->append(CCString(std::to_string(OpenSleepValue) + "秒后自动启动服务").c_str()); - }); - OpenSleepValue--; - } - if(!ServerFlag){ - OpenServerClick(); - OpenFlagBtn(true); - } - } - } - }).detach(); - ui->OpenPCStart->setCheckState(checkAutoStartEntry("IPBS_Station(Web)") ? Qt::Checked:Qt::Unchecked); - ServerThread.SetThread(&Widget::ServerListening,this); - ServerThread.Start(); - OpenSerice(true); - foreach (QHostAddress ptr , QNetworkInterface::allAddresses()) { - // 获取ipv4地址 - if (ptr.protocol() == QAbstractSocket::IPv4Protocol) { - // 过滤本地回环127.0.0.1 - if (!ptr.isLoopback()) { - CCString A = ptr.toString().toStdString(); - ui->Sub_IP->addItem(A.c_str()); - } - } - } - //------------------------------------------------------------------------------------------------ -} - -Widget::~Widget(){ - delete ui; -} - -void Widget::on_pushButton_clicked() { - SetBtn(0); - SetPage(0); -} - -void Widget::on_pushButton_clicked2() { - SetBtn(1); - SetPage(1); -} - -void Widget::WebThreadRun() { - CCString jre = WebSubPaths + JavaExe; - CCString cmd = jre + " -jar " + WebSubPaths + "WebSub/SpringWeb.jar"; - bool F = QProcess::startDetached(cmd.c_str()); - if(F){ - ui->ServerConsele->append("Sub Start OK!"); - } - F = QProcess::startDetached(NginxExe.c_str()); - if(F){ - ui->ServerConsele->append("Web Start OK!"); - } -} - -void Widget::closeEvent(QCloseEvent *event) { - QMessageBox msgBox; - msgBox.setWindowTitle(tr("退出程序")); - msgBox.setText(tr("你确定要退出吗?")); - QPushButton *yesButton = msgBox.addButton(tr("结束程序"), QMessageBox::YesRole); - msgBox.addButton(tr("到托盘"), QMessageBox::NoRole); - msgBox.exec(); - if (msgBox.clickedButton() == yesButton) - { - terminateProcessByName("IPBS_NSSM"); - ServerThread.Stop(); - WebThread.Stop(); - terminateProcessByName("java"); - terminateProcessByName("nginx"); - event->accept(); - QCoreApplication::quit(); - } - else - { - this->hide(); - event->ignore(); // 阻止窗口关闭 - } -} - -bool Widget::WebRunFun() { - if(!ServerFlag){ - if(!WebThread.Sign()){ - ServerFlag = true; - SetState(ServerFlag); - WebThread.SetThread(&Widget::WebThreadRun,this); - WebThread.Start(); - } - } - return true; -} - -void Widget::SetPage(int i) { - ui->stackedWidget->setCurrentIndex(i); - if(i == 1){ - ServerSettings = CText::ReadConfig(ServerSttingsPath.c_str()); - if(!ServerSettings.empty()){ - ui->CS_IP->setText(ServerSettings["C/S_IP"].c_str()); - ui->CS_Port->setText(ServerSettings["C/S_PORT"].c_str()); - for (int j = 0; j < ui->Sub_IP->count(); ++j) { - if(ui->Sub_IP->itemText(j) == ServerSettings["Sub_Control_IP"].c_str()){ - ui->Sub_IP->setCurrentIndex(j); - } - } - ui->Sub_Port->setText(ServerSettings["Sub_Control_PORT"].c_str()); - ui->Sub_Audio_Port->setText(ServerSettings["Sub_Control_Audio_PORT"].c_str()); - ui->Web_IP->setText(ui->Sub_IP->currentText()); - if(ServerSettings["Sub_Web_PORT"].empty()){ - ui->Web_Port->setText("5180"); - } - else{ - ui->Web_Port->setText(ServerSettings["Sub_Web_PORT"].c_str()); - } - if(!ServerSettings["OpenSleep"].empty()){ - OpenSleepValue = QString(ServerSettings["OpenSleep"].c_str()).toInt(); - } - if(ServerSettings["Language"] == "English"){ - ui->LabguageBox->setCurrentIndex(1); - } - else{ - ui->LabguageBox->setCurrentIndex(0); - } - QString str = CCString("['http://" + ui->Sub_IP->currentText().toStdString() + ":" + ui->Web_Port->text().toStdString() + "']").c_str(); - ui->Sub_Origins->setText(str); - CCString URL = ui->Sub_IP->currentText().toStdString()+":"+ui->Web_Port->text().toStdString(); - ui->HTTPURL->setText(CCString("http://"+URL).c_str()); - ui->OpenSleep->setValue(OpenSleepValue); - } - } -} - -void Widget::SetBtn(int i) { - for (auto & Btn : Btns) { - Btn->setStyleSheet("QPushButton{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(255, 255, 255, 0);\n" - "}\n" - "\n" - "QPushButton:hover{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(74,89,146, 255);\n" - "}"); - } - Btns[i]->setStyleSheet("QPushButton{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(74,89,146, 255);\n" - "}\n" - "\n" - "QPushButton:hover{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(74,89,146, 255);\n" - "}"); -} - -void Widget::OpenServerClick() { - auto A = CText::ReadConfig(ServerSttingsPath.c_str()); - if(A.size() >= 8){ - try { - ServerReRun(); - } - catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; - } - } - else{ - QMessageBox::information(this,"提示","启动参数错误,请先配置服务器参数!"); - } -} - -void Widget::OpenFlagBtn(bool F) { - if(!F){ - ui->OpenServerBtn->setStyleSheet("QPushButton{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(255,68,138,255);\n" - "}\n" - "\n" - "QPushButton:hover{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(255,100,150, 255);\n" - "}"); - ui->OpenServerBtn->setText("打开服务"); - } - else{ - ui->OpenServerBtn->setStyleSheet("QPushButton{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(255,0,0,255);\n" - "}\n" - "\n" - "QPushButton:hover{\n" - "\tborder-radius:10px;\n" - "\tcolor: rgb(255, 255, 255);\n" - "\tbackground-color: rgba(255,100,150, 255);\n" - "}"); - ui->OpenServerBtn->setText("关闭服务"); - } -} - -void Widget::ServerListening() { - bool F = false,S = false; - Threading::Sleep(1000 * 1000 * 60); - while (ServerThread.Sign()){ - try { - F = isJarRunning("java"); - S = isJarRunning("nginx"); - } - catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; - } - char bus[1024] = {0}; - if(ServerFlag){ - sprintf(bus,"%d天%d小时%d分%d秒",t,h,f,s); - s++; - if(s >= 60){ - f++; - s = 0; - if(f >= 60){ - f = 0; - if(h >= 24){ - t++; - h = 0; - } - h++; - } - } - } - QMetaObject::invokeMethod(this, [this,F,S,bus](){ - SetSuBState(F); - SetWebState(S); - // 获取当前的日期和时间 - QDateTime currentDateTime = QDateTime::currentDateTime(); - // 将日期时间对象转换为字符串格式 - QString currentTime = currentDateTime.toString("yyyy-MM-dd-hh:mm:ss"); - ui->NowTime->setText(currentTime); - QString str = bus; - ui->RunTime->setText(str); - }); - if(!F && ServerFlag){ - QMetaObject::invokeMethod(this, [this](){ - CCString jre = WebSubPaths + JavaExe; - CCString cmd = jre + " -jar " + WebSubPaths + "WebSub/SpringWeb.jar"; - bool F = QProcess::startDetached(cmd.c_str()); - if(F){ - ui->ServerConsele->append("Sub Res Start OK!"); - } - Threading::Sleep(1000 * 1000 * 10); - }); - } - if(!S && ServerFlag){ - try{ - F = QProcess::startDetached(NginxExe.c_str()); - if(F){ - ui->ServerConsele->append("Web Res Start OK!"); - } - Threading::Sleep(1000 * 1000 * 10); - } - catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; - } - } - Threading::Sleep(1000 * 1000); - } -} - -bool Widget::isJarRunning(const char *jarName) { -#ifdef _WIN32 - CCString str = jarName; - str.append(".exe"); - HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) { - return false; - } - PROCESSENTRY32 pe32; - pe32.dwSize = sizeof(PROCESSENTRY32); - if (Process32First(hSnapshot, &pe32)) { - do { - if (_tcsstr(pe32.szExeFile, str.c_str()) != nullptr) { - CloseHandle(hSnapshot); - return true; - } - } while (Process32Next(hSnapshot, &pe32)); - } - - CloseHandle(hSnapshot); - return false; -#elif __linux__ -#endif -} - -bool Widget::terminateProcessByName(const char *processName) { -#ifdef _WIN32 - CCString str = processName; - str.append(".exe"); - HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); - if (hSnapshot == INVALID_HANDLE_VALUE) { - return false; - } - - PROCESSENTRY32 pe32; - pe32.dwSize = sizeof(PROCESSENTRY32); - - if (Process32First(hSnapshot, &pe32)) { - do { - if (_tcscmp(pe32.szExeFile, str.c_str()) == 0) { - HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pe32.th32ProcessID); - if (hProcess != NULL) { - TerminateProcess(hProcess, 0); - CloseHandle(hProcess); - } - } - } while (Process32Next(hSnapshot, &pe32)); - } - - CloseHandle(hSnapshot); - return true; -#elif __linux__ -#endif -} - -void Widget::ServerReRun() { - if(ServerFlag){ - try { - terminateProcessByName("java"); - terminateProcessByName("nginx"); - if(ServerFlag){ - WebThread.Stop(); - ui->ServerConsele->append("Server Close"); - OpenFlagBtn(false); - ServerFlag = false; - SetState(ServerFlag); - ui->RunTime->setVisible(false); - t = 0;h = 0;f = 0;s = 0; - } - } - catch (const std::exception& e) { - std::cerr << "Error: " << e.what() << std::endl; - } - } - else{ - WebRunFun(); - OpenFlagBtn(true); - t = 0;h = 0;f = 0;s = 0; - ui->RunTime->setVisible(true); - } -} - -void Widget::onCurrentIndexChanged(int index) { - ui->Web_IP->setText(ui->Sub_IP->currentText()); - CCString URL = ui->Sub_IP->currentText().toStdString()+":"+ui->Web_Port->text().toStdString(); - ui->HTTPURL->setText(CCString("http://"+URL).c_str()); - QString str = CCString("['http://" + ui->Sub_IP->currentText().toStdString() + ":" + ServerSettings["Sub_Web_PORT"] + "']").c_str(); - ui->Sub_Origins->setText(str); -} - -void Widget::SetSuBState(bool F) { - if(F){ - ui->SubLabel->setStyleSheet("color: rgb(0, 255, 0);"); - ui->SubLabel->setText("后端:在线"); - } - else{ - ui->SubLabel->setStyleSheet("color: rgb(255, 0, 0);"); - ui->SubLabel->setText("后端:离线"); - } -} - -void Widget::SetWebState(bool F) { - if(F){ - ui->WebLabel->setStyleSheet("color: rgb(0, 255, 0);"); - ui->WebLabel->setText("前端:在线"); - } - else{ - ui->WebLabel->setStyleSheet("color: rgb(255, 0, 0);"); - ui->WebLabel->setText("前端:离线"); - } -} - -void Widget::onTextChanged(const QString &text) { - ui->Web_IP->setText(ui->Sub_IP->currentText()); - CCString URL = ui->Sub_IP->currentText().toStdString()+":"+ui->Web_Port->text().toStdString(); - ui->HTTPURL->setText(CCString("http://"+URL).c_str()); - QString str = CCString("['http://" + ui->Web_IP->text().toStdString() + ":" + text.toStdString() + "']").c_str(); - ui->Sub_Origins->setText(str); -} - -void Widget::SetSaveBtn() { - if(ui->CS_IP->text().isEmpty()){ - QMessageBox::information(this, "Error", "C/S_IP不能为空"); - return; - } - if(ui->CS_Port->text().isEmpty()){ - QMessageBox::information(this, "Error", "C/S_Port不能为空"); - return; - } - if(ui->Sub_IP->currentText().isEmpty()){ - QMessageBox::information(this, "Error", "Sub_IP不能为空"); - return; - } - if(ui->Sub_Port->text().isEmpty()){ - QMessageBox::information(this, "Error", "Sub_Port不能为空"); - return; - } - if(ui->Web_Port->text().isEmpty()){ - QMessageBox::information(this, "Error", "Web_Port不能为空"); - return; - } - if(ui->Web_IP->text().isEmpty()){ - QMessageBox::information(this, "Error", "Web_IP不能为空"); - return; - } - if(ui->Sub_Audio_Port->text().isEmpty()){ - QMessageBox::information(this, "Error", "Sub_Audio_Port不能为空"); - return; - } - if(ui->Sub_Origins->text().isEmpty()){ - QMessageBox::information(this, "Error", "Sub_Origins不能为空"); - return; - } - SetServerConfig(); - QMessageBox::information(this, "Success", "Write OK!"); -} - -void Widget::ServerConfigInit() { - QString IP = ui->Sub_IP->currentText(); - ui->CS_IP->setText(IP); - ui->CS_Port->setText("5418"); - ui->Web_IP->setText(IP); - ui->Sub_Port->setText("5417"); - ui->Web_Port->setText("5180"); - ui->Sub_Audio_Port->setText("52018"); - QString str = CCString("['http://" + ui->Web_IP->text().toStdString() + ":" + ui->Web_Port->text().toStdString() + "']").c_str(); - ui->Sub_Origins->setText(str); - ui->LabguageBox->setCurrentIndex(0); -} - -void Widget::Initlogo() { - CCString str = WebSubPaths + "html/assets/logo-CuXNbvLG.png"; - QPixmap pixmap(str.c_str()); // 替换为你的图片路径 - ui->logoIMG->setPixmap(pixmap); - ui->logoIMG->setScaledContents(true); // 图片自动缩放以适应 QLabel 大小 - ui->logoIMG->setMaximumSize(111,61); // 设置 QLabel 最小尺寸 - ui->logos->setPixmap(pixmap); - ui->logos->setScaledContents(true); // 图片自动缩放以适应 QLabel 大小 - ui->logoIMG->setMaximumSize(320,180); // 设置 QLabel 最小尺寸 -} - -void Widget::SelectFile() { - try { - //定义文件对话框类 - QFileDialog *fileDialog = new QFileDialog(this); - //定义文件对话框标题 - fileDialog->setWindowTitle(QStringLiteral("选择文件")); - //设置打开的文件路径 - fileDialog->setDirectory("./"); - //设置文件过滤器,只显示.ui .cpp 文件,多个过滤文件使用空格隔开 - fileDialog->setNameFilter(tr("File(*.png*)")); - //设置可以选择多个文件,默认为只能选择一个文件QFileDialog::ExistingFiles - fileDialog->setFileMode(QFileDialog::ExistingFile); - //设置视图模式 - fileDialog->setViewMode(QFileDialog::Detail); - //获取选择的文件的路径 - QStringList fileNames; - if (fileDialog->exec()) { - fileNames = fileDialog->selectedFiles(); - } - if(!fileNames.isEmpty()){ - CCString fileName = fileNames[0].toStdString(); - CCFile file = CCFile(fileName.c_str(), CC::ios::rb, false); - CCString str = WebSubPaths + "html/assets/logo-CuXNbvLG.png"; - ui->ServerConsele->append(CCString("OLD:"+str).c_str()); - ui->ServerConsele->append(CCString("New:"+fileName).c_str()); - bool F = file.Copy(str); - if(F){ - Initlogo(); - QMessageBox::information(this, "Success", "Copy OK!"); - } - else{ - QMessageBox::information(this, "Error", "Failed to copy file,Chinese is not supported"); - } - } - } - catch (const std::exception& e) { - ui->ServerConsele->append(e.what()); - } -} - -void Widget::SetServerConfig() { - FILE *fp = fopen(ServerSttingsPath.c_str(), "w"); - if (fp == nullptr) { - QMessageBox::information(this, "Error", "Failed to open ServerSttings file"); - return; - } - // 写入配置数据 - fprintf(fp, "C/S_IP:%s\n",ui->CS_IP->text().toStdString().c_str()); - fprintf(fp, "C/S_PORT:%s\n",ui->CS_Port->text().toStdString().c_str()); - fprintf(fp, "Sub_Control_IP:%s\n",ui->Sub_IP->currentText().toStdString().c_str()); - fprintf(fp, "Sub_Control_PORT:%s\n",ui->Sub_Port->text().toStdString().c_str()); - fprintf(fp, "Sub_Control_Audio_PORT:%s\n",ui->Sub_Audio_Port->text().toStdString().c_str()); - fprintf(fp, "Sub_Web_PORT:%s\n",ui->Web_Port->text().toStdString().c_str()); - fprintf(fp, "Origins:%s\n",ui->Sub_Origins->text().toStdString().c_str()); - fprintf(fp, "#中文简体,English\n"); - fprintf(fp, "Language:%s\n",ui->LabguageBox->currentText().toStdString().c_str()); - fprintf(fp, "OpenSleep:%d\n",ui->OpenSleep->value()); - fclose(fp); - fp = fopen(NginxSttingsPath.c_str(), "w"); - if (fp == nullptr) { - QMessageBox::information(this, "Error", "Failed to open NginxSttings file"); - return; - } - // 写入配置数据 - fprintf(fp, "worker_processes 1;\n" - "events {\n" - " worker_connections 1024;\n" - "}\n" - "http {\n" - " include mime.types;\n" - " default_type application/octet-stream;\n" - " sendfile on;\n" - " keepalive_timeout 65;\n" - " client_max_body_size 500m;\n" - " server {\n" - " listen %s;\n" - " server_name %s;\n" - " location / {\n" - " root html;\n" - " index index.html index.htm;\n" - " try_files $uri $uri/ /index.html;\n" - " # try_files $uri $uri/ @router;\n" - " }\n" - " location /api/ {\n" - " #rewrite ^.+api/?(.*)$ /$1 break; \n" - " rewrite ^/api/(.*)$ /$1 break; \n" - " proxy_pass http://%s:%s/;\n" - " proxy_redirect off;\n" - " proxy_set_header Host $host;\n" - " proxy_set_header X-Real-IP $remote_addr;\n" - " proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n" - " }\n" - " error_page 500 502 503 504 /50x.html;\n" - " location = /50x.html {\n" - " root html;\n" - " }\n" - " }\n" - "}",ui->Web_Port->text().toStdString().c_str(),ui->Web_IP->text().toStdString().c_str(), - ui->Sub_IP->currentText().toStdString().c_str(),ui->Sub_Port->text().toStdString().c_str()); - fclose(fp); -} - -void Widget::SetState(bool F) { - CCString str = WebSubPaths + "State.cfg"; - CCFile file = CCFile(str.c_str(), CC::ios::w); - file.Write(F ? "State:Open\n" : "State:Close\n"); - file.Close(); -} - -void Widget::SetAutoStart(const QString &path, bool enable) { - QSettings startupSettings("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows", QSettings::NativeFormat); - if (enable) { - startupSettings.setValue("IPBS_Station(Web)", path); - } else { - startupSettings.remove("IPBS_Station(Web)"); - } -} - -void Widget::OpenSerice(bool F) { -#ifdef _WIN32 - -#elif __linux__ - -#endif -} - -void Widget::slotCheckedChanged(int i) { - CCString str = "IPBS_Start"; - if(ui->OpenPCStart->isChecked()){ - SetAutoStart(str.c_str(),true); - } else{ - SetAutoStart(str.c_str(),false); - } - str = WebSubPaths + QApplication::applicationName().toStdString() + ".exe.lnk"; - if(ui->OpenPCStart->isChecked()){ - CreateShortO(); - CCString A = OpenKit + QApplication::applicationName().toStdString() + ".exe.lnk"; - CCFile file = CCFile(str.c_str(), CC::ios::w,false); - file.Copy(A); - file.Deleted(); - } else{ - str = OpenKit + QApplication::applicationName().toStdString() + ".exe.lnk"; - CCFile file = CCFile(str.c_str(), CC::ios::w,false); - file.Deleted(); - } -} - -bool Widget::checkAutoStartEntry(const QString &appName) { - QSettings startupSettings("HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Windows", QSettings::NativeFormat); - return startupSettings.contains(appName); -} - - - -