1.0
This commit is contained in:
131
.vscode/compile_commands.json
vendored
Normal file
131
.vscode/compile_commands.json
vendored
Normal file
@@ -0,0 +1,131 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\tests\\crypto_smoke_test.cpp.obj", "tests\\crypto_smoke_test.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "tests\\crypto_smoke_test.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\src\\app.cpp.obj", "src\\app.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\app.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\src\\config.cpp.obj", "src\\config.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\config.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\src\\fs_utils.cpp.obj", "src\\fs_utils.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\fs_utils.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\src\\http.cpp.obj", "src\\http.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\http.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\src\\json.cpp.obj", "src\\json.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\json.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\src\\labels.cpp.obj", "src\\labels.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\labels.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c11", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\third_party\\libbcrypt\\crypt_blowfish\\wrapper.c.obj", "third_party\\libbcrypt\\crypt_blowfish\\wrapper.c", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "third_party\\libbcrypt\\crypt_blowfish\\wrapper.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c11", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\third_party\\libbcrypt\\crypt_blowfish\\crypt_blowfish.c.obj", "third_party\\libbcrypt\\crypt_blowfish\\crypt_blowfish.c", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "third_party\\libbcrypt\\crypt_blowfish\\crypt_blowfish.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c11", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\crypto_smoke_test\\windows\\x64\\release\\third_party\\libbcrypt\\crypt_blowfish\\crypt_gensalt.c.obj", "third_party\\libbcrypt\\crypt_blowfish\\crypt_gensalt.c", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "third_party\\libbcrypt\\crypt_blowfish\\crypt_gensalt.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\app.cpp.obj", "src\\app.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\app.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\config.cpp.obj", "src\\config.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\config.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\fs_utils.cpp.obj", "src\\fs_utils.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\fs_utils.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\http.cpp.obj", "src\\http.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\http.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\json.cpp.obj", "src\\json.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\json.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\labels.cpp.obj", "src\\labels.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\labels.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\src\\main.cpp.obj", "src\\main.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\main.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c11", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\third_party\\libbcrypt\\crypt_blowfish\\wrapper.c.obj", "third_party\\libbcrypt\\crypt_blowfish\\wrapper.c", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "third_party\\libbcrypt\\crypt_blowfish\\wrapper.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c11", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\third_party\\libbcrypt\\crypt_blowfish\\crypt_blowfish.c.obj", "third_party\\libbcrypt\\crypt_blowfish\\crypt_blowfish.c", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "third_party\\libbcrypt\\crypt_blowfish\\crypt_blowfish.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c11", "/Iinclude", "/Ithird_party\\libbcrypt\\crypt_blowfish", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\o\\openssl3\\3.6.1\\f6105560d35d4708bbf8084662ae6c0b\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\z\\zlib\\v1.3.2\\1087d98a25354760941affad70a541d9\\include", "/IC:\\Users\\dongj\\AppData\\Local\\.xmake\\packages\\m\\mariadb-connector-c\\3.4.8\\15faf4d65a8b4e2b90b71d8039471456\\include", "/DNDEBUG", "/w", "/Fobuild\\.objs\\dps_manager_server\\windows\\x64\\release\\third_party\\libbcrypt\\crypt_blowfish\\crypt_gensalt.c.obj", "third_party\\libbcrypt\\crypt_blowfish\\crypt_gensalt.c", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "third_party\\libbcrypt\\crypt_blowfish\\crypt_gensalt.c"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/DNDEBUG", "/Fobuild\\.objs\\fs_utils_smoke_test\\windows\\x64\\release\\tests\\fs_utils_smoke_test.cpp.obj", "tests\\fs_utils_smoke_test.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "tests\\fs_utils_smoke_test.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/DNDEBUG", "/Fobuild\\.objs\\fs_utils_smoke_test\\windows\\x64\\release\\src\\fs_utils.cpp.obj", "src\\fs_utils.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\fs_utils.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/DNDEBUG", "/Fobuild\\.objs\\json_smoke_test\\windows\\x64\\release\\tests\\json_smoke_test.cpp.obj", "tests\\json_smoke_test.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "tests\\json_smoke_test.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/DNDEBUG", "/Fobuild\\.objs\\json_smoke_test\\windows\\x64\\release\\src\\json.cpp.obj", "src\\json.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\json.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/DNDEBUG", "/Fobuild\\.objs\\labels_smoke_test\\windows\\x64\\release\\tests\\labels_smoke_test.cpp.obj", "tests\\labels_smoke_test.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "tests\\labels_smoke_test.cpp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"directory": "l:\\Qt_Project\\DPS_Manager\\服务端\\DpsManagerServer",
|
||||||
|
"arguments": ["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe", "/c", "/nologo", "/MD", "/W3", "/WX", "/O2", "/std:c++17", "/Iinclude", "/DDPS_WINDOWS", "/DOPENSSL_SUPPRESS_DEPRECATED", "/EHsc", "/DNDEBUG", "/Fobuild\\.objs\\labels_smoke_test\\windows\\x64\\release\\src\\labels.cpp.obj", "src\\labels.cpp", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\ATLMFC\\include", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Auxiliary\\VS\\include", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\include\\10.0.22621.0\\ucrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\um", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\shared", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\winrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\10\\\\include\\10.0.22621.0\\\\cppwinrt", "-imsvc", "C:\\Program Files (x86)\\Windows Kits\\NETFXSDK\\4.8\\include\\um", "-imsvc", "H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.34.31933\\include"],
|
||||||
|
"file": "src\\labels.cpp"
|
||||||
|
}]
|
||||||
9
.xmake/windows/x64/cache/config
vendored
Normal file
9
.xmake/windows/x64/cache/config
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
mtimes = {
|
||||||
|
["xmake.lua"] = 1776155854
|
||||||
|
},
|
||||||
|
recheck = false,
|
||||||
|
options = {
|
||||||
|
clean = true
|
||||||
|
}
|
||||||
|
}
|
||||||
128
.xmake/windows/x64/cache/detect
vendored
Normal file
128
.xmake/windows/x64/cache/detect
vendored
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
{
|
||||||
|
find_program_fetch_package_system = {
|
||||||
|
nasm = [[H:\mingw64\bin\nasm.exe]],
|
||||||
|
cmake = [[H:\Cmake\bin\cmake]],
|
||||||
|
ninja = [[H:\mingw64\bin\ninja.exe]]
|
||||||
|
},
|
||||||
|
find_program_fetch_package_xmake = {
|
||||||
|
nasm = false,
|
||||||
|
ninja = false,
|
||||||
|
["jom.exe"] = false,
|
||||||
|
cmake = false,
|
||||||
|
perl = false
|
||||||
|
},
|
||||||
|
["lib.detect.has_flags"] = {
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cxx__-nologo_-O2"] = true,
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cc_cxflags_-nologo_cl_external_includedir"] = true,
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cc_cxflags_-nologo_-DNDEBUG"] = true,
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cxx_cxflags_-nologo_-DNDEBUG"] = true,
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cc_cxflags_-nologo_-std:c11"] = true,
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cc__-nologo_-O2"] = true,
|
||||||
|
["windows_x64_h:\\visual studio\\ide\\vc\\tools\\msvc\\14.43.34808\\bin\\hostx64\\x64\\cl.exe__cxx_cxflags_-nologo_cl_external_includedir"] = true
|
||||||
|
},
|
||||||
|
find_package_windows_x64_fetch_package_xmake = {
|
||||||
|
["xmake::zlib_1087d98a25354760941affad70a541d9_release_v1.3.2_external"] = {
|
||||||
|
linkdirs = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9\lib]]
|
||||||
|
},
|
||||||
|
links = {
|
||||||
|
"zlib"
|
||||||
|
},
|
||||||
|
sysincludedirs = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9\include]]
|
||||||
|
},
|
||||||
|
version = "v1.3.2",
|
||||||
|
license = "zlib",
|
||||||
|
libfiles = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9\lib\zlib.lib]]
|
||||||
|
},
|
||||||
|
static = true
|
||||||
|
},
|
||||||
|
["xmake::mariadb-connector-c_15faf4d65a8b4e2b90b71d8039471456_release_3.4.8_external"] = {
|
||||||
|
links = {
|
||||||
|
"mariadbclient"
|
||||||
|
},
|
||||||
|
sysincludedirs = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\include]]
|
||||||
|
},
|
||||||
|
version = "3.4.8",
|
||||||
|
libfiles = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\mariadbclient.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\libmariadb.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\libmariadb.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\auth_gssapi_client.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\caching_sha2_password.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\client_ed25519.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\dialog.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\mysql_clear_password.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\parsec.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\pvio_shmem.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\sha256_password.dll]]
|
||||||
|
},
|
||||||
|
linkdirs = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb]]
|
||||||
|
},
|
||||||
|
shared = true,
|
||||||
|
static = true,
|
||||||
|
license = "LGPL-2.1",
|
||||||
|
syslinks = {
|
||||||
|
"secur32",
|
||||||
|
"shlwapi",
|
||||||
|
"crypt32",
|
||||||
|
"bcrypt",
|
||||||
|
"advapi32",
|
||||||
|
"iphlpapi",
|
||||||
|
"ws2_32"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["xmake::openssl3_f6105560d35d4708bbf8084662ae6c0b_release_3.6.1_external"] = {
|
||||||
|
links = {
|
||||||
|
"libssl",
|
||||||
|
"libcrypto"
|
||||||
|
},
|
||||||
|
sysincludedirs = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\include]]
|
||||||
|
},
|
||||||
|
version = "3.6.1",
|
||||||
|
libfiles = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib\libssl.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib\libcrypto.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib\ossl-modules\legacy.dll]]
|
||||||
|
},
|
||||||
|
linkdirs = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib]]
|
||||||
|
},
|
||||||
|
shared = true,
|
||||||
|
static = true,
|
||||||
|
license = "Apache-2.0",
|
||||||
|
syslinks = {
|
||||||
|
"ws2_32",
|
||||||
|
"user32",
|
||||||
|
"crypt32",
|
||||||
|
"advapi32"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
find_program = {
|
||||||
|
tar = [[C:\Windows\System32\tar.exe]],
|
||||||
|
nim = false,
|
||||||
|
["cl.exe"] = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]],
|
||||||
|
git = [[C:\Program Files\Git\cmd\git.exe]],
|
||||||
|
["H:\\Visual Studio\\IDE\\VC\\Tools\\MSVC\\14.43.34808\\bin\\HostX64\\x64\\cl.exe"] = [[h:\visual studio\ide\vc\tools\msvc\14.43.34808\bin\hostx64\x64\cl.exe]],
|
||||||
|
gzip = [[H:\ToonuOne\gzip.exe]]
|
||||||
|
},
|
||||||
|
find_programver_fetch_package_system = {
|
||||||
|
["H:\\mingw64\\bin\\nasm.exe"] = "2.16.03",
|
||||||
|
["H:\\mingw64\\bin\\ninja.exe"] = "1.13.1",
|
||||||
|
["H:\\Cmake\\bin\\cmake"] = "3.31.1"
|
||||||
|
},
|
||||||
|
find_program_msvc_arch_x64_plat_windows_checktoolld = {
|
||||||
|
["link.exe"] = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\link.exe]]
|
||||||
|
},
|
||||||
|
find_program_msvc_arch_x64_plat_windows_checktoolcxx = {
|
||||||
|
["cl.exe"] = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
find_program_msvc_arch_x64_plat_windows_checktoolcc = {
|
||||||
|
["cl.exe"] = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
}
|
||||||
|
}
|
||||||
67
.xmake/windows/x64/cache/history
vendored
Normal file
67
.xmake/windows/x64/cache/history
vendored
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
{
|
||||||
|
cmdlines = {
|
||||||
|
"xmake check",
|
||||||
|
"xmake build fs_utils_smoke_test",
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\update_intellisense.lua .vscode clangd]],
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\explorer.lua]],
|
||||||
|
"xmake check",
|
||||||
|
"xmake build fs_utils_smoke_test",
|
||||||
|
"xmake build dps_manager_server",
|
||||||
|
"xmake build dps_manager_server",
|
||||||
|
"xmake build crypto_smoke_test",
|
||||||
|
"xmake run",
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\update_intellisense.lua .vscode clangd]],
|
||||||
|
"xmake check",
|
||||||
|
"xmake run",
|
||||||
|
"xmake build labels_smoke_test",
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\config.lua]],
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\update_intellisense.lua .vscode clangd]],
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\explorer.lua]],
|
||||||
|
"xmake check",
|
||||||
|
"xmake build labels_smoke_test",
|
||||||
|
"xmake build dps_manager_server",
|
||||||
|
"xmake ",
|
||||||
|
"xmake f -c",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake build dps_manager_server",
|
||||||
|
"xmake f -m debug",
|
||||||
|
"xmake build crypto_smoke_test",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake ",
|
||||||
|
"xmake f -p windows -a x64 -m debug",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
"xmake g --proxy=http://127.0.0.1:7897",
|
||||||
|
"xmake ",
|
||||||
|
"xmake g --proxy=http://127.0.0.1:7897",
|
||||||
|
"xmake -r",
|
||||||
|
"xmake g --proxy=http://127.0.0.1:7897",
|
||||||
|
"xmake ",
|
||||||
|
"xmake ",
|
||||||
|
"xmake ",
|
||||||
|
"xmake ",
|
||||||
|
"xmake ",
|
||||||
|
"xmake ",
|
||||||
|
"xmake run",
|
||||||
|
"xmake run",
|
||||||
|
[[xmake lua "C:\\Program Files\\xmake\\modules\\private\\utils\\statistics.lua"]],
|
||||||
|
[[xmake lua "C:\\Program Files\\xmake\\actions\\build\\cleaner.lua"]],
|
||||||
|
"xmake g --proxy=http://127.0.0.1:7897",
|
||||||
|
"xmake build",
|
||||||
|
"xmake f -m debug",
|
||||||
|
"xmake build -v",
|
||||||
|
"xmake g --proxy=http://127.0.0.1:7897",
|
||||||
|
"xmake build -v",
|
||||||
|
"xmake g --proxy=http://127.0.0.1:7897",
|
||||||
|
"xmake build",
|
||||||
|
"xmake run",
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\explorer.lua]],
|
||||||
|
[[xmake l c:\Users\dongj\.trae-cn\extensions\tboox.xmake-vscode-2.5.4-universal\assets\config.lua]]
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.xmake/windows/x64/cache/option
vendored
Normal file
1
.xmake/windows/x64/cache/option
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{ }
|
||||||
87
.xmake/windows/x64/cache/package
vendored
Normal file
87
.xmake/windows/x64/cache/package
vendored
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
openssl3 = {
|
||||||
|
version = "3.6.1",
|
||||||
|
envs = {
|
||||||
|
PATH = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\n\nasm\2.16.03\a21bbd6e91e3451bb2fbb65664f020c8\bin]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\s\strawberry-perl\5.32.0+1\b64caa2665494fc5b5ca88386f62ce65\bin]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\s\strawberry-perl\5.32.0+1\b64caa2665494fc5b5ca88386f62ce65\perl\bin]]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links = {
|
||||||
|
"libssl",
|
||||||
|
"libcrypto"
|
||||||
|
},
|
||||||
|
sysincludedirs = [[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\include]],
|
||||||
|
__requirestr = "openssl3",
|
||||||
|
license = "Apache-2.0",
|
||||||
|
installdir = [[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b]],
|
||||||
|
linkdirs = [[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib]],
|
||||||
|
syslinks = {
|
||||||
|
"ws2_32",
|
||||||
|
"user32",
|
||||||
|
"crypt32",
|
||||||
|
"advapi32"
|
||||||
|
},
|
||||||
|
libfiles = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib\libssl.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib\libcrypto.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b\lib\ossl-modules\legacy.dll]]
|
||||||
|
},
|
||||||
|
static = true,
|
||||||
|
__enabled = true,
|
||||||
|
shared = true
|
||||||
|
},
|
||||||
|
["mariadb-connector-c"] = {
|
||||||
|
version = "3.4.8",
|
||||||
|
envs = {
|
||||||
|
PATH = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\n\ninja\v1.13.1\fd5a0995dca64146a4f4c4dbff879aad\bin]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\c\cmake\4.2.3\674adf9609f646bc9f678b5e946b080a\bin]]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
links = "mariadbclient",
|
||||||
|
sysincludedirs = [[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\include]],
|
||||||
|
__requirestr = "mariadb-connector-c",
|
||||||
|
license = "LGPL-2.1",
|
||||||
|
installdir = [[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456]],
|
||||||
|
linkdirs = [[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb]],
|
||||||
|
syslinks = {
|
||||||
|
"secur32",
|
||||||
|
"shlwapi",
|
||||||
|
"crypt32",
|
||||||
|
"bcrypt",
|
||||||
|
"advapi32",
|
||||||
|
"iphlpapi",
|
||||||
|
"ws2_32"
|
||||||
|
},
|
||||||
|
libfiles = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\mariadbclient.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\libmariadb.lib]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\libmariadb.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\auth_gssapi_client.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\caching_sha2_password.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\client_ed25519.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\dialog.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\mysql_clear_password.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\parsec.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\pvio_shmem.dll]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456\lib\mariadb\plugin\sha256_password.dll]]
|
||||||
|
},
|
||||||
|
static = true,
|
||||||
|
__enabled = true,
|
||||||
|
shared = true
|
||||||
|
},
|
||||||
|
zlib = {
|
||||||
|
version = "v1.3.2",
|
||||||
|
links = "zlib",
|
||||||
|
sysincludedirs = [[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9\include]],
|
||||||
|
__requirestr = "zlib",
|
||||||
|
installdir = [[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9]],
|
||||||
|
license = "zlib",
|
||||||
|
linkdirs = [[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9\lib]],
|
||||||
|
static = true,
|
||||||
|
__enabled = true,
|
||||||
|
libfiles = [[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9\lib\zlib.lib]]
|
||||||
|
}
|
||||||
|
}
|
||||||
1
.xmake/windows/x64/cache/project
vendored
Normal file
1
.xmake/windows/x64/cache/project
vendored
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{ }
|
||||||
9
.xmake/windows/x64/cache/references
vendored
Normal file
9
.xmake/windows/x64/cache/references
vendored
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
packages = {
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\s\strawberry-perl\5.32.0+1\b64caa2665494fc5b5ca88386f62ce65]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\j\jom\1.1.4\9a79be4085074ec7bc62e782058794c3]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\o\openssl3\3.6.1\f6105560d35d4708bbf8084662ae6c0b]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\z\zlib\v1.3.2\1087d98a25354760941affad70a541d9]],
|
||||||
|
[[C:\Users\dongj\AppData\Local\.xmake\packages\m\mariadb-connector-c\3.4.8\15faf4d65a8b4e2b90b71d8039471456]]
|
||||||
|
}
|
||||||
|
}
|
||||||
13
.xmake/windows/x64/cache/repository
vendored
Normal file
13
.xmake/windows/x64/cache/repository
vendored
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
artifacts_urls = {
|
||||||
|
"https://gitee.com/xmake-mirror/build-artifacts.git",
|
||||||
|
"https://gitlab.com/xmake-mirror/build-artifacts.git",
|
||||||
|
"https://github.com/xmake-mirror/build-artifacts.git"
|
||||||
|
},
|
||||||
|
mainurls = {
|
||||||
|
"https://gitee.com/tboox/xmake-repo.git",
|
||||||
|
"https://gitcode.com/xmake-io/xmake-repo.git",
|
||||||
|
"https://gitlab.com/tboox/xmake-repo.git",
|
||||||
|
"https://github.com/xmake-io/xmake-repo.git"
|
||||||
|
}
|
||||||
|
}
|
||||||
219
.xmake/windows/x64/cache/toolchain
vendored
Normal file
219
.xmake/windows/x64/cache/toolchain
vendored
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
{
|
||||||
|
tool_target_labels_smoke_test_windows_x64_cxx = {
|
||||||
|
toolname = "cl",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
nim_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = false,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_dps_manager_server_windows_x64_cc = {
|
||||||
|
toolname = "cl",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
tool_target_json_smoke_test_windows_x64_ld = {
|
||||||
|
toolname = "link",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\link.exe]]
|
||||||
|
},
|
||||||
|
clang_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_json_smoke_test_windows_x64_cxx = {
|
||||||
|
toolname = "cl",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
fpc_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
gfortran_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
nasm_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_crypto_smoke_test_windows_x64_cxx = {
|
||||||
|
toolname = "cl",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
go_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_fs_utils_smoke_test_windows_x64_cxx = {
|
||||||
|
toolname = "cl",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
tool_target_fs_utils_smoke_test_windows_x64_ld = {
|
||||||
|
toolname = "link",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\link.exe]]
|
||||||
|
},
|
||||||
|
zig_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
msvc_arch_x64_plat_windows = {
|
||||||
|
vs_toolset = "14.43.34808",
|
||||||
|
plat = "windows",
|
||||||
|
vs = "2022",
|
||||||
|
vs_sdkver = "10.0.22621.0",
|
||||||
|
vcarchs = {
|
||||||
|
"arm",
|
||||||
|
"arm64",
|
||||||
|
"arm64ec",
|
||||||
|
"x64",
|
||||||
|
"x86"
|
||||||
|
},
|
||||||
|
__checked = "2022",
|
||||||
|
vcvars = {
|
||||||
|
WindowsSdkVerBinPath = [[C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\]],
|
||||||
|
VCToolsRedistDir = [[H:\Visual Studio\IDE\VC\Redist\MSVC\14.42.34433\]],
|
||||||
|
UCRTVersion = "10.0.22621.0",
|
||||||
|
VS170COMNTOOLS = [[H:\Visual Studio\IDE\Common7\Tools\]],
|
||||||
|
WindowsSdkDir = [[C:\Program Files (x86)\Windows Kits\10\]],
|
||||||
|
WindowsLibPath = [[C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.22621.0;C:\Program Files (x86)\Windows Kits\10\References\10.0.22621.0]],
|
||||||
|
VCToolsVersion = "14.43.34808",
|
||||||
|
VSCMD_ARG_app_plat = "Desktop",
|
||||||
|
WindowsSDKVersion = "10.0.22621.0",
|
||||||
|
PATH = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64;H:\Visual Studio\IDE\Common7\IDE\VC\VCPackages;H:\Visual Studio\IDE\Common7\IDE\CommonExtensions\Microsoft\TestWindow;H:\Visual Studio\IDE\Common7\IDE\CommonExtensions\Microsoft\TeamFoundation\Team Explorer;H:\Visual Studio\IDE\MSBuild\Current\bin\Roslyn;C:\Program Files (x86)\Microsoft SDKs\Windows\v10.0A\bin\NETFX 4.8 Tools\x64\;C:\Program Files (x86)\HTML Help Workshop;H:\Visual Studio\IDE\Common7\IDE\CommonExtensions\Microsoft\FSharp\Tools;H:\Visual Studio\IDE\Team Tools\DiagnosticsHub\Collector;C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\\x64;C:\Program Files (x86)\Windows Kits\10\bin\\x64;H:\Visual Studio\IDE\\MSBuild\Current\Bin\amd64;C:\Windows\Microsoft.NET\Framework64\v4.0.30319;H:\Visual Studio\IDE\Common7\IDE\;H:\Visual Studio\IDE\Common7\Tools\;C:\Program Files\Git\mingw64\bin;C:\Program Files\Git\usr\bin;C:\Users\dongj\bin;H:\mingw64\bin;C:\Program Files\Python313\Scripts;C:\Program Files\Python313;H:\Cmake\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v12.3\libnvvp;C:\Program Files\Microsoft\jdk-11.0.12.7-hotspot\bin;C:\Program Files\Common Files\Oracle\Java\javapath;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0;C:\WINDOWS\System32\OpenSSH;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\Program Files\dotnet;C:\Program Files\Git\cmd;H:\Bandizip;H:\Visual Studio\IDE\MSBuild\Microsoft\VisualStudio\NodeJs;H:\Visual Studio\IDE\Msbuild\Microsoft\VisualStudio\NodeJs;H:\WechatSdk\dll;H:\OpenSSL-Win64\include;C:\ProgramData\chocolatey\bin;C:\Program Files\NVIDIA Corporation\Nsight Compute 2023.3.0;C:\Program Files\cURL\bin;H:\Visual Studio\IDE\VC\Tools\MSVC\14.34.31933\bin\Hostx86\x86;H:\Visual Studio\Tool_And_SDK\Python39_64;C:\Program Files\NVIDIA Corporation\NVIDIA app\NvDLISR;H:\C++_Lib\Vcpkg\vcpkg;H:\flutter\bin;C:\Program Files (x86)\Windows Kits\10\Windows Performance Toolkit;L:\Qt\QtApp\5.15.2\msvc2015_64;L:\Qt\QtApp\5.15.2\msvc2015_64\bin;L:\Qt\QtApp\Tools\CMake_64\bin;H:\ToonuOne;L:\SSH\WezTerm;H:\cursor\resources\app\bin;C:\Program Files\xmake;H:\mingw64\bin;H:\Trae CN\bin;H:\Cmake\bin;C:\Users\dongj\scoop\shims;L:\Cocos\cocos2d-x\templates;L:\Cocos\cocos2d-x\tools\cocos2d-console\bin;cocos2d-x-4.0\templates;C:\Users\dongj\AppData\Local\Microsoft\WindowsApps;C:\Users\dongj\.dotnet\tools;C:\Users\dongj\AppData\Local\Programs\Microsoft VS Code\bin;flutter;flutter\bin;Visual Studio\IDE\MSBuild\Microsoft\VisualStudio\NodeJs;C:\Users\dongj\AppData\Roaming\npm;L:\CLion 2024.3.4\bin;OpenSSL-Win64\include;C:\tools\dart-sdk\bin;C:\Users\dongj\AppData\Local\Pub\Cache\bin;JDK8\JAVA;C++_Lib\Vcpkg\vcpkg;C:\Users\dongj\.bun\bin;C:\Users\dongj\AppData\Local\Programs\Ollama;C:\Users\dongj\AppData\Local\Microsoft\WindowsApps;L:\Switch\devkitPro\tools\bin;H:\Visual Studio\IDE\Common7\IDE\CommonExtensions\Microsoft\CMake\CMake\bin;H:\Visual Studio\IDE\Common7\IDE\CommonExtensions\Microsoft\CMake\Ninja;H:\Visual Studio\IDE\Common7\IDE\VC\Linux\bin\ConnectionManagerExe;H:\Visual Studio\IDE\VC\vcpkg]],
|
||||||
|
WindowsSdkBinPath = [[C:\Program Files (x86)\Windows Kits\10\bin\]],
|
||||||
|
VSInstallDir = [[H:\Visual Studio\IDE\]],
|
||||||
|
VCInstallDir = [[H:\Visual Studio\IDE\VC\]],
|
||||||
|
VSCMD_VER = "17.13.5",
|
||||||
|
UniversalCRTSdkDir = [[C:\Program Files (x86)\Windows Kits\10\]],
|
||||||
|
VSCMD_ARG_TGT_ARCH = "x64",
|
||||||
|
VisualStudioVersion = "17.0",
|
||||||
|
VSCMD_ARG_HOST_ARCH = "x64",
|
||||||
|
VCIDEInstallDir = [[H:\Visual Studio\IDE\Common7\IDE\VC\]],
|
||||||
|
ExtensionSdkDir = [[C:\Program Files (x86)\Microsoft SDKs\Windows Kits\10\ExtensionSDKs]],
|
||||||
|
LIB = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\ATLMFC\lib\x64;H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\lib\x64;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\lib\um\x64;C:\Program Files (x86)\Windows Kits\10\lib\10.0.22621.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\\lib\10.0.22621.0\\um\x64]],
|
||||||
|
DevEnvdir = [[H:\Visual Studio\IDE\Common7\IDE\]],
|
||||||
|
VCToolsInstallDir = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\]],
|
||||||
|
LIBPATH = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\ATLMFC\lib\x64;H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\lib\x64;H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\lib\x86\store\references;C:\Program Files (x86)\Windows Kits\10\UnionMetadata\10.0.22621.0;C:\Program Files (x86)\Windows Kits\10\References\10.0.22621.0;C:\Windows\Microsoft.NET\Framework64\v4.0.30319]],
|
||||||
|
INCLUDE = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\include;H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\ATLMFC\include;H:\Visual Studio\IDE\VC\Auxiliary\VS\include;C:\Program Files (x86)\Windows Kits\10\include\10.0.22621.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\winrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.22621.0\\cppwinrt;C:\Program Files (x86)\Windows Kits\NETFXSDK\4.8\include\um;H:\Visual Studio\IDE\VC\Tools\MSVC\14.34.31933\include]]
|
||||||
|
},
|
||||||
|
arch = "x64",
|
||||||
|
__global = true
|
||||||
|
},
|
||||||
|
yasm_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_labels_smoke_test_windows_x64_ld = {
|
||||||
|
toolname = "link",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\link.exe]]
|
||||||
|
},
|
||||||
|
rust_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_crypto_smoke_test_windows_x64_ld = {
|
||||||
|
toolname = "link",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\link.exe]]
|
||||||
|
},
|
||||||
|
tool_target_dps_manager_server_windows_x64_cxx = {
|
||||||
|
toolname = "cl",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\cl.exe]]
|
||||||
|
},
|
||||||
|
cuda_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
swift_arch_x64_plat_windows = {
|
||||||
|
__global = true,
|
||||||
|
__checked = true,
|
||||||
|
arch = "x64",
|
||||||
|
plat = "windows"
|
||||||
|
},
|
||||||
|
tool_target_dps_manager_server_windows_x64_ld = {
|
||||||
|
toolname = "link",
|
||||||
|
toolchain_info = {
|
||||||
|
name = "msvc",
|
||||||
|
plat = "windows",
|
||||||
|
arch = "x64",
|
||||||
|
cachekey = "msvc_arch_x64_plat_windows"
|
||||||
|
},
|
||||||
|
program = [[H:\Visual Studio\IDE\VC\Tools\MSVC\14.43.34808\bin\HostX64\x64\link.exe]]
|
||||||
|
}
|
||||||
|
}
|
||||||
0
.xmake/windows/x64/project.lock
Normal file
0
.xmake/windows/x64/project.lock
Normal file
38
.xmake/windows/x64/xmake.conf
Normal file
38
.xmake/windows/x64/xmake.conf
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
__toolchains_windows_x64 = {
|
||||||
|
"msvc",
|
||||||
|
"yasm",
|
||||||
|
"nasm",
|
||||||
|
"cuda",
|
||||||
|
"rust",
|
||||||
|
"swift",
|
||||||
|
"go",
|
||||||
|
"gfortran",
|
||||||
|
"fpc"
|
||||||
|
},
|
||||||
|
__toolchains_windows_x64_host = {
|
||||||
|
"msvc",
|
||||||
|
"yasm",
|
||||||
|
"nasm",
|
||||||
|
"cuda",
|
||||||
|
"rust",
|
||||||
|
"swift",
|
||||||
|
"go",
|
||||||
|
"gfortran",
|
||||||
|
"fpc"
|
||||||
|
},
|
||||||
|
arch = "x64",
|
||||||
|
builddir = "build",
|
||||||
|
ccache = true,
|
||||||
|
clean = true,
|
||||||
|
host = "windows",
|
||||||
|
kind = "static",
|
||||||
|
mode = "release",
|
||||||
|
ndk_stdcxx = true,
|
||||||
|
network = "public",
|
||||||
|
plat = "windows",
|
||||||
|
proxy = "http://127.0.0.1:7897",
|
||||||
|
proxy_pac = "pac.lua",
|
||||||
|
theme = "default",
|
||||||
|
vs = "2022"
|
||||||
|
}
|
||||||
75
README.md
Normal file
75
README.md
Normal file
@@ -0,0 +1,75 @@
|
|||||||
|
# DPS Manager Server
|
||||||
|
|
||||||
|
This directory contains the current C++17 service implementation. The legacy Java project is kept only as a behavior reference under `旧的java项目/`.
|
||||||
|
|
||||||
|
## Build targets
|
||||||
|
|
||||||
|
The server now uses one codebase with the same runtime behavior on:
|
||||||
|
|
||||||
|
- Windows: `MSVC + xmake`
|
||||||
|
- Linux: `gcc/clang + xmake`
|
||||||
|
|
||||||
|
`mingw` is no longer the primary target for this service.
|
||||||
|
|
||||||
|
## Dependencies
|
||||||
|
|
||||||
|
Xmake resolves these shared dependencies for both platforms:
|
||||||
|
|
||||||
|
- `openssl3`
|
||||||
|
- `zlib`
|
||||||
|
- `mariadb-connector-c`
|
||||||
|
|
||||||
|
Platform system links:
|
||||||
|
|
||||||
|
- Windows: `ws2_32`
|
||||||
|
- Linux: `pthread`
|
||||||
|
|
||||||
|
## Database TLS
|
||||||
|
|
||||||
|
- `database.ssl_mode=disable`: disable TLS for local Windows testing
|
||||||
|
- `database.ssl_mode=preferred`: allow TLS without strict certificate validation
|
||||||
|
- `database.ssl_mode=required`: require TLS but skip certificate validation
|
||||||
|
- `database.ssl_mode=verify_ca`: require TLS and verify the server certificate chain
|
||||||
|
- `database.ssl_mode=verify_identity`: same strict verification path as `verify_ca` in the current Connector/C integration
|
||||||
|
- `database.ssl_ca`: optional CA certificate file path for strict verification modes
|
||||||
|
- `database.plugin_dir`: optional MariaDB auth plugin directory override; Windows builds also copy connector plugins to `mariadb-plugin` beside the executable
|
||||||
|
|
||||||
|
## Build
|
||||||
|
|
||||||
|
### Windows local testing
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
xmake f -p windows -a x64 -m debug
|
||||||
|
xmake
|
||||||
|
Copy-Item config/server.windows.conf config/server.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
### Linux deployment build
|
||||||
|
|
||||||
|
```bash
|
||||||
|
xmake f -p linux -a x86_64 -m release
|
||||||
|
xmake
|
||||||
|
cp config/server.conf.example config/server.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Run
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```powershell
|
||||||
|
./build/windows/x64/debug/dps_manager_server.exe --config config/server.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
./build/linux/x86_64/release/dps_manager_server --config config/server.conf
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- Password hashing, JWT signing, RSA operations, and gzip payload generation all use the same OpenSSL/zlib-based implementation on Windows and Linux.
|
||||||
|
- The server fails fast on startup if the database connection cannot be established.
|
||||||
|
- Windows local testing can set `database.ssl_mode=disable` when the remote database presents a certificate chain that Windows does not trust yet.
|
||||||
|
- Proxy headers are ignored by default; enable `server.trust_proxy=true` only when the service runs behind a trusted reverse proxy.
|
||||||
|
- `config/server.conf.example` is the Linux-oriented template, and `config/server.windows.conf` is the Windows local test template.
|
||||||
BIN
build-debug-rebuild.log
Normal file
BIN
build-debug-rebuild.log
Normal file
Binary file not shown.
BIN
build-debug.log
Normal file
BIN
build-debug.log
Normal file
Binary file not shown.
34
config/server.conf
Normal file
34
config/server.conf
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
# Windows local test configuration
|
||||||
|
# Fill in the database settings and adjust all paths to match your machine.
|
||||||
|
server.host=0.0.0.0
|
||||||
|
server.port=65170
|
||||||
|
|
||||||
|
jwt.secret=rjyusrghdfghj2345ryu123asdfvbyukuirtwjhfsd
|
||||||
|
jwt.expiration_seconds=7200
|
||||||
|
|
||||||
|
logging.level=debug
|
||||||
|
logging.http_summary=true
|
||||||
|
logging.http_dump=true
|
||||||
|
logging.http_max_body=2048
|
||||||
|
|
||||||
|
# Keep these disabled for the first Windows test pass.
|
||||||
|
features.video_enabled=false
|
||||||
|
features.payment_enabled=false
|
||||||
|
|
||||||
|
# MySQL test database
|
||||||
|
database.host=192.168.200.179
|
||||||
|
database.port=3306
|
||||||
|
database.name=rindro
|
||||||
|
database.user=root
|
||||||
|
database.password=Djq5231520!
|
||||||
|
database.ssl_mode=disable
|
||||||
|
database.ssl_ca=
|
||||||
|
database.plugin_dir=
|
||||||
|
|
||||||
|
# Main legacy-compatible Windows test paths
|
||||||
|
paths.configfile=H:\\DpsTest\\rindro\\Script\\FileConfig.json
|
||||||
|
paths.file_root=H:\\DpsTest\\rindro\\
|
||||||
|
paths.file_map=H:\\DpsTest\\rindro\\file.json
|
||||||
|
paths.script_root=H:\\DpsTest\\rindro\\ClentScript\\
|
||||||
|
paths.dps_root=H:\\DpsTest\\DP_S\\
|
||||||
|
paths.client_user_script_root=H:\\DpsTest\\rindro\\ClentUserScript\\
|
||||||
33
config/server.conf.example
Normal file
33
config/server.conf.example
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Linux deployment example
|
||||||
|
# Copy this file to config/server.conf and adjust the database credentials and paths.
|
||||||
|
server.host=0.0.0.0
|
||||||
|
server.port=8651
|
||||||
|
server.trust_proxy=false
|
||||||
|
server.proxy_header=x-forwarded-for
|
||||||
|
|
||||||
|
jwt.secret=change-me
|
||||||
|
jwt.expiration_seconds=7200
|
||||||
|
|
||||||
|
logging.level=info
|
||||||
|
logging.http_summary=true
|
||||||
|
logging.http_dump=false
|
||||||
|
logging.http_max_body=2048
|
||||||
|
|
||||||
|
features.video_enabled=false
|
||||||
|
features.payment_enabled=false
|
||||||
|
|
||||||
|
database.host=127.0.0.1
|
||||||
|
database.port=3306
|
||||||
|
database.name=rindro
|
||||||
|
database.user=root
|
||||||
|
database.password=change-me
|
||||||
|
database.ssl_mode=preferred
|
||||||
|
database.ssl_ca=
|
||||||
|
database.plugin_dir=
|
||||||
|
|
||||||
|
paths.configfile=/root/rindro/Script/FileConfig.json
|
||||||
|
paths.file_root=/root/rindro/
|
||||||
|
paths.file_map=/root/rindro/file.json
|
||||||
|
paths.script_root=/root/rindro/ClentScript/
|
||||||
|
paths.dps_root=/home/DP_S/
|
||||||
|
paths.client_user_script_root=/root/rindro/ClentUserScript/
|
||||||
33
config/server.windows.conf
Normal file
33
config/server.windows.conf
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
# Windows local test example for MSVC builds
|
||||||
|
# Copy this file to config/server.conf and adjust the database credentials and paths.
|
||||||
|
server.host=0.0.0.0
|
||||||
|
server.port=8651
|
||||||
|
server.trust_proxy=false
|
||||||
|
server.proxy_header=x-forwarded-for
|
||||||
|
|
||||||
|
jwt.secret=change-me
|
||||||
|
jwt.expiration_seconds=7200
|
||||||
|
|
||||||
|
logging.level=debug
|
||||||
|
logging.http_summary=true
|
||||||
|
logging.http_dump=true
|
||||||
|
logging.http_max_body=2048
|
||||||
|
|
||||||
|
features.video_enabled=false
|
||||||
|
features.payment_enabled=false
|
||||||
|
|
||||||
|
database.host=127.0.0.1
|
||||||
|
database.port=3306
|
||||||
|
database.name=rindro
|
||||||
|
database.user=root
|
||||||
|
database.password=change-me
|
||||||
|
database.ssl_mode=disable
|
||||||
|
database.ssl_ca=
|
||||||
|
database.plugin_dir=
|
||||||
|
|
||||||
|
paths.configfile=D:\\DpsTest\\rindro\\Script\\FileConfig.json
|
||||||
|
paths.file_root=D:\\DpsTest\\rindro\\
|
||||||
|
paths.file_map=D:\\DpsTest\\rindro\\file.json
|
||||||
|
paths.script_root=D:\\DpsTest\\rindro\\ClentScript\\
|
||||||
|
paths.dps_root=D:\\DpsTest\\DP_S\\
|
||||||
|
paths.client_user_script_root=D:\\DpsTest\\rindro\\ClentUserScript\\
|
||||||
1
folder-alias.json
Normal file
1
folder-alias.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
1
http-log-body-test.err
Normal file
1
http-log-body-test.err
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Listening on 0.0.0.0:65170
|
||||||
0
http-log-body-test.out
Normal file
0
http-log-body-test.out
Normal file
3
http-log-test.err
Normal file
3
http-log-test.err
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
Listening on 0.0.0.0:65170
|
||||||
|
[2026-04-14 03:31:55] REQ ip=127.0.0.1 method=GET path=/rindro/getversion query=- body_bytes=0 content_type=- auth=absent
|
||||||
|
[2026-04-14 03:31:55] RESP ip=127.0.0.1 method=GET path=/rindro/getversion status=200 content_type=text/plain; charset=utf-8 body_bytes=146 binary=no cost_ms=0
|
||||||
0
http-log-test.out
Normal file
0
http-log-test.out
Normal file
227
include/dps/app.hpp
Normal file
227
include/dps/app.hpp
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dps/config.hpp"
|
||||||
|
#include "dps/http.hpp"
|
||||||
|
#include "dps/json.hpp"
|
||||||
|
|
||||||
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
#include <optional>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
struct User {
|
||||||
|
int id = 0;
|
||||||
|
std::string username;
|
||||||
|
std::string password;
|
||||||
|
int gold = 0;
|
||||||
|
int level = 1;
|
||||||
|
std::string qq;
|
||||||
|
std::string name;
|
||||||
|
std::string img;
|
||||||
|
std::string client_key;
|
||||||
|
std::string server_key;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UserAndServer {
|
||||||
|
std::string user_name;
|
||||||
|
std::string server_ip;
|
||||||
|
std::string account;
|
||||||
|
std::string password;
|
||||||
|
std::string port;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct UserServerProject {
|
||||||
|
std::string server_ip;
|
||||||
|
std::string project_name;
|
||||||
|
std::string user_name;
|
||||||
|
std::string expiration_date;
|
||||||
|
int open = 1;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ProjectDefinition {
|
||||||
|
std::string name;
|
||||||
|
std::vector<std::string> script_paths;
|
||||||
|
std::map<std::string, Json> info;
|
||||||
|
int price = 0;
|
||||||
|
bool is_private = false;
|
||||||
|
std::string img_path;
|
||||||
|
};
|
||||||
|
|
||||||
|
class LegacyCrypto {
|
||||||
|
public:
|
||||||
|
explicit LegacyCrypto(std::string jwt_secret);
|
||||||
|
|
||||||
|
std::string issue_jwt(const std::string &username, long long expiration_seconds) const;
|
||||||
|
std::optional<std::string> validate_jwt(const std::string &token) const;
|
||||||
|
|
||||||
|
std::string hash_password(const std::string &password) const;
|
||||||
|
bool verify_password(const std::string &password, const std::string &encoded) const;
|
||||||
|
|
||||||
|
std::string rsa_private_encrypt_tool(const std::string &plain) const;
|
||||||
|
std::string rsa_private_encrypt_script(const std::string &plain) const;
|
||||||
|
std::string gzip_base64(const std::string &plain) const;
|
||||||
|
std::vector<unsigned char> makecode(std::vector<unsigned char> bytes, const std::vector<int> &key) const;
|
||||||
|
std::string xor_encrypt(const std::string &plain, const std::string &key) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string base64_url_encode(const std::string &input) const;
|
||||||
|
std::string base64_url_decode(const std::string &input) const;
|
||||||
|
std::string hmac_sha256(const std::string &message) const;
|
||||||
|
std::string sha256_hex(const std::string &message) const;
|
||||||
|
std::string bcrypt_hash(const std::string &password) const;
|
||||||
|
std::string rsa_private_encrypt_der_b64(const std::string &der_b64, const std::string &plain) const;
|
||||||
|
|
||||||
|
std::string jwt_secret_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Database {
|
||||||
|
public:
|
||||||
|
explicit Database(const DatabaseConfig &config);
|
||||||
|
~Database();
|
||||||
|
|
||||||
|
bool connect();
|
||||||
|
bool is_connected() const;
|
||||||
|
std::string last_error() const;
|
||||||
|
std::string escape(const std::string &value) const;
|
||||||
|
bool execute(const std::string &sql);
|
||||||
|
std::vector<std::map<std::string, std::string>> query(const std::string &sql);
|
||||||
|
long long last_insert_id() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Impl;
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ProjectCatalog {
|
||||||
|
public:
|
||||||
|
explicit ProjectCatalog(const PathConfig &paths);
|
||||||
|
|
||||||
|
void reload();
|
||||||
|
std::optional<ProjectDefinition> get_project(const std::string &name, const std::string &version = "") const;
|
||||||
|
Json public_project_info() const;
|
||||||
|
Json all_project_info() const;
|
||||||
|
int project_price(const std::string &name) const;
|
||||||
|
std::string project_img_path(const std::string &name) const;
|
||||||
|
std::vector<std::string> base_script_contents(const std::string &version, bool cs_mode) const;
|
||||||
|
std::vector<std::string> project_script_contents(const std::string &project_name, const std::string &version) const;
|
||||||
|
std::vector<std::string> custom_client_scripts(const std::string &ip, const std::string &version) const;
|
||||||
|
std::vector<std::pair<std::string, std::string>> dps_service_scripts(const std::string &ip) const;
|
||||||
|
std::vector<std::pair<std::string, std::string>> dps_service_scripts_new(const std::string &ip, const std::string &version) const;
|
||||||
|
std::string newest_version() const;
|
||||||
|
long long base_update_time(const std::string &version) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct VersionData {
|
||||||
|
std::string name;
|
||||||
|
std::map<std::string, ProjectDefinition> projects;
|
||||||
|
std::vector<std::string> base_scripts;
|
||||||
|
std::vector<std::string> cs_base_scripts;
|
||||||
|
std::map<std::string, std::vector<std::string>> project_scripts;
|
||||||
|
std::map<std::string, std::vector<std::string>> custom_client_scripts;
|
||||||
|
Json dps_manifest;
|
||||||
|
};
|
||||||
|
|
||||||
|
const VersionData *find_version(const std::string &requested) const;
|
||||||
|
std::vector<std::string> read_script_list(const std::string &root, const std::vector<std::string> &items) const;
|
||||||
|
std::vector<std::pair<std::string, std::string>> read_named_scripts(const std::string &root, const std::vector<std::string> &items) const;
|
||||||
|
void load_client_versions();
|
||||||
|
void load_custom_client_scripts(VersionData &data);
|
||||||
|
Json parse_json_file(const std::string &path) const;
|
||||||
|
|
||||||
|
PathConfig paths_;
|
||||||
|
std::map<std::string, VersionData> versions_;
|
||||||
|
std::string newest_version_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Application {
|
||||||
|
public:
|
||||||
|
explicit Application(AppConfig config);
|
||||||
|
int run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
using Row = std::map<std::string, std::string>;
|
||||||
|
|
||||||
|
void register_routes();
|
||||||
|
Response handle_login(const Request &request);
|
||||||
|
Response handle_register(const Request &request);
|
||||||
|
Response handle_change_password(const Request &request);
|
||||||
|
Response handle_get_info(const Request &request);
|
||||||
|
Response handle_add_server(const Request &request);
|
||||||
|
Response handle_delete_server(const Request &request);
|
||||||
|
Response handle_get_server_list(const Request &request);
|
||||||
|
Response handle_get_server(const Request &request);
|
||||||
|
Response handle_get_project_info_list(const Request &request);
|
||||||
|
Response handle_get_user_project_list(const Request &request);
|
||||||
|
Response handle_get_server_project_list(const Request &request);
|
||||||
|
Response handle_buy(const Request &request);
|
||||||
|
Response handle_add_gold(const Request &request);
|
||||||
|
Response handle_transfer(const Request &request);
|
||||||
|
Response handle_set_key(const Request &request);
|
||||||
|
Response handle_set_project_open(const Request &request);
|
||||||
|
|
||||||
|
Response handle_rindro_download(const Request &request);
|
||||||
|
Response handle_static_download(const std::string &disk_path, const std::string &download_name) const;
|
||||||
|
Response handle_get_image(const Request &request, bool thumbnail);
|
||||||
|
Response handle_get_mp42(const Request &request);
|
||||||
|
Response handle_get_version(const Request &request);
|
||||||
|
|
||||||
|
Response handle_dps_version(const std::string &relative_file) const;
|
||||||
|
Response handle_dps_list(const std::string &relative_dir, const std::string &metadata_file) const;
|
||||||
|
Response handle_dps_download(const Request &request, const std::string &base_dir) const;
|
||||||
|
|
||||||
|
Response handle_script_client(const Request &request);
|
||||||
|
Response handle_script_client2(const Request &request);
|
||||||
|
Response handle_script_getzdy(const Request &request);
|
||||||
|
Response handle_script_getpro(const Request &request);
|
||||||
|
Response handle_script_getservice(const Request &request);
|
||||||
|
Response handle_script_base_update_time(const Request &request);
|
||||||
|
Response handle_script_base_sut(const Request &request);
|
||||||
|
Response handle_script_getservice_new(const Request &request);
|
||||||
|
|
||||||
|
Response handle_video_placeholder(const Request &request);
|
||||||
|
Response handle_payment_placeholder(const Request &request);
|
||||||
|
|
||||||
|
std::optional<User> find_user_by_username(const std::string &username);
|
||||||
|
bool username_exists(const std::string &username);
|
||||||
|
bool create_user(const std::string &username, const std::string &password, const std::string &qq);
|
||||||
|
bool update_password(const std::string &username, const std::string &qq, const std::string &password);
|
||||||
|
bool update_user_row(const User &user);
|
||||||
|
std::vector<UserAndServer> servers_for_user(const std::string &username);
|
||||||
|
std::optional<UserAndServer> find_server(const std::string &username, const std::string &ip);
|
||||||
|
bool upsert_server(const UserAndServer &server);
|
||||||
|
bool delete_server(const std::string &username, const std::string &ip);
|
||||||
|
std::vector<UserServerProject> projects_for_ip(const std::string &ip, bool require_open = false);
|
||||||
|
std::vector<UserServerProject> projects_for_user(const std::string &username);
|
||||||
|
std::optional<UserServerProject> find_project_binding(const std::string &ip, const std::string &project_name);
|
||||||
|
bool add_or_extend_project(const std::string &ip, const std::string &project_name, int days, const std::string &username);
|
||||||
|
bool update_project_open(const std::string &ip, const std::string &project_name, int open_value);
|
||||||
|
bool insert_log(const std::string &username, int type, const std::string &content);
|
||||||
|
|
||||||
|
Response json_response(int status, const Json &body) const;
|
||||||
|
Response common_success(const Json &data, const std::string &message = "操作成功", int status = 200) const;
|
||||||
|
Response common_failed(int code, const std::string &message, int http_status = 200) const;
|
||||||
|
Response file_response(const std::filesystem::path &path, const std::string &download_name = "") const;
|
||||||
|
std::string request_ip(const Request &request) const;
|
||||||
|
std::vector<int> random_key() const;
|
||||||
|
std::string format_date_now() const;
|
||||||
|
std::string add_days(const std::string &iso_date, int days) const;
|
||||||
|
std::string make_random_name() const;
|
||||||
|
Json parse_body_or_empty(const Request &request) const;
|
||||||
|
std::optional<std::string> current_user(const Request &request) const;
|
||||||
|
|
||||||
|
AppConfig config_;
|
||||||
|
Router router_;
|
||||||
|
LegacyCrypto crypto_;
|
||||||
|
Database database_;
|
||||||
|
ProjectCatalog catalog_;
|
||||||
|
mutable std::mutex transfer_mutex_;
|
||||||
|
mutable std::mutex script_mutex_;
|
||||||
|
std::map<std::string, std::string> ip_and_mac_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
62
include/dps/config.hpp
Normal file
62
include/dps/config.hpp
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
struct ServerConfig {
|
||||||
|
std::string host = "0.0.0.0";
|
||||||
|
int port = 8651;
|
||||||
|
bool trust_proxy = false;
|
||||||
|
std::string proxy_header = "x-forwarded-for";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JwtConfig {
|
||||||
|
std::string secret = "change-me";
|
||||||
|
long long expiration_seconds = 7200;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct LoggingConfig {
|
||||||
|
std::string level = "info";
|
||||||
|
bool http_summary = true;
|
||||||
|
bool http_dump = false;
|
||||||
|
int http_max_body = 2048;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct FeatureConfig {
|
||||||
|
bool video_enabled = false;
|
||||||
|
bool payment_enabled = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct DatabaseConfig {
|
||||||
|
std::string host = "127.0.0.1";
|
||||||
|
int port = 3306;
|
||||||
|
std::string name = "rindro";
|
||||||
|
std::string user = "root";
|
||||||
|
std::string password;
|
||||||
|
std::string ssl_mode = "preferred";
|
||||||
|
std::string ssl_ca;
|
||||||
|
std::string plugin_dir;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PathConfig {
|
||||||
|
std::string configfile = "/root/rindro/Script/FileConfig.json";
|
||||||
|
std::string file_root = "/root/rindro/";
|
||||||
|
std::string file_map = "/root/rindro/file.json";
|
||||||
|
std::string script_root = "/root/rindro/ClentScript/";
|
||||||
|
std::string dps_root = "/home/DP_S/";
|
||||||
|
std::string client_user_script_root = "/root/rindro/ClentUserScript/";
|
||||||
|
};
|
||||||
|
|
||||||
|
struct AppConfig {
|
||||||
|
ServerConfig server;
|
||||||
|
JwtConfig jwt;
|
||||||
|
LoggingConfig logging;
|
||||||
|
FeatureConfig features;
|
||||||
|
DatabaseConfig database;
|
||||||
|
PathConfig paths;
|
||||||
|
};
|
||||||
|
|
||||||
|
AppConfig load_config(const std::string &path);
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
14
include/dps/fs_utils.hpp
Normal file
14
include/dps/fs_utils.hpp
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <filesystem>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
std::filesystem::path path_from_utf8(const std::string &value);
|
||||||
|
std::string path_to_utf8_string(const std::filesystem::path &path);
|
||||||
|
std::string read_text_file(const std::filesystem::path &path);
|
||||||
|
std::vector<unsigned char> read_binary_file(const std::filesystem::path &path);
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
73
include/dps/http.hpp
Normal file
73
include/dps/http.hpp
Normal file
@@ -0,0 +1,73 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "dps/config.hpp"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
#include <map>
|
||||||
|
#include <optional>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
struct Request {
|
||||||
|
std::string method;
|
||||||
|
std::string raw_target;
|
||||||
|
std::string path;
|
||||||
|
std::string body;
|
||||||
|
std::string remote_addr;
|
||||||
|
std::map<std::string, std::string> headers;
|
||||||
|
std::map<std::string, std::string> query;
|
||||||
|
std::map<std::string, std::string> path_params;
|
||||||
|
std::optional<std::string> current_user;
|
||||||
|
|
||||||
|
std::string header(const std::string &name) const;
|
||||||
|
std::string query_value(const std::string &name) const;
|
||||||
|
std::string path_param(const std::string &name) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Response {
|
||||||
|
int status = 200;
|
||||||
|
std::string content_type = "application/json; charset=utf-8";
|
||||||
|
std::string body;
|
||||||
|
std::vector<unsigned char> binary_body;
|
||||||
|
std::map<std::string, std::string> headers;
|
||||||
|
|
||||||
|
bool has_binary() const;
|
||||||
|
};
|
||||||
|
|
||||||
|
using Handler = std::function<Response(const Request &)>;
|
||||||
|
|
||||||
|
class Router {
|
||||||
|
public:
|
||||||
|
void add(const std::string &method, const std::string &pattern, bool requires_auth, Handler handler);
|
||||||
|
Response dispatch(Request request) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
struct Route {
|
||||||
|
std::string method;
|
||||||
|
std::string pattern;
|
||||||
|
bool requires_auth = false;
|
||||||
|
Handler handler;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<Route> routes_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class HttpServer {
|
||||||
|
public:
|
||||||
|
HttpServer(std::string host, int port, LoggingConfig logging, const Router &router);
|
||||||
|
int run() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::string host_;
|
||||||
|
int port_;
|
||||||
|
LoggingConfig logging_;
|
||||||
|
const Router &router_;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string url_decode(const std::string &value);
|
||||||
|
std::map<std::string, std::string> parse_query_string(const std::string &query);
|
||||||
|
std::string guess_content_type(const std::string &path);
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
72
include/dps/json.hpp
Normal file
72
include/dps/json.hpp
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <map>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <string>
|
||||||
|
#include <variant>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
class Json {
|
||||||
|
public:
|
||||||
|
using array_t = std::vector<Json>;
|
||||||
|
using object_t = std::map<std::string, Json>;
|
||||||
|
using value_t = std::variant<std::nullptr_t, bool, double, std::string, array_t, object_t>;
|
||||||
|
|
||||||
|
Json();
|
||||||
|
Json(std::nullptr_t);
|
||||||
|
Json(bool value);
|
||||||
|
Json(int value);
|
||||||
|
Json(long long value);
|
||||||
|
Json(double value);
|
||||||
|
Json(const char *value);
|
||||||
|
Json(const std::string &value);
|
||||||
|
Json(std::string &&value);
|
||||||
|
Json(const array_t &value);
|
||||||
|
Json(array_t &&value);
|
||||||
|
Json(const object_t &value);
|
||||||
|
Json(object_t &&value);
|
||||||
|
|
||||||
|
static Json parse(const std::string &text);
|
||||||
|
static Json object();
|
||||||
|
static Json array();
|
||||||
|
|
||||||
|
bool is_null() const;
|
||||||
|
bool is_bool() const;
|
||||||
|
bool is_number() const;
|
||||||
|
bool is_string() const;
|
||||||
|
bool is_array() const;
|
||||||
|
bool is_object() const;
|
||||||
|
|
||||||
|
bool as_bool() const;
|
||||||
|
double as_number() const;
|
||||||
|
int as_int() const;
|
||||||
|
long long as_int64() const;
|
||||||
|
const std::string &as_string() const;
|
||||||
|
const array_t &as_array() const;
|
||||||
|
const object_t &as_object() const;
|
||||||
|
array_t &as_array();
|
||||||
|
object_t &as_object();
|
||||||
|
|
||||||
|
bool contains(const std::string &key) const;
|
||||||
|
const Json &at(const std::string &key) const;
|
||||||
|
Json &operator[](const std::string &key);
|
||||||
|
const Json &operator[](const std::string &key) const;
|
||||||
|
|
||||||
|
const Json &at(std::size_t index) const;
|
||||||
|
Json &at(std::size_t index);
|
||||||
|
void push_back(const Json &value);
|
||||||
|
std::size_t size() const;
|
||||||
|
|
||||||
|
std::string dump() const;
|
||||||
|
std::string to_string_or(const std::string &fallback) const;
|
||||||
|
int to_int_or(int fallback) const;
|
||||||
|
bool to_bool_or(bool fallback) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
value_t value_;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
9
include/dps/labels.hpp
Normal file
9
include/dps/labels.hpp
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
std::string membership_label(int level);
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
15
packaging/systemd/dps-manager-server.service
Normal file
15
packaging/systemd/dps-manager-server.service
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=DPS Manager Server
|
||||||
|
After=network.target mysql.service
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
WorkingDirectory=/opt/dps-manager-server
|
||||||
|
ExecStart=/opt/dps-manager-server/bin/dps_manager_server --config /opt/dps-manager-server/config/server.conf
|
||||||
|
Restart=always
|
||||||
|
RestartSec=3
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
1
private-folder-alias.json
Normal file
1
private-folder-alias.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
4
server-run.err
Normal file
4
server-run.err
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
Listening on 0.0.0.0:65170
|
||||||
|
[2026-04-14 03:58:00] REQ ip=127.0.0.1 method=POST path=/login query=- body_bytes=17 content_type=application/json;charset=UTF-8 auth=absent
|
||||||
|
[2026-04-14 03:58:00] REQ_BODY username:lenheart
|
||||||
|
[2026-04-14 03:58:00] RESP ip=127.0.0.1 method=POST path=/login status=401 content_type=application/json; charset=utf-8 body_bytes=61 binary=no cost_ms=0
|
||||||
0
server-run.out
Normal file
0
server-run.out
Normal file
1
server-start-check.err
Normal file
1
server-start-check.err
Normal file
@@ -0,0 +1 @@
|
|||||||
|
Listening on 0.0.0.0:65170
|
||||||
0
server-start-check.out
Normal file
0
server-start-check.out
Normal file
6
server-unicode-check.err
Normal file
6
server-unicode-check.err
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
Listening on 0.0.0.0:65170
|
||||||
|
[2026-04-14 16:14:00] REQ ip=127.0.0.1 method=GET path=/dps/download3/3_%E5%A4%9F%E9%92%9F:img.png query=- body_bytes=0 content_type=- auth=absent
|
||||||
|
[2026-04-14 16:14:00] RESP ip=127.0.0.1 method=GET path=/dps/download3/3_%E5%A4%9F%E9%92%9F:img.png status=200 content_type=image/png body_bytes=173653 binary=yes cost_ms=1
|
||||||
|
[2026-04-14 16:14:01] REQ ip=127.0.0.1 method=GET path=/dps/download3/..:..:windows/win.ini query=- body_bytes=0 content_type=- auth=absent
|
||||||
|
[2026-04-14 16:14:01] RESP ip=127.0.0.1 method=GET path=/dps/download3/..:..:windows/win.ini status=404 content_type=application/json; charset=utf-8 body_bytes=46 binary=no cost_ms=0
|
||||||
|
[2026-04-14 16:14:01] RESP_BODY {"code":404,"message":"not found","data":null}
|
||||||
0
server-unicode-check.out
Normal file
0
server-unicode-check.out
Normal file
1586
src/app.cpp
Normal file
1586
src/app.cpp
Normal file
File diff suppressed because it is too large
Load Diff
117
src/config.cpp
Normal file
117
src/config.cpp
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
#include "dps/config.hpp"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <fstream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string trim(const std::string &value) {
|
||||||
|
std::size_t left = 0;
|
||||||
|
while (left < value.size() && std::isspace(static_cast<unsigned char>(value[left]))) {
|
||||||
|
++left;
|
||||||
|
}
|
||||||
|
std::size_t right = value.size();
|
||||||
|
while (right > left && std::isspace(static_cast<unsigned char>(value[right - 1]))) {
|
||||||
|
--right;
|
||||||
|
}
|
||||||
|
return value.substr(left, right - left);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_bool(const std::string &value) {
|
||||||
|
return value == "1" || value == "true" || value == "TRUE" || value == "yes" || value == "on";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string to_lower(std::string value) {
|
||||||
|
for (char &ch : value) {
|
||||||
|
ch = static_cast<char>(std::tolower(static_cast<unsigned char>(ch)));
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string env_or(const char *name, const std::string &fallback) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
char *raw = nullptr;
|
||||||
|
std::size_t size = 0;
|
||||||
|
if (_dupenv_s(&raw, &size, name) != 0 || raw == nullptr) {
|
||||||
|
return fallback;
|
||||||
|
}
|
||||||
|
std::string value(raw);
|
||||||
|
std::free(raw);
|
||||||
|
return value;
|
||||||
|
#else
|
||||||
|
const char *raw = std::getenv(name);
|
||||||
|
return raw == nullptr ? fallback : std::string(raw);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
AppConfig load_config(const std::string &path) {
|
||||||
|
AppConfig config;
|
||||||
|
|
||||||
|
std::ifstream input(path);
|
||||||
|
if (!input.good()) {
|
||||||
|
throw std::runtime_error("failed to open config file: " + path);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string line;
|
||||||
|
while (std::getline(input, line)) {
|
||||||
|
line = trim(line);
|
||||||
|
if (line.empty() || line[0] == '#') {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const std::size_t pos = line.find('=');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
const std::string key = trim(line.substr(0, pos));
|
||||||
|
const std::string value = trim(line.substr(pos + 1));
|
||||||
|
|
||||||
|
if (key == "server.host") config.server.host = value;
|
||||||
|
else if (key == "server.port") config.server.port = std::stoi(value);
|
||||||
|
else if (key == "server.trust_proxy") config.server.trust_proxy = parse_bool(value);
|
||||||
|
else if (key == "server.proxy_header") config.server.proxy_header = value;
|
||||||
|
else if (key == "jwt.secret") config.jwt.secret = value;
|
||||||
|
else if (key == "jwt.expiration_seconds") config.jwt.expiration_seconds = std::stoll(value);
|
||||||
|
else if (key == "logging.level") config.logging.level = value;
|
||||||
|
else if (key == "logging.http_summary") config.logging.http_summary = parse_bool(value);
|
||||||
|
else if (key == "logging.http_dump") config.logging.http_dump = parse_bool(value);
|
||||||
|
else if (key == "logging.http_max_body") config.logging.http_max_body = std::stoi(value);
|
||||||
|
else if (key == "features.video_enabled") config.features.video_enabled = parse_bool(value);
|
||||||
|
else if (key == "features.payment_enabled") config.features.payment_enabled = parse_bool(value);
|
||||||
|
else if (key == "database.host") config.database.host = value;
|
||||||
|
else if (key == "database.port") config.database.port = std::stoi(value);
|
||||||
|
else if (key == "database.name") config.database.name = value;
|
||||||
|
else if (key == "database.user") config.database.user = value;
|
||||||
|
else if (key == "database.password") config.database.password = value;
|
||||||
|
else if (key == "database.ssl_mode") config.database.ssl_mode = to_lower(value);
|
||||||
|
else if (key == "database.ssl_ca") config.database.ssl_ca = value;
|
||||||
|
else if (key == "database.plugin_dir") config.database.plugin_dir = value;
|
||||||
|
else if (key == "paths.configfile") config.paths.configfile = value;
|
||||||
|
else if (key == "paths.file_root") config.paths.file_root = value;
|
||||||
|
else if (key == "paths.file_map") config.paths.file_map = value;
|
||||||
|
else if (key == "paths.script_root") config.paths.script_root = value;
|
||||||
|
else if (key == "paths.dps_root") config.paths.dps_root = value;
|
||||||
|
else if (key == "paths.client_user_script_root") config.paths.client_user_script_root = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
config.server.host = env_or("DPS_SERVER_HOST", config.server.host);
|
||||||
|
config.server.proxy_header = env_or("DPS_SERVER_PROXY_HEADER", config.server.proxy_header);
|
||||||
|
config.jwt.secret = env_or("DPS_JWT_SECRET", config.jwt.secret);
|
||||||
|
config.database.host = env_or("DPS_DB_HOST", config.database.host);
|
||||||
|
config.database.user = env_or("DPS_DB_USER", config.database.user);
|
||||||
|
config.database.password = env_or("DPS_DB_PASSWORD", config.database.password);
|
||||||
|
config.database.name = env_or("DPS_DB_NAME", config.database.name);
|
||||||
|
config.database.ssl_mode = to_lower(env_or("DPS_DB_SSL_MODE", config.database.ssl_mode));
|
||||||
|
config.database.ssl_ca = env_or("DPS_DB_SSL_CA", config.database.ssl_ca);
|
||||||
|
config.database.plugin_dir = env_or("DPS_DB_PLUGIN_DIR", config.database.plugin_dir);
|
||||||
|
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
33
src/fs_utils.cpp
Normal file
33
src/fs_utils.cpp
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
#include "dps/fs_utils.hpp"
|
||||||
|
|
||||||
|
#include <fstream>
|
||||||
|
#include <iterator>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
fs::path path_from_utf8(const std::string &value) {
|
||||||
|
return fs::u8path(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string path_to_utf8_string(const fs::path &path) {
|
||||||
|
return path.u8string();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string read_text_file(const fs::path &path) {
|
||||||
|
std::ifstream input(path, std::ios::binary);
|
||||||
|
if (!input.good()) return "";
|
||||||
|
std::ostringstream buffer;
|
||||||
|
buffer << input.rdbuf();
|
||||||
|
return buffer.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> read_binary_file(const fs::path &path) {
|
||||||
|
std::ifstream input(path, std::ios::binary);
|
||||||
|
if (!input.good()) return {};
|
||||||
|
return std::vector<unsigned char>((std::istreambuf_iterator<char>(input)), std::istreambuf_iterator<char>());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
534
src/http.cpp
Normal file
534
src/http.cpp
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
#include "dps/http.hpp"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <array>
|
||||||
|
#include <cerrno>
|
||||||
|
#include <chrono>
|
||||||
|
#include <cctype>
|
||||||
|
#include <cstring>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <stdexcept>
|
||||||
|
#include <thread>
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include <winsock2.h>
|
||||||
|
#include <ws2tcpip.h>
|
||||||
|
using socket_t = SOCKET;
|
||||||
|
static constexpr socket_t kInvalidSocket = INVALID_SOCKET;
|
||||||
|
#else
|
||||||
|
#include <arpa/inet.h>
|
||||||
|
#include <netdb.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
using socket_t = int;
|
||||||
|
static constexpr socket_t kInvalidSocket = -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string to_lower(std::string value) {
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(), [](unsigned char ch) {
|
||||||
|
return static_cast<char>(std::tolower(ch));
|
||||||
|
});
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string trim(const std::string &value) {
|
||||||
|
std::size_t left = 0;
|
||||||
|
while (left < value.size() && std::isspace(static_cast<unsigned char>(value[left]))) {
|
||||||
|
++left;
|
||||||
|
}
|
||||||
|
std::size_t right = value.size();
|
||||||
|
while (right > left && std::isspace(static_cast<unsigned char>(value[right - 1]))) {
|
||||||
|
--right;
|
||||||
|
}
|
||||||
|
return value.substr(left, right - left);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string now_text() {
|
||||||
|
const auto now = std::chrono::system_clock::now();
|
||||||
|
const std::time_t time = std::chrono::system_clock::to_time_t(now);
|
||||||
|
std::tm local{};
|
||||||
|
#ifdef _WIN32
|
||||||
|
localtime_s(&local, &time);
|
||||||
|
#else
|
||||||
|
localtime_r(&time, &local);
|
||||||
|
#endif
|
||||||
|
std::ostringstream out;
|
||||||
|
out << std::put_time(&local, "%Y-%m-%d %H:%M:%S");
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_text_content_type(const std::string &content_type) {
|
||||||
|
const std::string lower = to_lower(content_type);
|
||||||
|
return lower.find("json") != std::string::npos || lower.find("text/") != std::string::npos ||
|
||||||
|
lower.find("x-www-form-urlencoded") != std::string::npos || lower.find("xml") != std::string::npos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_mostly_printable(const std::string &text) {
|
||||||
|
if (text.empty()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::size_t printable = 0;
|
||||||
|
for (unsigned char ch : text) {
|
||||||
|
if (std::isprint(ch) || std::isspace(ch)) {
|
||||||
|
++printable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return printable * 100 / text.size() >= 90;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string truncate_text(const std::string &text, int max_body) {
|
||||||
|
if (max_body <= 0 || text.size() <= static_cast<std::size_t>(max_body)) {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
return text.substr(0, static_cast<std::size_t>(max_body)) + "...<truncated>";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string request_header_summary(const Request &request) {
|
||||||
|
std::ostringstream out;
|
||||||
|
const std::string content_type = request.header("content-type");
|
||||||
|
out << "content_type=" << (content_type.empty() ? "-" : content_type);
|
||||||
|
out << " auth=" << (request.header("authorization").empty() ? "absent" : "present");
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_request_summary(const LoggingConfig &logging, const Request &request) {
|
||||||
|
if (!logging.http_summary) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::clog << "[" << now_text() << "] REQ ip=" << request.remote_addr
|
||||||
|
<< " method=" << request.method
|
||||||
|
<< " path=" << request.path
|
||||||
|
<< " query=" << (request.query.empty() ? "-" : request.raw_target.substr(request.path.size()))
|
||||||
|
<< " body_bytes=" << request.body.size()
|
||||||
|
<< " " << request_header_summary(request)
|
||||||
|
<< std::endl;
|
||||||
|
if (logging.http_dump && !request.body.empty()) {
|
||||||
|
const std::string content_type = request.header("content-type");
|
||||||
|
if ((content_type.empty() || is_text_content_type(content_type)) && is_mostly_printable(request.body)) {
|
||||||
|
std::clog << "[" << now_text() << "] REQ_BODY "
|
||||||
|
<< truncate_text(request.body, logging.http_max_body)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void log_response_summary(const LoggingConfig &logging, const Request &request, const Response &response, long long cost_ms) {
|
||||||
|
if (!logging.http_summary) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const std::size_t body_bytes = response.has_binary() ? response.binary_body.size() : response.body.size();
|
||||||
|
std::clog << "[" << now_text() << "] RESP ip=" << request.remote_addr
|
||||||
|
<< " method=" << request.method
|
||||||
|
<< " path=" << request.path
|
||||||
|
<< " status=" << response.status
|
||||||
|
<< " content_type=" << response.content_type
|
||||||
|
<< " body_bytes=" << body_bytes
|
||||||
|
<< " binary=" << (response.has_binary() ? "yes" : "no")
|
||||||
|
<< " cost_ms=" << cost_ms
|
||||||
|
<< std::endl;
|
||||||
|
if (logging.http_dump && !response.has_binary() && !response.body.empty() &&
|
||||||
|
is_text_content_type(response.content_type) && is_mostly_printable(response.body)) {
|
||||||
|
std::clog << "[" << now_text() << "] RESP_BODY "
|
||||||
|
<< truncate_text(response.body, logging.http_max_body)
|
||||||
|
<< std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> split_path(const std::string &path) {
|
||||||
|
std::vector<std::string> result;
|
||||||
|
std::string current;
|
||||||
|
for (char ch : path) {
|
||||||
|
if (ch == '/') {
|
||||||
|
if (!current.empty()) {
|
||||||
|
result.push_back(current);
|
||||||
|
current.clear();
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
current.push_back(ch);
|
||||||
|
}
|
||||||
|
if (!current.empty()) {
|
||||||
|
result.push_back(current);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match_route(const std::string &pattern, const std::string &path, std::map<std::string, std::string> *params) {
|
||||||
|
const auto lhs = split_path(pattern);
|
||||||
|
const auto rhs = split_path(path);
|
||||||
|
if (lhs.size() != rhs.size()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (std::size_t i = 0; i < lhs.size(); ++i) {
|
||||||
|
const std::string &expected = lhs[i];
|
||||||
|
const std::string actual = url_decode(rhs[i]);
|
||||||
|
if (expected.size() >= 2 && expected.front() == '{' && expected.back() == '}') {
|
||||||
|
(*params)[expected.substr(1, expected.size() - 2)] = actual;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (expected != actual) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void close_socket(socket_t sock) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
closesocket(sock);
|
||||||
|
#else
|
||||||
|
close(sock);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
bool parse_ipv4_address(const std::string &host, in_addr *addr) {
|
||||||
|
if (host.empty() || host == "0.0.0.0") {
|
||||||
|
addr->s_addr = htonl(INADDR_ANY);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
#ifdef _WIN32
|
||||||
|
return InetPtonA(AF_INET, host.c_str(), addr) == 1;
|
||||||
|
#else
|
||||||
|
return inet_pton(AF_INET, host.c_str(), addr) == 1;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string ipv4_address_to_string(const in_addr &addr) {
|
||||||
|
char buffer[INET_ADDRSTRLEN] = {};
|
||||||
|
#ifdef _WIN32
|
||||||
|
if (InetNtopA(AF_INET, const_cast<in_addr *>(&addr), buffer, static_cast<DWORD>(sizeof(buffer))) == nullptr) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
if (inet_ntop(AF_INET, &addr, buffer, sizeof(buffer)) == nullptr) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool send_all(socket_t sock, const unsigned char *data, std::size_t size) {
|
||||||
|
std::size_t sent = 0;
|
||||||
|
while (sent < size) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
const int count = send(sock, reinterpret_cast<const char *>(data + sent), static_cast<int>(size - sent), 0);
|
||||||
|
#else
|
||||||
|
const auto count = send(sock, data + sent, size - sent, 0);
|
||||||
|
#endif
|
||||||
|
if (count <= 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
sent += static_cast<std::size_t>(count);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string reason_phrase(int status) {
|
||||||
|
switch (status) {
|
||||||
|
case 200: return "OK";
|
||||||
|
case 201: return "Created";
|
||||||
|
case 400: return "Bad Request";
|
||||||
|
case 401: return "Unauthorized";
|
||||||
|
case 403: return "Forbidden";
|
||||||
|
case 404: return "Not Found";
|
||||||
|
case 405: return "Method Not Allowed";
|
||||||
|
case 500: return "Internal Server Error";
|
||||||
|
case 501: return "Not Implemented";
|
||||||
|
default: return "OK";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string make_http_message(const Response &response) {
|
||||||
|
std::ostringstream out;
|
||||||
|
const std::size_t content_length = response.has_binary() ? response.binary_body.size() : response.body.size();
|
||||||
|
out << "HTTP/1.1 " << response.status << " " << reason_phrase(response.status) << "\r\n";
|
||||||
|
out << "Connection: close\r\n";
|
||||||
|
out << "Content-Length: " << content_length << "\r\n";
|
||||||
|
out << "Content-Type: " << response.content_type << "\r\n";
|
||||||
|
for (const auto &header : response.headers) {
|
||||||
|
out << header.first << ": " << header.second << "\r\n";
|
||||||
|
}
|
||||||
|
out << "\r\n";
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
Response bad_request(const std::string &message) {
|
||||||
|
Response response;
|
||||||
|
response.status = 400;
|
||||||
|
response.body = "{\"code\":400,\"message\":\"" + message + "\",\"data\":null}";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string read_request(socket_t client) {
|
||||||
|
std::string data;
|
||||||
|
std::array<char, 4096> buffer{};
|
||||||
|
std::size_t header_end = std::string::npos;
|
||||||
|
std::size_t content_length = 0;
|
||||||
|
while (true) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
const int bytes = recv(client, buffer.data(), static_cast<int>(buffer.size()), 0);
|
||||||
|
#else
|
||||||
|
const auto bytes = recv(client, buffer.data(), buffer.size(), 0);
|
||||||
|
#endif
|
||||||
|
if (bytes <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
data.append(buffer.data(), static_cast<std::size_t>(bytes));
|
||||||
|
if (header_end == std::string::npos) {
|
||||||
|
header_end = data.find("\r\n\r\n");
|
||||||
|
if (header_end != std::string::npos) {
|
||||||
|
const std::string headers = data.substr(0, header_end + 4);
|
||||||
|
const std::size_t pos = to_lower(headers).find("content-length:");
|
||||||
|
if (pos != std::string::npos) {
|
||||||
|
std::size_t value_start = headers.find(':', pos);
|
||||||
|
std::size_t value_end = headers.find("\r\n", value_start);
|
||||||
|
content_length = static_cast<std::size_t>(
|
||||||
|
std::stoll(trim(headers.substr(value_start + 1, value_end - value_start - 1))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (header_end != std::string::npos && data.size() >= header_end + 4 + content_length) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
Request parse_request(const std::string &raw, const std::string &remote_addr) {
|
||||||
|
const std::size_t header_end = raw.find("\r\n\r\n");
|
||||||
|
if (header_end == std::string::npos) {
|
||||||
|
throw std::runtime_error("invalid request");
|
||||||
|
}
|
||||||
|
std::istringstream lines(raw.substr(0, header_end));
|
||||||
|
std::string line;
|
||||||
|
if (!std::getline(lines, line)) {
|
||||||
|
throw std::runtime_error("missing request line");
|
||||||
|
}
|
||||||
|
if (!line.empty() && line.back() == '\r') {
|
||||||
|
line.pop_back();
|
||||||
|
}
|
||||||
|
std::istringstream request_line(line);
|
||||||
|
Request request;
|
||||||
|
std::string version;
|
||||||
|
request_line >> request.method >> request.raw_target >> version;
|
||||||
|
request.remote_addr = remote_addr;
|
||||||
|
const std::size_t query_pos = request.raw_target.find('?');
|
||||||
|
request.path = query_pos == std::string::npos ? request.raw_target : request.raw_target.substr(0, query_pos);
|
||||||
|
if (query_pos != std::string::npos) {
|
||||||
|
request.query = parse_query_string(request.raw_target.substr(query_pos + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
while (std::getline(lines, line)) {
|
||||||
|
if (!line.empty() && line.back() == '\r') {
|
||||||
|
line.pop_back();
|
||||||
|
}
|
||||||
|
const std::size_t pos = line.find(':');
|
||||||
|
if (pos == std::string::npos) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
request.headers[to_lower(trim(line.substr(0, pos)))] = trim(line.substr(pos + 1));
|
||||||
|
}
|
||||||
|
request.body = raw.substr(header_end + 4);
|
||||||
|
return request;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::string Request::header(const std::string &name) const {
|
||||||
|
const auto it = headers.find(to_lower(name));
|
||||||
|
return it == headers.end() ? "" : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Request::query_value(const std::string &name) const {
|
||||||
|
const auto it = query.find(name);
|
||||||
|
return it == query.end() ? "" : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Request::path_param(const std::string &name) const {
|
||||||
|
const auto it = path_params.find(name);
|
||||||
|
return it == path_params.end() ? "" : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Response::has_binary() const {
|
||||||
|
return !binary_body.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Router::add(const std::string &method, const std::string &pattern, bool requires_auth, Handler handler) {
|
||||||
|
routes_.push_back(Route{to_lower(method), pattern, requires_auth, std::move(handler)});
|
||||||
|
}
|
||||||
|
|
||||||
|
Response Router::dispatch(Request request) const {
|
||||||
|
const std::string method = to_lower(request.method);
|
||||||
|
for (const auto &route : routes_) {
|
||||||
|
if (route.method != method) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::map<std::string, std::string> params;
|
||||||
|
if (!match_route(route.pattern, request.path, ¶ms)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
request.path_params = std::move(params);
|
||||||
|
return route.handler(request);
|
||||||
|
}
|
||||||
|
Response response;
|
||||||
|
response.status = 404;
|
||||||
|
response.body = "{\"code\":404,\"message\":\"not found\",\"data\":null}";
|
||||||
|
return response;
|
||||||
|
}
|
||||||
|
|
||||||
|
HttpServer::HttpServer(std::string host, int port, LoggingConfig logging, const Router &router)
|
||||||
|
: host_(std::move(host)), port_(port), logging_(std::move(logging)), router_(router) {}
|
||||||
|
|
||||||
|
int HttpServer::run() const {
|
||||||
|
#ifdef _WIN32
|
||||||
|
WSADATA wsa_data{};
|
||||||
|
if (WSAStartup(MAKEWORD(2, 2), &wsa_data) != 0) {
|
||||||
|
std::cerr << "WSAStartup failed\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
socket_t server = socket(AF_INET, SOCK_STREAM, 0);
|
||||||
|
if (server == kInvalidSocket) {
|
||||||
|
std::cerr << "socket creation failed\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int reuse = 1;
|
||||||
|
#ifdef _WIN32
|
||||||
|
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<const char *>(&reuse), sizeof(reuse));
|
||||||
|
#else
|
||||||
|
setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sockaddr_in addr{};
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons(static_cast<unsigned short>(port_));
|
||||||
|
if (!parse_ipv4_address(host_, &addr.sin_addr)) {
|
||||||
|
std::cerr << "invalid listen host: " << host_ << "\n";
|
||||||
|
close_socket(server);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bind(server, reinterpret_cast<sockaddr *>(&addr), sizeof(addr)) != 0) {
|
||||||
|
std::cerr << "bind failed\n";
|
||||||
|
close_socket(server);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (listen(server, 64) != 0) {
|
||||||
|
std::cerr << "listen failed\n";
|
||||||
|
close_socket(server);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::clog << "Listening on " << host_ << ":" << port_ << std::endl;
|
||||||
|
while (true) {
|
||||||
|
sockaddr_in client_addr{};
|
||||||
|
#ifdef _WIN32
|
||||||
|
int client_len = sizeof(client_addr);
|
||||||
|
#else
|
||||||
|
socklen_t client_len = sizeof(client_addr);
|
||||||
|
#endif
|
||||||
|
socket_t client = accept(server, reinterpret_cast<sockaddr *>(&client_addr), &client_len);
|
||||||
|
if (client == kInvalidSocket) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::thread([this, client, client_addr]() {
|
||||||
|
const std::string remote = ipv4_address_to_string(client_addr.sin_addr);
|
||||||
|
try {
|
||||||
|
const std::string raw = read_request(client);
|
||||||
|
if (raw.empty()) {
|
||||||
|
close_socket(client);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Request request = parse_request(raw, remote);
|
||||||
|
log_request_summary(logging_, request);
|
||||||
|
const auto started = std::chrono::steady_clock::now();
|
||||||
|
const Response response = router_.dispatch(request);
|
||||||
|
const auto finished = std::chrono::steady_clock::now();
|
||||||
|
const auto cost_ms = std::chrono::duration_cast<std::chrono::milliseconds>(finished - started).count();
|
||||||
|
log_response_summary(logging_, request, response, cost_ms);
|
||||||
|
const std::string headers = make_http_message(response);
|
||||||
|
send_all(client, reinterpret_cast<const unsigned char *>(headers.data()), headers.size());
|
||||||
|
if (response.has_binary()) {
|
||||||
|
send_all(client, response.binary_body.data(), response.binary_body.size());
|
||||||
|
} else {
|
||||||
|
send_all(client, reinterpret_cast<const unsigned char *>(response.body.data()), response.body.size());
|
||||||
|
}
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
const Response response = bad_request(ex.what());
|
||||||
|
Request fallback;
|
||||||
|
fallback.remote_addr = remote;
|
||||||
|
fallback.method = "UNKNOWN";
|
||||||
|
fallback.path = "-";
|
||||||
|
log_response_summary(logging_, fallback, response, 0);
|
||||||
|
const std::string headers = make_http_message(response);
|
||||||
|
send_all(client, reinterpret_cast<const unsigned char *>(headers.data()), headers.size());
|
||||||
|
send_all(client, reinterpret_cast<const unsigned char *>(response.body.data()), response.body.size());
|
||||||
|
}
|
||||||
|
close_socket(client);
|
||||||
|
}).detach();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url_decode(const std::string &value) {
|
||||||
|
std::ostringstream out;
|
||||||
|
for (std::size_t i = 0; i < value.size(); ++i) {
|
||||||
|
const char ch = value[i];
|
||||||
|
if (ch == '+' ) {
|
||||||
|
out << ' ';
|
||||||
|
} else if (ch == '%' && i + 2 < value.size()) {
|
||||||
|
const std::string hex = value.substr(i + 1, 2);
|
||||||
|
out << static_cast<char>(std::strtol(hex.c_str(), nullptr, 16));
|
||||||
|
i += 2;
|
||||||
|
} else {
|
||||||
|
out << ch;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, std::string> parse_query_string(const std::string &query) {
|
||||||
|
std::map<std::string, std::string> values;
|
||||||
|
std::size_t start = 0;
|
||||||
|
while (start < query.size()) {
|
||||||
|
const std::size_t amp = query.find('&', start);
|
||||||
|
const std::string token = query.substr(start, amp == std::string::npos ? std::string::npos : amp - start);
|
||||||
|
const std::size_t eq = token.find('=');
|
||||||
|
if (eq == std::string::npos) {
|
||||||
|
values[url_decode(token)] = "";
|
||||||
|
} else {
|
||||||
|
values[url_decode(token.substr(0, eq))] = url_decode(token.substr(eq + 1));
|
||||||
|
}
|
||||||
|
if (amp == std::string::npos) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
start = amp + 1;
|
||||||
|
}
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string guess_content_type(const std::string &path) {
|
||||||
|
const auto lower = to_lower(path);
|
||||||
|
if (lower.size() >= 4 && lower.substr(lower.size() - 4) == ".png") return "image/png";
|
||||||
|
if (lower.size() >= 4 && lower.substr(lower.size() - 4) == ".jpg") return "image/jpeg";
|
||||||
|
if (lower.size() >= 5 && lower.substr(lower.size() - 5) == ".jpeg") return "image/jpeg";
|
||||||
|
if (lower.size() >= 4 && lower.substr(lower.size() - 4) == ".mp4") return "video/mp4";
|
||||||
|
if (lower.size() >= 4 && lower.substr(lower.size() - 4) == ".zip") return "application/zip";
|
||||||
|
if (lower.size() >= 7 && lower.substr(lower.size() - 7) == ".tar.gz") return "application/gzip";
|
||||||
|
if (lower.size() >= 4 && lower.substr(lower.size() - 4) == ".txt") return "text/plain; charset=utf-8";
|
||||||
|
if (lower.size() >= 5 && lower.substr(lower.size() - 5) == ".json") return "application/json; charset=utf-8";
|
||||||
|
if (lower.size() >= 3 && lower.substr(lower.size() - 3) == ".sh") return "application/octet-stream";
|
||||||
|
return "application/octet-stream";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
384
src/json.cpp
Normal file
384
src/json.cpp
Normal file
@@ -0,0 +1,384 @@
|
|||||||
|
#include "dps/json.hpp"
|
||||||
|
|
||||||
|
#include <cctype>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class Parser {
|
||||||
|
public:
|
||||||
|
explicit Parser(const std::string &text) : text_(text) {}
|
||||||
|
|
||||||
|
Json parse() {
|
||||||
|
skip_ws();
|
||||||
|
Json value = parse_value();
|
||||||
|
skip_ws();
|
||||||
|
if (pos_ != text_.size()) {
|
||||||
|
throw std::runtime_error("unexpected trailing json content");
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Json parse_value() {
|
||||||
|
if (match("null")) {
|
||||||
|
return Json();
|
||||||
|
}
|
||||||
|
if (match("true")) {
|
||||||
|
return Json(true);
|
||||||
|
}
|
||||||
|
if (match("false")) {
|
||||||
|
return Json(false);
|
||||||
|
}
|
||||||
|
if (peek() == '"') {
|
||||||
|
return Json(parse_string());
|
||||||
|
}
|
||||||
|
if (peek() == '[') {
|
||||||
|
return parse_array();
|
||||||
|
}
|
||||||
|
if (peek() == '{') {
|
||||||
|
return parse_object();
|
||||||
|
}
|
||||||
|
return Json(parse_number());
|
||||||
|
}
|
||||||
|
|
||||||
|
Json parse_array() {
|
||||||
|
consume('[');
|
||||||
|
Json::array_t items;
|
||||||
|
skip_ws();
|
||||||
|
if (peek() == ']') {
|
||||||
|
consume(']');
|
||||||
|
return Json(std::move(items));
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
skip_ws();
|
||||||
|
items.push_back(parse_value());
|
||||||
|
skip_ws();
|
||||||
|
if (peek() == ']') {
|
||||||
|
consume(']');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
consume(',');
|
||||||
|
}
|
||||||
|
return Json(std::move(items));
|
||||||
|
}
|
||||||
|
|
||||||
|
Json parse_object() {
|
||||||
|
consume('{');
|
||||||
|
Json::object_t object;
|
||||||
|
skip_ws();
|
||||||
|
if (peek() == '}') {
|
||||||
|
consume('}');
|
||||||
|
return Json(std::move(object));
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
skip_ws();
|
||||||
|
std::string key = parse_string();
|
||||||
|
skip_ws();
|
||||||
|
consume(':');
|
||||||
|
skip_ws();
|
||||||
|
object.emplace(std::move(key), parse_value());
|
||||||
|
skip_ws();
|
||||||
|
if (peek() == '}') {
|
||||||
|
consume('}');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
consume(',');
|
||||||
|
}
|
||||||
|
return Json(std::move(object));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string parse_string() {
|
||||||
|
consume('"');
|
||||||
|
std::ostringstream out;
|
||||||
|
while (pos_ < text_.size()) {
|
||||||
|
char ch = text_[pos_++];
|
||||||
|
if (ch == '"') {
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
if (ch != '\\') {
|
||||||
|
out << ch;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pos_ >= text_.size()) {
|
||||||
|
throw std::runtime_error("unterminated escape");
|
||||||
|
}
|
||||||
|
char esc = text_[pos_++];
|
||||||
|
switch (esc) {
|
||||||
|
case '"': out << '"'; break;
|
||||||
|
case '\\': out << '\\'; break;
|
||||||
|
case '/': out << '/'; break;
|
||||||
|
case 'b': out << '\b'; break;
|
||||||
|
case 'f': out << '\f'; break;
|
||||||
|
case 'n': out << '\n'; break;
|
||||||
|
case 'r': out << '\r'; break;
|
||||||
|
case 't': out << '\t'; break;
|
||||||
|
case 'u': {
|
||||||
|
if (pos_ + 4 > text_.size()) {
|
||||||
|
throw std::runtime_error("bad unicode escape");
|
||||||
|
}
|
||||||
|
const std::string hex = text_.substr(pos_, 4);
|
||||||
|
pos_ += 4;
|
||||||
|
const unsigned int code = static_cast<unsigned int>(std::stoul(hex, nullptr, 16));
|
||||||
|
if (code <= 0x7F) {
|
||||||
|
out << static_cast<char>(code);
|
||||||
|
} else if (code <= 0x7FF) {
|
||||||
|
out << static_cast<char>(0xC0 | ((code >> 6) & 0x1F));
|
||||||
|
out << static_cast<char>(0x80 | (code & 0x3F));
|
||||||
|
} else {
|
||||||
|
out << static_cast<char>(0xE0 | ((code >> 12) & 0x0F));
|
||||||
|
out << static_cast<char>(0x80 | ((code >> 6) & 0x3F));
|
||||||
|
out << static_cast<char>(0x80 | (code & 0x3F));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw std::runtime_error("unsupported escape");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw std::runtime_error("unterminated string");
|
||||||
|
}
|
||||||
|
|
||||||
|
double parse_number() {
|
||||||
|
const std::size_t start = pos_;
|
||||||
|
if (peek() == '-') {
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
while (std::isdigit(static_cast<unsigned char>(peek()))) {
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
if (peek() == '.') {
|
||||||
|
++pos_;
|
||||||
|
while (std::isdigit(static_cast<unsigned char>(peek()))) {
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (peek() == 'e' || peek() == 'E') {
|
||||||
|
++pos_;
|
||||||
|
if (peek() == '+' || peek() == '-') {
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
while (std::isdigit(static_cast<unsigned char>(peek()))) {
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return std::stod(text_.substr(start, pos_ - start));
|
||||||
|
}
|
||||||
|
|
||||||
|
char peek() const {
|
||||||
|
return pos_ < text_.size() ? text_[pos_] : '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void consume(char expected) {
|
||||||
|
if (peek() != expected) {
|
||||||
|
throw std::runtime_error("unexpected token");
|
||||||
|
}
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool match(const char *literal) {
|
||||||
|
const std::size_t len = std::char_traits<char>::length(literal);
|
||||||
|
if (text_.compare(pos_, len, literal) == 0) {
|
||||||
|
pos_ += len;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void skip_ws() {
|
||||||
|
while (pos_ < text_.size() && std::isspace(static_cast<unsigned char>(text_[pos_]))) {
|
||||||
|
++pos_;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string &text_;
|
||||||
|
std::size_t pos_ = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
std::string escape_string(const std::string &value) {
|
||||||
|
std::ostringstream out;
|
||||||
|
for (const unsigned char ch : value) {
|
||||||
|
switch (ch) {
|
||||||
|
case '"': out << "\\\""; break;
|
||||||
|
case '\\': out << "\\\\"; break;
|
||||||
|
case '\b': out << "\\b"; break;
|
||||||
|
case '\f': out << "\\f"; break;
|
||||||
|
case '\n': out << "\\n"; break;
|
||||||
|
case '\r': out << "\\r"; break;
|
||||||
|
case '\t': out << "\\t"; break;
|
||||||
|
default:
|
||||||
|
if (ch < 0x20) {
|
||||||
|
out << "\\u" << std::hex << std::setw(4) << std::setfill('0') << static_cast<int>(ch);
|
||||||
|
} else {
|
||||||
|
out << static_cast<char>(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Json::Json() : value_(nullptr) {}
|
||||||
|
Json::Json(std::nullptr_t) : value_(nullptr) {}
|
||||||
|
Json::Json(bool value) : value_(value) {}
|
||||||
|
Json::Json(int value) : value_(static_cast<double>(value)) {}
|
||||||
|
Json::Json(long long value) : value_(static_cast<double>(value)) {}
|
||||||
|
Json::Json(double value) : value_(value) {}
|
||||||
|
Json::Json(const char *value) : value_(std::string(value == nullptr ? "" : value)) {}
|
||||||
|
Json::Json(const std::string &value) : value_(value) {}
|
||||||
|
Json::Json(std::string &&value) : value_(std::move(value)) {}
|
||||||
|
Json::Json(const array_t &value) : value_(value) {}
|
||||||
|
Json::Json(array_t &&value) : value_(std::move(value)) {}
|
||||||
|
Json::Json(const object_t &value) : value_(value) {}
|
||||||
|
Json::Json(object_t &&value) : value_(std::move(value)) {}
|
||||||
|
|
||||||
|
Json Json::parse(const std::string &text) {
|
||||||
|
return Parser(text).parse();
|
||||||
|
}
|
||||||
|
|
||||||
|
Json Json::object() {
|
||||||
|
return Json(object_t{});
|
||||||
|
}
|
||||||
|
|
||||||
|
Json Json::array() {
|
||||||
|
return Json(array_t{});
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Json::is_null() const { return std::holds_alternative<std::nullptr_t>(value_); }
|
||||||
|
bool Json::is_bool() const { return std::holds_alternative<bool>(value_); }
|
||||||
|
bool Json::is_number() const { return std::holds_alternative<double>(value_); }
|
||||||
|
bool Json::is_string() const { return std::holds_alternative<std::string>(value_); }
|
||||||
|
bool Json::is_array() const { return std::holds_alternative<array_t>(value_); }
|
||||||
|
bool Json::is_object() const { return std::holds_alternative<object_t>(value_); }
|
||||||
|
|
||||||
|
bool Json::as_bool() const { return std::get<bool>(value_); }
|
||||||
|
double Json::as_number() const { return std::get<double>(value_); }
|
||||||
|
int Json::as_int() const { return static_cast<int>(as_number()); }
|
||||||
|
long long Json::as_int64() const { return static_cast<long long>(as_number()); }
|
||||||
|
const std::string &Json::as_string() const { return std::get<std::string>(value_); }
|
||||||
|
const Json::array_t &Json::as_array() const { return std::get<array_t>(value_); }
|
||||||
|
const Json::object_t &Json::as_object() const { return std::get<object_t>(value_); }
|
||||||
|
Json::array_t &Json::as_array() { return std::get<array_t>(value_); }
|
||||||
|
Json::object_t &Json::as_object() { return std::get<object_t>(value_); }
|
||||||
|
|
||||||
|
bool Json::contains(const std::string &key) const {
|
||||||
|
if (!is_object()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return as_object().find(key) != as_object().end();
|
||||||
|
}
|
||||||
|
|
||||||
|
const Json &Json::at(const std::string &key) const {
|
||||||
|
return as_object().at(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
Json &Json::operator[](const std::string &key) {
|
||||||
|
if (!is_object()) {
|
||||||
|
value_ = object_t{};
|
||||||
|
}
|
||||||
|
return as_object()[key];
|
||||||
|
}
|
||||||
|
|
||||||
|
const Json &Json::operator[](const std::string &key) const {
|
||||||
|
static const Json kNull;
|
||||||
|
if (!is_object()) {
|
||||||
|
return kNull;
|
||||||
|
}
|
||||||
|
const auto it = as_object().find(key);
|
||||||
|
return it == as_object().end() ? kNull : it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Json &Json::at(std::size_t index) const {
|
||||||
|
return as_array().at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
Json &Json::at(std::size_t index) {
|
||||||
|
return as_array().at(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Json::push_back(const Json &value) {
|
||||||
|
if (!is_array()) {
|
||||||
|
value_ = array_t{};
|
||||||
|
}
|
||||||
|
as_array().push_back(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t Json::size() const {
|
||||||
|
if (is_array()) {
|
||||||
|
return as_array().size();
|
||||||
|
}
|
||||||
|
if (is_object()) {
|
||||||
|
return as_object().size();
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Json::dump() const {
|
||||||
|
if (is_null()) {
|
||||||
|
return "null";
|
||||||
|
}
|
||||||
|
if (is_bool()) {
|
||||||
|
return as_bool() ? "true" : "false";
|
||||||
|
}
|
||||||
|
if (is_number()) {
|
||||||
|
std::ostringstream out;
|
||||||
|
out << std::setprecision(15) << as_number();
|
||||||
|
std::string result = out.str();
|
||||||
|
if (result.find('.') != std::string::npos) {
|
||||||
|
while (!result.empty() && result.back() == '0') {
|
||||||
|
result.pop_back();
|
||||||
|
}
|
||||||
|
if (!result.empty() && result.back() == '.') {
|
||||||
|
result.pop_back();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.empty() ? "0" : result;
|
||||||
|
}
|
||||||
|
if (is_string()) {
|
||||||
|
return "\"" + escape_string(as_string()) + "\"";
|
||||||
|
}
|
||||||
|
if (is_array()) {
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "[";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto &item : as_array()) {
|
||||||
|
if (!first) {
|
||||||
|
out << ",";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
out << item.dump();
|
||||||
|
}
|
||||||
|
out << "]";
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
std::ostringstream out;
|
||||||
|
out << "{";
|
||||||
|
bool first = true;
|
||||||
|
for (const auto &entry : as_object()) {
|
||||||
|
if (!first) {
|
||||||
|
out << ",";
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
out << "\"" << escape_string(entry.first) << "\":" << entry.second.dump();
|
||||||
|
}
|
||||||
|
out << "}";
|
||||||
|
return out.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Json::to_string_or(const std::string &fallback) const {
|
||||||
|
return is_string() ? as_string() : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
int Json::to_int_or(int fallback) const {
|
||||||
|
return is_number() ? as_int() : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Json::to_bool_or(bool fallback) const {
|
||||||
|
return is_bool() ? as_bool() : fallback;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
17
src/labels.cpp
Normal file
17
src/labels.cpp
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
#include "dps/labels.hpp"
|
||||||
|
|
||||||
|
namespace dps {
|
||||||
|
|
||||||
|
std::string membership_label(int level) {
|
||||||
|
switch (level) {
|
||||||
|
case 2:
|
||||||
|
return "\xE9\x92\xBB\xE7\x9F\xB3\xE4\xBC\x9A\xE5\x91\x98";
|
||||||
|
case 3:
|
||||||
|
return "\xE8\x87\xB3\xE8\x87\xBB\xE4\xBC\x9A\xE5\x91\x98";
|
||||||
|
case 1:
|
||||||
|
default:
|
||||||
|
return "\xE9\xBB\x84\xE9\x87\x91\xE4\xBC\x9A\xE5\x91\x98";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace dps
|
||||||
25
src/main.cpp
Normal file
25
src/main.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "dps/app.hpp"
|
||||||
|
#include "dps/config.hpp"
|
||||||
|
|
||||||
|
#include <exception>
|
||||||
|
#include <iostream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
std::string config_path = "config/server.conf";
|
||||||
|
for (int i = 1; i < argc; ++i) {
|
||||||
|
const std::string arg = argv[i];
|
||||||
|
if (arg == "--config" && i + 1 < argc) {
|
||||||
|
config_path = argv[++i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
dps::AppConfig config = dps::load_config(config_path);
|
||||||
|
dps::Application app(std::move(config));
|
||||||
|
return app.run();
|
||||||
|
} catch (const std::exception &ex) {
|
||||||
|
std::cerr << "failed to start dps_manager_server: " << ex.what() << "\n";
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
51
tests/config_sync_test.py
Normal file
51
tests/config_sync_test.py
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import difflib
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def normalize(text: str) -> str:
|
||||||
|
return text.replace("\r\n", "\n").strip() + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def assert_same_file(expected: Path, actual: Path) -> None:
|
||||||
|
expected_text = normalize(expected.read_text(encoding="utf-8"))
|
||||||
|
actual_text = normalize(actual.read_text(encoding="utf-8"))
|
||||||
|
if expected_text == actual_text:
|
||||||
|
return
|
||||||
|
|
||||||
|
diff = "".join(
|
||||||
|
difflib.unified_diff(
|
||||||
|
expected_text.splitlines(keepends=True),
|
||||||
|
actual_text.splitlines(keepends=True),
|
||||||
|
fromfile=str(expected),
|
||||||
|
tofile=str(actual),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
raise AssertionError(diff)
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
project_root = Path(__file__).resolve().parents[1]
|
||||||
|
source_config = project_root / "config" / "server.conf"
|
||||||
|
build_configs = [
|
||||||
|
project_root / "build" / "windows" / "x64" / "debug" / "config" / "server.conf",
|
||||||
|
project_root / "build" / "windows" / "x64" / "release" / "config" / "server.conf",
|
||||||
|
]
|
||||||
|
|
||||||
|
missing = [path for path in build_configs if not path.is_file()]
|
||||||
|
if missing:
|
||||||
|
raise AssertionError(
|
||||||
|
"missing build config(s): " + ", ".join(str(path) for path in missing)
|
||||||
|
)
|
||||||
|
|
||||||
|
for build_config in build_configs:
|
||||||
|
assert_same_file(source_config, build_config)
|
||||||
|
|
||||||
|
print("config sync test passed")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
162
tests/crypto_smoke_test.cpp
Normal file
162
tests/crypto_smoke_test.cpp
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
#include "dps/app.hpp"
|
||||||
|
#include "dps/config.hpp"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstdio>
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <openssl/evp.h>
|
||||||
|
#include <zlib.h>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
void set_env(const char *name, const char *value) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
_putenv_s(name, value);
|
||||||
|
#else
|
||||||
|
setenv(name, value, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_env(const char *name) {
|
||||||
|
#ifdef _WIN32
|
||||||
|
_putenv_s(name, "");
|
||||||
|
#else
|
||||||
|
unsetenv(name);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<unsigned char> decode_base64(const std::string &text) {
|
||||||
|
std::string normalized = text;
|
||||||
|
while (normalized.size() % 4 != 0) normalized.push_back('=');
|
||||||
|
|
||||||
|
std::vector<unsigned char> decoded((normalized.size() / 4) * 3);
|
||||||
|
const int size = EVP_DecodeBlock(decoded.data(),
|
||||||
|
reinterpret_cast<const unsigned char *>(normalized.data()),
|
||||||
|
static_cast<int>(normalized.size()));
|
||||||
|
assert(size >= 0);
|
||||||
|
|
||||||
|
std::size_t padding = 0;
|
||||||
|
if (!normalized.empty() && normalized.back() == '=') ++padding;
|
||||||
|
if (normalized.size() > 1 && normalized[normalized.size() - 2] == '=') ++padding;
|
||||||
|
decoded.resize(static_cast<std::size_t>(size) - padding);
|
||||||
|
return decoded;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string gunzip_bytes(const std::vector<unsigned char> &compressed) {
|
||||||
|
z_stream stream{};
|
||||||
|
stream.next_in = const_cast<Bytef *>(reinterpret_cast<const Bytef *>(compressed.data()));
|
||||||
|
stream.avail_in = static_cast<uInt>(compressed.size());
|
||||||
|
|
||||||
|
const int init = inflateInit2(&stream, 15 + 16);
|
||||||
|
assert(init == Z_OK);
|
||||||
|
|
||||||
|
std::string output;
|
||||||
|
std::vector<char> buffer(4096);
|
||||||
|
int ret = Z_OK;
|
||||||
|
while (ret == Z_OK) {
|
||||||
|
stream.next_out = reinterpret_cast<Bytef *>(buffer.data());
|
||||||
|
stream.avail_out = static_cast<uInt>(buffer.size());
|
||||||
|
ret = inflate(&stream, Z_NO_FLUSH);
|
||||||
|
output.append(buffer.data(), buffer.size() - stream.avail_out);
|
||||||
|
}
|
||||||
|
inflateEnd(&stream);
|
||||||
|
assert(ret == Z_STREAM_END);
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_crypto() {
|
||||||
|
dps::LegacyCrypto crypto("unit-test-secret");
|
||||||
|
|
||||||
|
const std::string password = "P@ssw0rd!";
|
||||||
|
const std::string hashed = crypto.hash_password(password);
|
||||||
|
assert(!hashed.empty());
|
||||||
|
assert(hashed.rfind("$2", 0) == 0);
|
||||||
|
assert(crypto.verify_password(password, hashed));
|
||||||
|
assert(!crypto.verify_password(password, password));
|
||||||
|
|
||||||
|
const std::string token = crypto.issue_jwt("tester", 60);
|
||||||
|
assert(!token.empty());
|
||||||
|
const auto subject = crypto.validate_jwt(token);
|
||||||
|
assert(subject.has_value());
|
||||||
|
assert(subject.value() == "tester");
|
||||||
|
assert(!crypto.validate_jwt(token + "broken").has_value());
|
||||||
|
|
||||||
|
const std::string gzip_payload = crypto.gzip_base64("{\"hello\":\"world\"}");
|
||||||
|
assert(!gzip_payload.empty());
|
||||||
|
const std::string inflated = gunzip_bytes(decode_base64(gzip_payload));
|
||||||
|
assert(inflated == "{\"hello\":\"world\"}");
|
||||||
|
|
||||||
|
const std::string rsa_tool = crypto.rsa_private_encrypt_tool("abc123");
|
||||||
|
const std::string rsa_script = crypto.rsa_private_encrypt_script("xyz789");
|
||||||
|
assert(!rsa_tool.empty());
|
||||||
|
assert(!rsa_script.empty());
|
||||||
|
assert(rsa_tool != "abc123");
|
||||||
|
assert(rsa_script != "xyz789");
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_config() {
|
||||||
|
const fs::path path = fs::temp_directory_path() / "dps-config-smoke.conf";
|
||||||
|
{
|
||||||
|
std::ofstream out(path);
|
||||||
|
out << "server.host=0.0.0.0\n";
|
||||||
|
out << "server.port=8651\n";
|
||||||
|
out << "server.trust_proxy=true\n";
|
||||||
|
out << "server.proxy_header=x-real-ip\n";
|
||||||
|
out << "database.host=127.0.0.1\n";
|
||||||
|
out << "database.name=rindro\n";
|
||||||
|
out << "database.user=root\n";
|
||||||
|
out << "database.password=test\n";
|
||||||
|
out << "database.ssl_mode=verify_ca\n";
|
||||||
|
out << "database.ssl_ca=C:/certs/demo-ca.pem\n";
|
||||||
|
out << "database.plugin_dir=C:/mariadb/plugin\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
set_env("DPS_SERVER_HOST", "10.0.0.8");
|
||||||
|
set_env("DPS_SERVER_PROXY_HEADER", "x-forwarded-for");
|
||||||
|
set_env("DPS_DB_HOST", "192.168.0.10");
|
||||||
|
set_env("DPS_DB_USER", "tester");
|
||||||
|
set_env("DPS_DB_PASSWORD", "secret");
|
||||||
|
set_env("DPS_DB_NAME", "demo");
|
||||||
|
set_env("DPS_DB_SSL_MODE", "disable");
|
||||||
|
set_env("DPS_DB_SSL_CA", "D:/certs/dev-ca.pem");
|
||||||
|
set_env("DPS_DB_PLUGIN_DIR", "D:/mariadb/plugin");
|
||||||
|
|
||||||
|
const dps::AppConfig config = dps::load_config(path.string());
|
||||||
|
assert(config.server.host == "10.0.0.8");
|
||||||
|
assert(config.server.port == 8651);
|
||||||
|
assert(config.server.trust_proxy);
|
||||||
|
assert(config.server.proxy_header == "x-forwarded-for");
|
||||||
|
assert(config.database.host == "192.168.0.10");
|
||||||
|
assert(config.database.user == "tester");
|
||||||
|
assert(config.database.password == "secret");
|
||||||
|
assert(config.database.name == "demo");
|
||||||
|
assert(config.database.ssl_mode == "disable");
|
||||||
|
assert(config.database.ssl_ca == "D:/certs/dev-ca.pem");
|
||||||
|
assert(config.database.plugin_dir == "D:/mariadb/plugin");
|
||||||
|
|
||||||
|
clear_env("DPS_SERVER_HOST");
|
||||||
|
clear_env("DPS_SERVER_PROXY_HEADER");
|
||||||
|
clear_env("DPS_DB_HOST");
|
||||||
|
clear_env("DPS_DB_USER");
|
||||||
|
clear_env("DPS_DB_PASSWORD");
|
||||||
|
clear_env("DPS_DB_NAME");
|
||||||
|
clear_env("DPS_DB_SSL_MODE");
|
||||||
|
clear_env("DPS_DB_SSL_CA");
|
||||||
|
clear_env("DPS_DB_PLUGIN_DIR");
|
||||||
|
std::remove(path.string().c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
test_crypto();
|
||||||
|
test_config();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
44
tests/fs_utils_smoke_test.cpp
Normal file
44
tests/fs_utils_smoke_test.cpp
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
#include "dps/fs_utils.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::string utf8_text() {
|
||||||
|
return "2_\xE5\x87\x8C\xE4\xBC\x97";
|
||||||
|
}
|
||||||
|
|
||||||
|
int run_test() {
|
||||||
|
const fs::path root = fs::temp_directory_path() / "dps-fs-utils-smoke";
|
||||||
|
const fs::path nested = root / dps::path_from_utf8(utf8_text());
|
||||||
|
const fs::path file = nested / "img.png";
|
||||||
|
|
||||||
|
fs::remove_all(root);
|
||||||
|
fs::create_directories(nested);
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ofstream output(file, std::ios::binary);
|
||||||
|
output << "png-data";
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::vector<unsigned char> bytes = dps::read_binary_file(file);
|
||||||
|
if (bytes.size() != 8) {
|
||||||
|
std::cerr << "unexpected file size: " << bytes.size() << "\n";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
fs::remove_all(root);
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
return run_test();
|
||||||
|
}
|
||||||
31
tests/get_info_level_contract_test.py
Normal file
31
tests/get_info_level_contract_test.py
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
|
|
||||||
|
def main() -> int:
|
||||||
|
source = Path(__file__).resolve().parents[1] / "src" / "app.cpp"
|
||||||
|
text = source.read_text(encoding="utf-8-sig")
|
||||||
|
|
||||||
|
match = re.search(
|
||||||
|
r"Response Application::handle_get_info\(const Request &request\) \{(?P<body>.*?)\n\}",
|
||||||
|
text,
|
||||||
|
re.S,
|
||||||
|
)
|
||||||
|
if not match:
|
||||||
|
raise AssertionError("handle_get_info definition not found")
|
||||||
|
|
||||||
|
body = match.group("body")
|
||||||
|
if 'body["level"] = user->level;' not in body:
|
||||||
|
raise AssertionError('missing `body["level"] = user->level;` in handle_get_info')
|
||||||
|
if 'body["uservip"] = membership_label(user->level);' not in body:
|
||||||
|
raise AssertionError('missing dynamic `uservip` mapping in handle_get_info')
|
||||||
|
|
||||||
|
print("get_info level contract test passed")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
sys.exit(main())
|
||||||
18
tests/json_smoke_test.cpp
Normal file
18
tests/json_smoke_test.cpp
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
#include "dps/json.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
const dps::Json value = dps::Json::parse("{\"hello\":\"world\",\"n\":1,\"list\":[true,false]}");
|
||||||
|
if (value["hello"].to_string_or("") != "world") {
|
||||||
|
std::cerr << "json parse failed\n";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
if (value["n"].to_int_or(0) != 1) {
|
||||||
|
std::cerr << "json number failed\n";
|
||||||
|
return EXIT_FAILURE;
|
||||||
|
}
|
||||||
|
std::cout << "json smoke test passed\n";
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
25
tests/labels_smoke_test.cpp
Normal file
25
tests/labels_smoke_test.cpp
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
#include "dps/labels.hpp"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
bool expect_label(int level, const std::string &expected) {
|
||||||
|
const std::string actual = dps::membership_label(level);
|
||||||
|
if (actual == expected) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::cerr << "unexpected label for level " << level << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
if (!expect_label(1, "\xE9\xBB\x84\xE9\x87\x91\xE4\xBC\x9A\xE5\x91\x98")) return EXIT_FAILURE;
|
||||||
|
if (!expect_label(2, "\xE9\x92\xBB\xE7\x9F\xB3\xE4\xBC\x9A\xE5\x91\x98")) return EXIT_FAILURE;
|
||||||
|
if (!expect_label(3, "\xE8\x87\xB3\xE8\x87\xBB\xE4\xBC\x9A\xE5\x91\x98")) return EXIT_FAILURE;
|
||||||
|
if (!expect_label(99, "\xE9\xBB\x84\xE9\x87\x91\xE4\xBC\x9A\xE5\x91\x98")) return EXIT_FAILURE;
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
||||||
12
tmp-verify.err
Normal file
12
tmp-verify.err
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
Listening on 0.0.0.0:65170
|
||||||
|
[[2026-04-14 18:39:37] REQ ip=127.0.0.1 method=GET path=/dps/download3/2_%E5%87%8C%E4%BC%97:img.png query=- body_bytes=0 2026-04-14 18:39:37] REQ ip=127.0.0.1 method=GET path=/dps/download3/1_DPS:img.png query=- body_bytes=content_type=- auth=absent
|
||||||
|
0 [content_type=- auth=absent
|
||||||
|
2026-04-14 18:39:37] RESP ip=127.0.0.1 method=GET path=/dps/download3/2_%E5%87%8C%E4%BC%97:img.png status=200 content_type=image/png body_bytes=0 binary=no cost_ms=0
|
||||||
|
[2026-04-14 18:39:37] RESP ip=127.0.0.1 method=GET path=/dps/download3/1_DPS:img.png status=200 content_type=image/png body_bytes=1146693 binary=yes cost_ms=34
|
||||||
|
[2026-04-14 18:39:37] REQ ip=127.0.0.1 method=GET path=/dps/download3/3_%E4%B8%83%E6%B8%B8:img.jpg query=- body_bytes=0 content_type=- auth=absent
|
||||||
|
[2026-04-14 18:39:37] RESP ip=127.0.0.1 method=GET path=/dps/download3/3_%E4%B8%83%E6%B8%B8:img.jpg status=200 content_type=image/jpeg body_bytes=0 binary=no cost_ms=0
|
||||||
|
[2026-04-14 18:39:39] REQ ip=127.0.0.1 method=POST path=/rindro/download/all query=- body_bytes=13 content_type=application/json auth=absent
|
||||||
|
[2026-04-14 18:39:39] REQ_BODY {"key":"***"}
|
||||||
|
[2026-04-14 18:39:39] RESP ip=127.0.0.1 method=POST path=/rindro/download/all status=200 content_type=application/octet-stream body_bytes=20093440 binary=yes cost_ms=582
|
||||||
|
[2026-04-14 18:39:42] REQ ip=127.0.0.1 method=GET path=/dps/download3/3_%E5%A4%9F%E9%92%9F:img.png query=- body_bytes=0 content_type=- auth=absent
|
||||||
|
[2026-04-14 18:39:42] RESP ip=127.0.0.1 method=GET path=/dps/download3/3_%E5%A4%9F%E9%92%9F:img.png status=200 content_type=image/png body_bytes=0 binary=no cost_ms=0
|
||||||
0
tmp-verify.out
Normal file
0
tmp-verify.out
Normal file
103
xmake.lua
Normal file
103
xmake.lua
Normal file
@@ -0,0 +1,103 @@
|
|||||||
|
set_project("dps_manager_server")
|
||||||
|
set_version("0.1.0")
|
||||||
|
set_languages("c11", "cxx17")
|
||||||
|
set_warnings("all", "error")
|
||||||
|
|
||||||
|
add_rules("mode.debug", "mode.release")
|
||||||
|
add_cxxflags("-Wno-deprecated-declarations", {tools = {"gcc", "clang"}})
|
||||||
|
add_requires("openssl3", "zlib", "mariadb-connector-c")
|
||||||
|
|
||||||
|
if is_plat("linux") then
|
||||||
|
add_syslinks("pthread")
|
||||||
|
elseif is_plat("mingw", "windows") then
|
||||||
|
add_defines("DPS_WINDOWS")
|
||||||
|
add_syslinks("ws2_32")
|
||||||
|
end
|
||||||
|
|
||||||
|
add_defines("OPENSSL_SUPPRESS_DEPRECATED")
|
||||||
|
|
||||||
|
target("dps_manager_server")
|
||||||
|
set_kind("binary")
|
||||||
|
add_includedirs("include")
|
||||||
|
add_includedirs("third_party/libbcrypt/crypt_blowfish")
|
||||||
|
add_packages("openssl3", "zlib", "mariadb-connector-c")
|
||||||
|
add_files("src/*.cpp")
|
||||||
|
add_files(
|
||||||
|
"third_party/libbcrypt/crypt_blowfish/wrapper.c",
|
||||||
|
"third_party/libbcrypt/crypt_blowfish/crypt_blowfish.c",
|
||||||
|
"third_party/libbcrypt/crypt_blowfish/crypt_gensalt.c",
|
||||||
|
{warnings = "none"}
|
||||||
|
)
|
||||||
|
add_headerfiles("include/(dps/*.hpp)")
|
||||||
|
after_build(function (target)
|
||||||
|
local project_config_dir = path.join(os.projectdir(), "config")
|
||||||
|
local output_config_dir = path.join(target:targetdir(), "config")
|
||||||
|
local config_files = {
|
||||||
|
"server.conf",
|
||||||
|
"server.conf.example",
|
||||||
|
"server.windows.conf"
|
||||||
|
}
|
||||||
|
|
||||||
|
os.mkdir(output_config_dir)
|
||||||
|
for _, config_file in ipairs(config_files) do
|
||||||
|
local source = path.join(project_config_dir, config_file)
|
||||||
|
if os.isfile(source) then
|
||||||
|
os.cp(source, path.join(output_config_dir, config_file))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not target:is_plat("windows") then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local pkg = target:pkg("mariadb-connector-c")
|
||||||
|
if not pkg then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local plugin_dir = path.join(pkg:installdir(), "lib", "mariadb", "plugin")
|
||||||
|
if os.isdir(plugin_dir) then
|
||||||
|
local output_dir = path.join(target:targetdir(), "mariadb-plugin")
|
||||||
|
if os.isfile(output_dir) then
|
||||||
|
os.rm(output_dir)
|
||||||
|
end
|
||||||
|
os.mkdir(output_dir)
|
||||||
|
os.cp(path.join(plugin_dir, "*.dll"), output_dir)
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
|
||||||
|
target("json_smoke_test")
|
||||||
|
set_kind("binary")
|
||||||
|
set_default(false)
|
||||||
|
add_includedirs("include")
|
||||||
|
add_files("tests/json_smoke_test.cpp", "src/json.cpp")
|
||||||
|
|
||||||
|
target("crypto_smoke_test")
|
||||||
|
set_kind("binary")
|
||||||
|
set_default(false)
|
||||||
|
add_includedirs("include")
|
||||||
|
add_includedirs("third_party/libbcrypt/crypt_blowfish")
|
||||||
|
add_packages("openssl3", "zlib", "mariadb-connector-c")
|
||||||
|
add_files(
|
||||||
|
"tests/crypto_smoke_test.cpp",
|
||||||
|
"src/app.cpp",
|
||||||
|
"src/config.cpp",
|
||||||
|
"src/fs_utils.cpp",
|
||||||
|
"src/http.cpp",
|
||||||
|
"src/json.cpp",
|
||||||
|
"src/labels.cpp",
|
||||||
|
"third_party/libbcrypt/crypt_blowfish/wrapper.c",
|
||||||
|
"third_party/libbcrypt/crypt_blowfish/crypt_blowfish.c",
|
||||||
|
"third_party/libbcrypt/crypt_blowfish/crypt_gensalt.c",
|
||||||
|
{warnings = "none"}
|
||||||
|
)
|
||||||
|
|
||||||
|
target("fs_utils_smoke_test")
|
||||||
|
set_kind("binary")
|
||||||
|
set_default(false)
|
||||||
|
add_includedirs("include")
|
||||||
|
add_files("tests/fs_utils_smoke_test.cpp", "src/fs_utils.cpp")
|
||||||
|
|
||||||
|
target("labels_smoke_test")
|
||||||
|
set_kind("binary")
|
||||||
|
set_default(false)
|
||||||
|
add_includedirs("include")
|
||||||
|
add_files("tests/labels_smoke_test.cpp", "src/labels.cpp")
|
||||||
33
旧的java项目/.gitignore
vendored
Normal file
33
旧的java项目/.gitignore
vendored
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
HELP.md
|
||||||
|
target/
|
||||||
|
!.mvn/wrapper/maven-wrapper.jar
|
||||||
|
!**/src/main/**/target/
|
||||||
|
!**/src/test/**/target/
|
||||||
|
|
||||||
|
### STS ###
|
||||||
|
.apt_generated
|
||||||
|
.classpath
|
||||||
|
.factorypath
|
||||||
|
.project
|
||||||
|
.settings
|
||||||
|
.springBeans
|
||||||
|
.sts4-cache
|
||||||
|
|
||||||
|
### IntelliJ IDEA ###
|
||||||
|
.idea
|
||||||
|
*.iws
|
||||||
|
*.iml
|
||||||
|
*.ipr
|
||||||
|
|
||||||
|
### NetBeans ###
|
||||||
|
/nbproject/private/
|
||||||
|
/nbbuild/
|
||||||
|
/dist/
|
||||||
|
/nbdist/
|
||||||
|
/.nb-gradle/
|
||||||
|
build/
|
||||||
|
!**/src/main/**/build/
|
||||||
|
!**/src/test/**/build/
|
||||||
|
|
||||||
|
### VS Code ###
|
||||||
|
.vscode/
|
||||||
BIN
旧的java项目/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
旧的java项目/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
2
旧的java项目/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
2
旧的java项目/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.8.3/apache-maven-3.8.3-bin.zip
|
||||||
|
wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar
|
||||||
120
旧的java项目/AGENTS.md
Normal file
120
旧的java项目/AGENTS.md
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
AGENTS.md for this repository
|
||||||
|
|
||||||
|
Purpose
|
||||||
|
- This document guides agent-like contributors (human or AI) on how to build, lint, test, and style the codebase.
|
||||||
|
- It also captures preferences or constraints used by the team and by automated agents operating in this repo.
|
||||||
|
|
||||||
|
Scope
|
||||||
|
- Build, test, and lint commands for common environments (Node/TS, Python, Go, Rust, Java).
|
||||||
|
- Code style guidelines: imports, formatting, types, naming, error handling, tests, and documentation.
|
||||||
|
- Cursor rules and Copilot rules inclusion if present in the repo.
|
||||||
|
- How to handle running a single test and how to extend tests locally.
|
||||||
|
|
||||||
|
1) Quick start: common commands
|
||||||
|
- Build (preferred entry point):
|
||||||
|
- Node/TypeScript: npm run build (or yarn build)
|
||||||
|
- Python: python -m build or your project-specific build script
|
||||||
|
- Go: go build ./...
|
||||||
|
- Rust: cargo build
|
||||||
|
- Lint:
|
||||||
|
- Node/TypeScript: npm run lint (or yarn lint)
|
||||||
|
- Python: ruff check . | flake8 or your project’s linter
|
||||||
|
- Go: golangci-lint run
|
||||||
|
- Rust: cargo clippy
|
||||||
|
- Test:
|
||||||
|
- Node/TS: npm test (or yarn test)
|
||||||
|
- Python: pytest
|
||||||
|
- Go: go test ./...
|
||||||
|
- Rust: cargo test
|
||||||
|
- Note: If your repo uses a mixed tech stack, prefer using the language-specific script in package.json or equivalent courier scripts.
|
||||||
|
|
||||||
|
2) Run a single test (typical patterns)
|
||||||
|
- Node / Jest
|
||||||
|
- Run a specific test by name: npm test -- -t "should render the component"
|
||||||
|
- Run a specific file: npm test -- path/to/file.test.js
|
||||||
|
- Python / Pytest
|
||||||
|
- Run tests matching a keyword: pytest -k "test_name_substring" -q
|
||||||
|
- Run a specific file: pytest tests/test_module.py -q
|
||||||
|
- Go
|
||||||
|
- Run a single test by name: go test -run TestName ./...
|
||||||
|
- Rust / Cargo
|
||||||
|
- Exact test: cargo test -- --exact TestName
|
||||||
|
- Run a file-like subset: cargo test -- 'pattern'
|
||||||
|
- Java / Maven or Gradle
|
||||||
|
- Maven: mvn -Dtest=MyTest#testMethod test
|
||||||
|
- Gradle: ./gradlew test --tests "com.example.MyTest.testMethod"
|
||||||
|
|
||||||
|
3) Code style guidelines
|
||||||
|
<A) Imports and modules>
|
||||||
|
- Group imports into three blocks: standard library, third-party, and first-party modules.
|
||||||
|
- Order blocks alphabetically within each group; separate blocks with a newline.
|
||||||
|
- Avoid wildcard imports; prefer explicit imports.
|
||||||
|
- For TS/JS, prefer absolute/alias imports over relative when it improves clarity.
|
||||||
|
|
||||||
|
<B) Formatting and tooling>
|
||||||
|
- Use the project’s formatter (Prettier, gofmt, black, etc.) with the configured settings.
|
||||||
|
- Respect the repository’s line length (commonly 100-120 chars). Break long lines at logical points.
|
||||||
|
- Use semicolons consistently if the project enforces them; otherwise adhere to the established style.
|
||||||
|
- Enable and respect lint rules; fix all autofixable issues during code edits.
|
||||||
|
|
||||||
|
<C) Types and APIs>
|
||||||
|
- In TypeScript, enable strict type checking; prefer interfaces for public APIs and type aliases for shapes.
|
||||||
|
- Use readonly modifiers where possible to express intent and optimize immutability guarantees.
|
||||||
|
- Prefer explicit return types for exported functions and public APIs.
|
||||||
|
- Avoid any where possible; if necessary, use unknown with proper checks.
|
||||||
|
|
||||||
|
<D) Naming conventions>
|
||||||
|
- Variables and functions: camelCase
|
||||||
|
- Classes and types: PascalCase
|
||||||
|
- Constants: UPPER_SNAKE_CASE
|
||||||
|
- File and module names: kebab-case or snake_case, consistent with project convention
|
||||||
|
|
||||||
|
<E) Error handling>
|
||||||
|
- Do not swallow errors; attach context when rethrowing (e.g., throw new Error(`Context: ${err.message}`)).
|
||||||
|
- Propagate errors to callers with meaningful messages.
|
||||||
|
- Use try/catch around IO-bound or network-bound operations and ensure resources are released in finally or via finally-like blocks.
|
||||||
|
|
||||||
|
<F) Async/Promises>
|
||||||
|
- Prefer async/await syntax for readability.
|
||||||
|
- Handle rejections at the call site when possible; avoid unhandled promises.
|
||||||
|
- Use Promise.all when performing independent async tasks, but catch and handle failures gracefully.
|
||||||
|
|
||||||
|
<G) Tests>
|
||||||
|
- Tests should be fast, deterministic, and hermetic.
|
||||||
|
- Use descriptive test names and structure (Arrange-Act-Assert patterns where helpful).
|
||||||
|
- Isolate external dependencies; mock/stub network/db calls effectively.
|
||||||
|
- Include tests for error paths and boundary conditions.
|
||||||
|
|
||||||
|
<H) Documentation and comments>
|
||||||
|
- Document non-obvious logic with concise comments; avoid obvious boilerplate.
|
||||||
|
- Public APIs should have JSDoc / TSdoc-style comments describing inputs, outputs, and side effects.
|
||||||
|
- Update or add READMEs where necessary to reflect changes in behavior.
|
||||||
|
|
||||||
|
<I) Security and compliance>
|
||||||
|
- Do not log sensitive data; mask secrets in logs.
|
||||||
|
- Validate inputs and sanitize outputs where appropriate.
|
||||||
|
- Treat untrusted data carefully; avoid code paths that execute untrusted input without validation.
|
||||||
|
|
||||||
|
4) Cursor and Copilot rules
|
||||||
|
- Cursor rules: If this repo uses Cursor tooling, its rules can live under .cursor/rules/ or .cursorrules. Copy or adapt them into this document when agents are created.
|
||||||
|
- Copilot rules: If there is .github/copilot-instructions.md, follow its guidance and ensure code generation adheres to the outlined constraints.
|
||||||
|
- If the repo contains these files, consider linking to them here and summarizing any special constraints applicable to agents.
|
||||||
|
|
||||||
|
5) Git workflow and contribution notes
|
||||||
|
- Do not modify dependencies without explicit approval.
|
||||||
|
- Keep commits small and focused; write 1-2 sentence messages describing why a change was made, not just what changed.
|
||||||
|
- For AGENTS.md updates, include a short rationale in the commit message.
|
||||||
|
- Prefer small, reviewed edits over sweeping rewrites.
|
||||||
|
|
||||||
|
6) Local integration guidance
|
||||||
|
- Run: npm install or yarn to install deps before building/tests.
|
||||||
|
- For multi-language repos, ensure the local environment has language runtimes and tooling installed (Node, Python, Go, Rust, etc.).
|
||||||
|
- Use a clean environment (e.g., nvm, virtualenv) to avoid cross-project contamination.
|
||||||
|
|
||||||
|
7) Example usage scenarios
|
||||||
|
- A single-file feature: create a minimal unit test, run npm test -- -t "feature X" to validate.
|
||||||
|
- A refactor: run lint and then a subset of tests; fix issues flagged by lints before merging.
|
||||||
|
- A CI-like dry run: run npm ci; npm run build; npm test; and report failures with minimal noise.
|
||||||
|
|
||||||
|
Notes
|
||||||
|
- If you want me to tailor this file to the exact repo, I can incorporate the actual existing AGENTS.md content (if present) or sync with Cursor/Copilot rules after inspecting the repo. Right now this is a solid, language-agnostic baseline.
|
||||||
41
旧的java项目/itcast/client/ChatClient.java
Normal file
41
旧的java项目/itcast/client/ChatClient.java
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package cn.itcast.client;
|
||||||
|
|
||||||
|
import cn.itcast.protocol.MessageCodecSharable;
|
||||||
|
import cn.itcast.protocol.ProcotolFrameDecoder;
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.handler.logging.LogLevel;
|
||||||
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ChatClient {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
NioEventLoopGroup group = new NioEventLoopGroup();
|
||||||
|
LoggingHandler LOGGING_HANDLER = new LoggingHandler(LogLevel.DEBUG);
|
||||||
|
MessageCodecSharable MESSAGE_CODEC = new MessageCodecSharable();
|
||||||
|
try {
|
||||||
|
Bootstrap bootstrap = new Bootstrap();
|
||||||
|
bootstrap.channel(NioSocketChannel.class);
|
||||||
|
bootstrap.group(group);
|
||||||
|
bootstrap.handler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
ch.pipeline().addLast(new ProcotolFrameDecoder());
|
||||||
|
ch.pipeline().addLast(LOGGING_HANDLER);
|
||||||
|
ch.pipeline().addLast(MESSAGE_CODEC);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Channel channel = bootstrap.connect("localhost", 9020).sync().channel();
|
||||||
|
channel.closeFuture().sync();
|
||||||
|
} catch (Exception e) {
|
||||||
|
// log.error("client error", e);
|
||||||
|
} finally {
|
||||||
|
group.shutdownGracefully();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
19
旧的java项目/itcast/message/AbstractResponseMessage.java
Normal file
19
旧的java项目/itcast/message/AbstractResponseMessage.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public abstract class AbstractResponseMessage extends Message {
|
||||||
|
private boolean success;
|
||||||
|
private String reason;
|
||||||
|
|
||||||
|
public AbstractResponseMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public AbstractResponseMessage(boolean success, String reason) {
|
||||||
|
this.success = success;
|
||||||
|
this.reason = reason;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
旧的java项目/itcast/message/ChatRequestMessage.java
Normal file
26
旧的java项目/itcast/message/ChatRequestMessage.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class ChatRequestMessage extends Message {
|
||||||
|
private String content;
|
||||||
|
private String to;
|
||||||
|
private String from;
|
||||||
|
|
||||||
|
public ChatRequestMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatRequestMessage(String from, String to, String content) {
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return ChatRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
旧的java项目/itcast/message/ChatResponseMessage.java
Normal file
26
旧的java项目/itcast/message/ChatResponseMessage.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class ChatResponseMessage extends AbstractResponseMessage {
|
||||||
|
|
||||||
|
private String from;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
public ChatResponseMessage(boolean success, String reason) {
|
||||||
|
super(success, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ChatResponseMessage(String from, String content) {
|
||||||
|
this.from = from;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return ChatResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
旧的java项目/itcast/message/GroupChatRequestMessage.java
Normal file
23
旧的java项目/itcast/message/GroupChatRequestMessage.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupChatRequestMessage extends Message {
|
||||||
|
private String content;
|
||||||
|
private String groupName;
|
||||||
|
private String from;
|
||||||
|
|
||||||
|
public GroupChatRequestMessage(String from, String groupName, String content) {
|
||||||
|
this.content = content;
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.from = from;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupChatRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
24
旧的java项目/itcast/message/GroupChatResponseMessage.java
Normal file
24
旧的java项目/itcast/message/GroupChatResponseMessage.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupChatResponseMessage extends AbstractResponseMessage {
|
||||||
|
private String from;
|
||||||
|
private String content;
|
||||||
|
|
||||||
|
public GroupChatResponseMessage(boolean success, String reason) {
|
||||||
|
super(success, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GroupChatResponseMessage(String from, String content) {
|
||||||
|
this.from = from;
|
||||||
|
this.content = content;
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupChatResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
23
旧的java项目/itcast/message/GroupCreateRequestMessage.java
Normal file
23
旧的java项目/itcast/message/GroupCreateRequestMessage.java
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupCreateRequestMessage extends Message {
|
||||||
|
private String groupName;
|
||||||
|
private Set<String> members;
|
||||||
|
|
||||||
|
public GroupCreateRequestMessage(String groupName, Set<String> members) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.members = members;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupCreateRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
旧的java项目/itcast/message/GroupCreateResponseMessage.java
Normal file
18
旧的java项目/itcast/message/GroupCreateResponseMessage.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupCreateResponseMessage extends AbstractResponseMessage {
|
||||||
|
|
||||||
|
public GroupCreateResponseMessage(boolean success, String reason) {
|
||||||
|
super(success, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupCreateResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
旧的java项目/itcast/message/GroupJoinRequestMessage.java
Normal file
22
旧的java项目/itcast/message/GroupJoinRequestMessage.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupJoinRequestMessage extends Message {
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
public GroupJoinRequestMessage(String username, String groupName) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupJoinRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
18
旧的java项目/itcast/message/GroupJoinResponseMessage.java
Normal file
18
旧的java项目/itcast/message/GroupJoinResponseMessage.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupJoinResponseMessage extends AbstractResponseMessage {
|
||||||
|
|
||||||
|
public GroupJoinResponseMessage(boolean success, String reason) {
|
||||||
|
super(success, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupJoinResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
旧的java项目/itcast/message/GroupMembersRequestMessage.java
Normal file
19
旧的java项目/itcast/message/GroupMembersRequestMessage.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupMembersRequestMessage extends Message {
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
public GroupMembersRequestMessage(String groupName) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupMembersRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
旧的java项目/itcast/message/GroupMembersResponseMessage.java
Normal file
22
旧的java项目/itcast/message/GroupMembersResponseMessage.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupMembersResponseMessage extends Message {
|
||||||
|
|
||||||
|
private Set<String> members;
|
||||||
|
|
||||||
|
public GroupMembersResponseMessage(Set<String> members) {
|
||||||
|
this.members = members;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupMembersResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
22
旧的java项目/itcast/message/GroupQuitRequestMessage.java
Normal file
22
旧的java项目/itcast/message/GroupQuitRequestMessage.java
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupQuitRequestMessage extends Message {
|
||||||
|
private String groupName;
|
||||||
|
|
||||||
|
private String username;
|
||||||
|
|
||||||
|
public GroupQuitRequestMessage(String username, String groupName) {
|
||||||
|
this.groupName = groupName;
|
||||||
|
this.username = username;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupQuitRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
17
旧的java项目/itcast/message/GroupQuitResponseMessage.java
Normal file
17
旧的java项目/itcast/message/GroupQuitResponseMessage.java
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class GroupQuitResponseMessage extends AbstractResponseMessage {
|
||||||
|
public GroupQuitResponseMessage(boolean success, String reason) {
|
||||||
|
super(success, reason);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return GroupQuitResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
26
旧的java项目/itcast/message/LoginRequestMessage.java
Normal file
26
旧的java项目/itcast/message/LoginRequestMessage.java
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class LoginRequestMessage extends Message {
|
||||||
|
private String username;
|
||||||
|
private String password;
|
||||||
|
private String nickname;
|
||||||
|
|
||||||
|
public LoginRequestMessage() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public LoginRequestMessage(String username, String password, String nickname) {
|
||||||
|
this.username = username;
|
||||||
|
this.password = password;
|
||||||
|
this.nickname = nickname;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return LoginRequestMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
13
旧的java项目/itcast/message/LoginResponseMessage.java
Normal file
13
旧的java项目/itcast/message/LoginResponseMessage.java
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.ToString;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@ToString(callSuper = true)
|
||||||
|
public class LoginResponseMessage extends AbstractResponseMessage {
|
||||||
|
@Override
|
||||||
|
public int getMessageType() {
|
||||||
|
return LoginResponseMessage;
|
||||||
|
}
|
||||||
|
}
|
||||||
54
旧的java项目/itcast/message/Message.java
Normal file
54
旧的java项目/itcast/message/Message.java
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
package cn.itcast.message;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public abstract class Message implements Serializable {
|
||||||
|
|
||||||
|
public static Class<?> getMessageClass(int messageType) {
|
||||||
|
return messageClasses.get(messageType);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int sequenceId;
|
||||||
|
|
||||||
|
private int messageType;
|
||||||
|
|
||||||
|
public abstract int getMessageType();
|
||||||
|
|
||||||
|
public static final int LoginRequestMessage = 0;
|
||||||
|
public static final int LoginResponseMessage = 1;
|
||||||
|
public static final int ChatRequestMessage = 2;
|
||||||
|
public static final int ChatResponseMessage = 3;
|
||||||
|
public static final int GroupCreateRequestMessage = 4;
|
||||||
|
public static final int GroupCreateResponseMessage = 5;
|
||||||
|
public static final int GroupJoinRequestMessage = 6;
|
||||||
|
public static final int GroupJoinResponseMessage = 7;
|
||||||
|
public static final int GroupQuitRequestMessage = 8;
|
||||||
|
public static final int GroupQuitResponseMessage = 9;
|
||||||
|
public static final int GroupChatRequestMessage = 10;
|
||||||
|
public static final int GroupChatResponseMessage = 11;
|
||||||
|
public static final int GroupMembersRequestMessage = 12;
|
||||||
|
public static final int GroupMembersResponseMessage = 13;
|
||||||
|
private static final Map<Integer, Class<?>> messageClasses = new HashMap<>();
|
||||||
|
|
||||||
|
static {
|
||||||
|
messageClasses.put(LoginRequestMessage, LoginRequestMessage.class);
|
||||||
|
messageClasses.put(LoginResponseMessage, LoginResponseMessage.class);
|
||||||
|
messageClasses.put(ChatRequestMessage, ChatRequestMessage.class);
|
||||||
|
messageClasses.put(ChatResponseMessage, ChatResponseMessage.class);
|
||||||
|
messageClasses.put(GroupCreateRequestMessage, GroupCreateRequestMessage.class);
|
||||||
|
messageClasses.put(GroupCreateResponseMessage, GroupCreateResponseMessage.class);
|
||||||
|
messageClasses.put(GroupJoinRequestMessage, GroupJoinRequestMessage.class);
|
||||||
|
messageClasses.put(GroupJoinResponseMessage, GroupJoinResponseMessage.class);
|
||||||
|
messageClasses.put(GroupQuitRequestMessage, GroupQuitRequestMessage.class);
|
||||||
|
messageClasses.put(GroupQuitResponseMessage, GroupQuitResponseMessage.class);
|
||||||
|
messageClasses.put(GroupChatRequestMessage, GroupChatRequestMessage.class);
|
||||||
|
messageClasses.put(GroupChatResponseMessage, GroupChatResponseMessage.class);
|
||||||
|
messageClasses.put(GroupMembersRequestMessage, GroupMembersRequestMessage.class);
|
||||||
|
messageClasses.put(GroupMembersResponseMessage, GroupMembersResponseMessage.class);
|
||||||
|
}
|
||||||
|
}
|
||||||
62
旧的java项目/itcast/protocol/MessageCodec.java
Normal file
62
旧的java项目/itcast/protocol/MessageCodec.java
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
package cn.itcast.protocol;
|
||||||
|
|
||||||
|
import cn.itcast.message.Message;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.ByteToMessageCodec;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
public class MessageCodec extends ByteToMessageCodec<Message> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
|
||||||
|
// // 1. 4 字节的魔数
|
||||||
|
// out.writeBytes(new byte[]{1, 2, 3, 4});
|
||||||
|
// // 2. 1 字节的版本,
|
||||||
|
// out.writeByte(1);
|
||||||
|
// // 3. 1 字节的序列化方式 jdk 0 , json 1
|
||||||
|
// out.writeByte(0);
|
||||||
|
// // 4. 1 字节的指令类型
|
||||||
|
// out.writeByte(msg.getMessageType());
|
||||||
|
// // 5. 4 个字节
|
||||||
|
//// out.writeInt(msg.getSequenceId());
|
||||||
|
// // 无意义,对齐填充
|
||||||
|
// out.writeByte(0xff);
|
||||||
|
// // 6. 获取内容的字节数组
|
||||||
|
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
// ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||||
|
// oos.writeObject(msg);
|
||||||
|
// byte[] bytes = bos.toByteArray();
|
||||||
|
// // 7. 长度
|
||||||
|
// out.writeInt(bytes.length);
|
||||||
|
// // 8. 写入内容
|
||||||
|
// out.writeBytes(bytes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
|
int magicNum = in.readInt();
|
||||||
|
byte version = in.readByte();
|
||||||
|
byte serializerType = in.readByte();
|
||||||
|
byte messageType = in.readByte();
|
||||||
|
int sequenceId = in.readInt();
|
||||||
|
in.readByte();
|
||||||
|
int length = in.readInt();
|
||||||
|
byte[] bytes = new byte[length];
|
||||||
|
in.readBytes(bytes, 0, length);
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
|
||||||
|
Message message = (Message) ois.readObject();
|
||||||
|
// log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
|
||||||
|
// log.debug("{}", message);
|
||||||
|
out.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
66
旧的java项目/itcast/protocol/MessageCodecSharable.java
Normal file
66
旧的java项目/itcast/protocol/MessageCodecSharable.java
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
package cn.itcast.protocol;
|
||||||
|
|
||||||
|
import cn.itcast.message.Message;
|
||||||
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.channel.ChannelHandler;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.handler.codec.MessageToMessageCodec;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
@ChannelHandler.Sharable
|
||||||
|
/**
|
||||||
|
* 必须和 LengthFieldBasedFrameDecoder 一起使用,确保接到的 ByteBuf 消息是完整的
|
||||||
|
*/
|
||||||
|
public class MessageCodecSharable extends MessageToMessageCodec<ByteBuf, Message> {
|
||||||
|
@Override
|
||||||
|
protected void encode(ChannelHandlerContext ctx, Message msg, List<Object> outList) throws Exception {
|
||||||
|
// ByteBuf out = ctx.alloc().buffer();
|
||||||
|
// // 1. 4 字节的魔数
|
||||||
|
// out.writeBytes(new byte[]{1, 2, 3, 4});
|
||||||
|
// // 2. 1 字节的版本,
|
||||||
|
// out.writeByte(1);
|
||||||
|
// // 3. 1 字节的序列化方式 jdk 0 , json 1
|
||||||
|
// out.writeByte(0);
|
||||||
|
// // 4. 1 字节的指令类型
|
||||||
|
// out.writeByte(msg.getMessageType());
|
||||||
|
// // 5. 4 个字节
|
||||||
|
// out.writeInt(msg.getSequenceId());
|
||||||
|
// // 无意义,对齐填充
|
||||||
|
// out.writeByte(0xff);
|
||||||
|
// // 6. 获取内容的字节数组
|
||||||
|
// ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||||
|
// ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||||
|
// oos.writeObject(msg);
|
||||||
|
// byte[] bytes = bos.toByteArray();
|
||||||
|
// // 7. 长度
|
||||||
|
// out.writeInt(bytes.length);
|
||||||
|
// // 8. 写入内容
|
||||||
|
// out.writeBytes(bytes);
|
||||||
|
// outList.add(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
|
||||||
|
int magicNum = in.readInt();
|
||||||
|
byte version = in.readByte();
|
||||||
|
byte serializerType = in.readByte();
|
||||||
|
byte messageType = in.readByte();
|
||||||
|
int sequenceId = in.readInt();
|
||||||
|
in.readByte();
|
||||||
|
int length = in.readInt();
|
||||||
|
byte[] bytes = new byte[length];
|
||||||
|
in.readBytes(bytes, 0, length);
|
||||||
|
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes));
|
||||||
|
Message message = (Message) ois.readObject();
|
||||||
|
// log.debug("{}, {}, {}, {}, {}, {}", magicNum, version, serializerType, messageType, sequenceId, length);
|
||||||
|
// log.debug("{}", message);
|
||||||
|
out.add(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
14
旧的java项目/itcast/protocol/ProcotolFrameDecoder.java
Normal file
14
旧的java项目/itcast/protocol/ProcotolFrameDecoder.java
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
package cn.itcast.protocol;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||||
|
|
||||||
|
public class ProcotolFrameDecoder extends LengthFieldBasedFrameDecoder {
|
||||||
|
|
||||||
|
public ProcotolFrameDecoder() {
|
||||||
|
this(1024, 12, 4, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ProcotolFrameDecoder(int maxFrameLength, int lengthFieldOffset, int lengthFieldLength, int lengthAdjustment, int initialBytesToStrip) {
|
||||||
|
super(maxFrameLength, lengthFieldOffset, lengthFieldLength, lengthAdjustment, initialBytesToStrip);
|
||||||
|
}
|
||||||
|
}
|
||||||
44
旧的java项目/itcast/server/ChatServer.java
Normal file
44
旧的java项目/itcast/server/ChatServer.java
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
package cn.itcast.server;
|
||||||
|
|
||||||
|
import cn.itcast.protocol.MessageCodecSharable;
|
||||||
|
import cn.itcast.protocol.ProcotolFrameDecoder;
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.SocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
|
||||||
|
import io.netty.handler.logging.LogLevel;
|
||||||
|
import io.netty.handler.logging.LoggingHandler;
|
||||||
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
|
@Slf4j
|
||||||
|
public class ChatServer {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
NioEventLoopGroup boss = new NioEventLoopGroup();
|
||||||
|
NioEventLoopGroup worker = new NioEventLoopGroup();
|
||||||
|
LoggingHandler LOGGING_HANDLER = new LoggingHandler(LogLevel.DEBUG);
|
||||||
|
MessageCodecSharable MESSAGE_CODEC = new MessageCodecSharable();
|
||||||
|
try {
|
||||||
|
ServerBootstrap serverBootstrap = new ServerBootstrap();
|
||||||
|
serverBootstrap.channel(NioServerSocketChannel.class);
|
||||||
|
serverBootstrap.group(boss, worker);
|
||||||
|
serverBootstrap.childHandler(new ChannelInitializer<SocketChannel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(SocketChannel ch) throws Exception {
|
||||||
|
ch.pipeline().addLast(new ProcotolFrameDecoder());
|
||||||
|
ch.pipeline().addLast(LOGGING_HANDLER);
|
||||||
|
ch.pipeline().addLast(MESSAGE_CODEC);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
Channel channel = serverBootstrap.bind(9020).sync().channel();
|
||||||
|
channel.closeFuture().sync();
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
// log.error("server error", e);
|
||||||
|
} finally {
|
||||||
|
boss.shutdownGracefully();
|
||||||
|
worker.shutdownGracefully();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
旧的java项目/itcast/server/service/UserService.java
Normal file
15
旧的java项目/itcast/server/service/UserService.java
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
package cn.itcast.server.service;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 用户管理接口
|
||||||
|
*/
|
||||||
|
public interface UserService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 登录
|
||||||
|
* @param username 用户名
|
||||||
|
* @param password 密码
|
||||||
|
* @return 登录成功返回 true, 否则返回 false
|
||||||
|
*/
|
||||||
|
boolean login(String username, String password);
|
||||||
|
}
|
||||||
10
旧的java项目/itcast/server/service/UserServiceFactory.java
Normal file
10
旧的java项目/itcast/server/service/UserServiceFactory.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package cn.itcast.server.service;
|
||||||
|
|
||||||
|
public abstract class UserServiceFactory {
|
||||||
|
|
||||||
|
private static UserService userService = new UserServiceMemoryImpl();
|
||||||
|
|
||||||
|
public static UserService getUserService() {
|
||||||
|
return userService;
|
||||||
|
}
|
||||||
|
}
|
||||||
25
旧的java项目/itcast/server/service/UserServiceMemoryImpl.java
Normal file
25
旧的java项目/itcast/server/service/UserServiceMemoryImpl.java
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
package cn.itcast.server.service;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class UserServiceMemoryImpl implements UserService {
|
||||||
|
private Map<String, String> allUserMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
{
|
||||||
|
allUserMap.put("zhangsan", "123");
|
||||||
|
allUserMap.put("lisi", "123");
|
||||||
|
allUserMap.put("wangwu", "123");
|
||||||
|
allUserMap.put("zhaoliu", "123");
|
||||||
|
allUserMap.put("qianqi", "123");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean login(String username, String password) {
|
||||||
|
String pass = allUserMap.get(username);
|
||||||
|
if (pass == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return pass.equals(password);
|
||||||
|
}
|
||||||
|
}
|
||||||
24
旧的java项目/itcast/server/session/Group.java
Normal file
24
旧的java项目/itcast/server/session/Group.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
/**
|
||||||
|
* 聊天组,即聊天室
|
||||||
|
*/
|
||||||
|
public class Group {
|
||||||
|
// 聊天室名称
|
||||||
|
private String name;
|
||||||
|
// 聊天室成员
|
||||||
|
private Set<String> members;
|
||||||
|
|
||||||
|
public static final Group EMPTY_GROUP = new Group("empty", Collections.emptySet());
|
||||||
|
|
||||||
|
public Group(String name, Set<String> members) {
|
||||||
|
this.name = name;
|
||||||
|
this.members = members;
|
||||||
|
}
|
||||||
|
}
|
||||||
57
旧的java项目/itcast/server/session/GroupSession.java
Normal file
57
旧的java项目/itcast/server/session/GroupSession.java
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 聊天组会话管理接口
|
||||||
|
*/
|
||||||
|
public interface GroupSession {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 创建一个聊天组, 如果不存在才能创建成功, 否则返回 null
|
||||||
|
* @param name 组名
|
||||||
|
* @param members 成员
|
||||||
|
* @return 成功时返回组对象, 失败返回 null
|
||||||
|
*/
|
||||||
|
Group createGroup(String name, Set<String> members);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加入聊天组
|
||||||
|
* @param name 组名
|
||||||
|
* @param member 成员名
|
||||||
|
* @return 如果组不存在返回 null, 否则返回组对象
|
||||||
|
*/
|
||||||
|
Group joinMember(String name, String member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除组成员
|
||||||
|
* @param name 组名
|
||||||
|
* @param member 成员名
|
||||||
|
* @return 如果组不存在返回 null, 否则返回组对象
|
||||||
|
*/
|
||||||
|
Group removeMember(String name, String member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 移除聊天组
|
||||||
|
* @param name 组名
|
||||||
|
* @return 如果组不存在返回 null, 否则返回组对象
|
||||||
|
*/
|
||||||
|
Group removeGroup(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组成员
|
||||||
|
* @param name 组名
|
||||||
|
* @return 成员集合, 没有成员会返回 empty set
|
||||||
|
*/
|
||||||
|
Set<String> getMembers(String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取组成员的 channel 集合, 只有在线的 channel 才会返回
|
||||||
|
* @param name 组名
|
||||||
|
* @return 成员 channel 集合
|
||||||
|
*/
|
||||||
|
List<Channel> getMembersChannel(String name);
|
||||||
|
}
|
||||||
10
旧的java项目/itcast/server/session/GroupSessionFactory.java
Normal file
10
旧的java项目/itcast/server/session/GroupSessionFactory.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
public abstract class GroupSessionFactory {
|
||||||
|
|
||||||
|
private static GroupSession session = new GroupSessionMemoryImpl();
|
||||||
|
|
||||||
|
public static GroupSession getGroupSession() {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
}
|
||||||
55
旧的java项目/itcast/server/session/GroupSessionMemoryImpl.java
Normal file
55
旧的java项目/itcast/server/session/GroupSessionMemoryImpl.java
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class GroupSessionMemoryImpl implements GroupSession {
|
||||||
|
private final Map<String, Group> groupMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Group createGroup(String name, Set<String> members) {
|
||||||
|
Group group = new Group(name, members);
|
||||||
|
return groupMap.putIfAbsent(name, group);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Group joinMember(String name, String member) {
|
||||||
|
return groupMap.computeIfPresent(name, (key, value) -> {
|
||||||
|
// value.getMembers().add(member);
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Group removeMember(String name, String member) {
|
||||||
|
return groupMap.computeIfPresent(name, (key, value) -> {
|
||||||
|
// value.getMembers().remove(member);
|
||||||
|
return value;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Group removeGroup(String name) {
|
||||||
|
return groupMap.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Set<String> getMembers(String name) {
|
||||||
|
// return groupMap.getOrDefault(name, Group.EMPTY_GROUP).getMembers();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<Channel> getMembersChannel(String name) {
|
||||||
|
return getMembers(name).stream()
|
||||||
|
.map(member -> SessionFactory.getSession().getChannel(member))
|
||||||
|
.filter(Objects::nonNull)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
}
|
||||||
46
旧的java项目/itcast/server/session/Session.java
Normal file
46
旧的java项目/itcast/server/session/Session.java
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 会话管理接口
|
||||||
|
*/
|
||||||
|
public interface Session {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 绑定会话
|
||||||
|
* @param channel 哪个 channel 要绑定会话
|
||||||
|
* @param username 会话绑定用户
|
||||||
|
*/
|
||||||
|
void bind(Channel channel, String username);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解绑会话
|
||||||
|
* @param channel 哪个 channel 要解绑会话
|
||||||
|
*/
|
||||||
|
void unbind(Channel channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取属性
|
||||||
|
* @param channel 哪个 channel
|
||||||
|
* @param name 属性名
|
||||||
|
* @return 属性值
|
||||||
|
*/
|
||||||
|
Object getAttribute(Channel channel, String name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置属性
|
||||||
|
* @param channel 哪个 channel
|
||||||
|
* @param name 属性名
|
||||||
|
* @param value 属性值
|
||||||
|
*/
|
||||||
|
void setAttribute(Channel channel, String name, Object value);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据用户名获取 channel
|
||||||
|
* @param username 用户名
|
||||||
|
* @return channel
|
||||||
|
*/
|
||||||
|
Channel getChannel(String username);
|
||||||
|
}
|
||||||
10
旧的java项目/itcast/server/session/SessionFactory.java
Normal file
10
旧的java项目/itcast/server/session/SessionFactory.java
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
public abstract class SessionFactory {
|
||||||
|
|
||||||
|
private static Session session = new SessionMemoryImpl();
|
||||||
|
|
||||||
|
public static Session getSession() {
|
||||||
|
return session;
|
||||||
|
}
|
||||||
|
}
|
||||||
47
旧的java项目/itcast/server/session/SessionMemoryImpl.java
Normal file
47
旧的java项目/itcast/server/session/SessionMemoryImpl.java
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
package cn.itcast.server.session;
|
||||||
|
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class SessionMemoryImpl implements Session {
|
||||||
|
|
||||||
|
private final Map<String, Channel> usernameChannelMap = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Channel, String> channelUsernameMap = new ConcurrentHashMap<>();
|
||||||
|
private final Map<Channel,Map<String,Object>> channelAttributesMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void bind(Channel channel, String username) {
|
||||||
|
usernameChannelMap.put(username, channel);
|
||||||
|
channelUsernameMap.put(channel, username);
|
||||||
|
channelAttributesMap.put(channel, new ConcurrentHashMap<>());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unbind(Channel channel) {
|
||||||
|
String username = channelUsernameMap.remove(channel);
|
||||||
|
usernameChannelMap.remove(username);
|
||||||
|
channelAttributesMap.remove(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getAttribute(Channel channel, String name) {
|
||||||
|
return channelAttributesMap.get(channel).get(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setAttribute(Channel channel, String name, Object value) {
|
||||||
|
channelAttributesMap.get(channel).put(name, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Channel getChannel(String username) {
|
||||||
|
return usernameChannelMap.get(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return usernameChannelMap.toString();
|
||||||
|
}
|
||||||
|
}
|
||||||
316
旧的java项目/mvnw
vendored
Normal file
316
旧的java项目/mvnw
vendored
Normal file
@@ -0,0 +1,316 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Maven Start Up Batch script
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# M2_HOME - location of maven2's installed home dir
|
||||||
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
# e.g. to debug Maven itself, use
|
||||||
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||||
|
|
||||||
|
if [ -f /usr/local/etc/mavenrc ] ; then
|
||||||
|
. /usr/local/etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f /etc/mavenrc ] ; then
|
||||||
|
. /etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME/.mavenrc" ] ; then
|
||||||
|
. "$HOME/.mavenrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS specific support. $var _must_ be set to either true or false.
|
||||||
|
cygwin=false;
|
||||||
|
darwin=false;
|
||||||
|
mingw=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN*) cygwin=true ;;
|
||||||
|
MINGW*) mingw=true;;
|
||||||
|
Darwin*) darwin=true
|
||||||
|
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||||
|
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
if [ -x "/usr/libexec/java_home" ]; then
|
||||||
|
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||||
|
else
|
||||||
|
export JAVA_HOME="/Library/Java/Home"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
|
JAVA_HOME=`java-config --jre-home`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$M2_HOME" ] ; then
|
||||||
|
## resolve links - $0 may be a link to maven's home
|
||||||
|
PRG="$0"
|
||||||
|
|
||||||
|
# need this for relative symlinks
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG="`dirname "$PRG"`/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
saveddir=`pwd`
|
||||||
|
|
||||||
|
M2_HOME=`dirname "$PRG"`/..
|
||||||
|
|
||||||
|
# make it fully qualified
|
||||||
|
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||||
|
|
||||||
|
cd "$saveddir"
|
||||||
|
# echo Using m2 at $M2_HOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $mingw ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
javaExecutable="`which javac`"
|
||||||
|
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||||
|
# readlink(1) is not available as standard on Solaris 10.
|
||||||
|
readLink=`which readlink`
|
||||||
|
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||||
|
if $darwin ; then
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||||
|
else
|
||||||
|
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||||
|
fi
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||||
|
JAVA_HOME="$javaHome"
|
||||||
|
export JAVA_HOME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="`\\unset -f command; \\command -v java`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||||
|
echo " We cannot execute $JAVACMD" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
echo "Warning: JAVA_HOME environment variable is not set."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||||
|
|
||||||
|
# traverses directory structure from process work directory to filesystem root
|
||||||
|
# first directory with .mvn subdirectory is considered project base directory
|
||||||
|
find_maven_basedir() {
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "Path not specified to find_maven_basedir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
basedir="$1"
|
||||||
|
wdir="$1"
|
||||||
|
while [ "$wdir" != '/' ] ; do
|
||||||
|
if [ -d "$wdir"/.mvn ] ; then
|
||||||
|
basedir=$wdir
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||||
|
if [ -d "${wdir}" ]; then
|
||||||
|
wdir=`cd "$wdir/.."; pwd`
|
||||||
|
fi
|
||||||
|
# end of workaround
|
||||||
|
done
|
||||||
|
echo "${basedir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# concatenates all lines of a file
|
||||||
|
concat_lines() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo "$(tr -s '\n' ' ' < "$1")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||||
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
##########################################################################################
|
||||||
|
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||||
|
fi
|
||||||
|
if [ -n "$MVNW_REPOURL" ]; then
|
||||||
|
jarUrl="$MVNW_REPOURL/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||||
|
else
|
||||||
|
jarUrl="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||||
|
fi
|
||||||
|
while IFS="=" read key value; do
|
||||||
|
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||||
|
esac
|
||||||
|
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Downloading from: $jarUrl"
|
||||||
|
fi
|
||||||
|
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||||
|
if $cygwin; then
|
||||||
|
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
if command -v wget > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found wget ... using wget"
|
||||||
|
fi
|
||||||
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||||
|
wget "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||||
|
else
|
||||||
|
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" || rm -f "$wrapperJarPath"
|
||||||
|
fi
|
||||||
|
elif command -v curl > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found curl ... using curl"
|
||||||
|
fi
|
||||||
|
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||||
|
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||||
|
else
|
||||||
|
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||||
|
fi
|
||||||
|
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Falling back to using Java to download"
|
||||||
|
fi
|
||||||
|
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||||
|
# For Cygwin, switch paths to Windows format before running javac
|
||||||
|
if $cygwin; then
|
||||||
|
javaClass=`cygpath --path --windows "$javaClass"`
|
||||||
|
fi
|
||||||
|
if [ -e "$javaClass" ]; then
|
||||||
|
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
# Compiling the Java class
|
||||||
|
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||||
|
fi
|
||||||
|
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
# Running the downloader
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Running MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
##########################################################################################
|
||||||
|
# End of extension
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo $MAVEN_PROJECTBASEDIR
|
||||||
|
fi
|
||||||
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||||
|
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||||
|
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Provide a "standardized" way to retrieve the CLI args that will
|
||||||
|
# work with both Windows and non-Windows executions.
|
||||||
|
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||||
|
export MAVEN_CMD_LINE_ARGS
|
||||||
|
|
||||||
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
exec "$JAVACMD" \
|
||||||
|
$MAVEN_OPTS \
|
||||||
|
$MAVEN_DEBUG_OPTS \
|
||||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
|
"-Dmaven.home=${M2_HOME}" \
|
||||||
|
"-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||||
188
旧的java项目/mvnw.cmd
vendored
Normal file
188
旧的java项目/mvnw.cmd
vendored
Normal file
@@ -0,0 +1,188 @@
|
|||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Maven Start Up Batch script
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM M2_HOME - location of maven2's installed home dir
|
||||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@REM e.g. to debug Maven itself, use
|
||||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||||
|
@echo off
|
||||||
|
@REM set title of command window
|
||||||
|
title %0
|
||||||
|
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||||
|
|
||||||
|
@REM set %HOME% to equivalent of $HOME
|
||||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
|
||||||
|
@REM Execute a user defined script before this one
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%USERPROFILE%\mavenrc_pre.bat" call "%USERPROFILE%\mavenrc_pre.bat" %*
|
||||||
|
if exist "%USERPROFILE%\mavenrc_pre.cmd" call "%USERPROFILE%\mavenrc_pre.cmd" %*
|
||||||
|
:skipRcPre
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set ERROR_CODE=0
|
||||||
|
|
||||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
@REM ==== START VALIDATION ====
|
||||||
|
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME not found in your environment. >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
:OkJHome
|
||||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
@REM ==== END VALIDATION ====
|
||||||
|
|
||||||
|
:init
|
||||||
|
|
||||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||||
|
@REM Fallback to current working directory if not found.
|
||||||
|
|
||||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||||
|
|
||||||
|
set EXEC_DIR=%CD%
|
||||||
|
set WDIR=%EXEC_DIR%
|
||||||
|
:findBaseDir
|
||||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||||
|
cd ..
|
||||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||||
|
set WDIR=%CD%
|
||||||
|
goto findBaseDir
|
||||||
|
|
||||||
|
:baseDirFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
goto endDetectBaseDir
|
||||||
|
|
||||||
|
:baseDirNotFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
|
||||||
|
:endDetectBaseDir
|
||||||
|
|
||||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||||
|
|
||||||
|
@setlocal EnableExtensions EnableDelayedExpansion
|
||||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||||
|
|
||||||
|
:endReadAdditionalConfig
|
||||||
|
|
||||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||||
|
|
||||||
|
FOR /F "usebackq tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||||
|
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
if exist %WRAPPER_JAR% (
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Found %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
) else (
|
||||||
|
if not "%MVNW_REPOURL%" == "" (
|
||||||
|
SET DOWNLOAD_URL="%MVNW_REPOURL%/org/apache/maven/wrapper/maven-wrapper/3.1.0/maven-wrapper-3.1.0.jar"
|
||||||
|
)
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
|
echo Downloading from: %DOWNLOAD_URL%
|
||||||
|
)
|
||||||
|
|
||||||
|
powershell -Command "&{"^
|
||||||
|
"$webclient = new-object System.Net.WebClient;"^
|
||||||
|
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||||
|
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||||
|
"}"^
|
||||||
|
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||||
|
"}"
|
||||||
|
if "%MVNW_VERBOSE%" == "true" (
|
||||||
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
)
|
||||||
|
@REM End of extension
|
||||||
|
|
||||||
|
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||||
|
@REM work with both Windows and non-Windows executions.
|
||||||
|
set MAVEN_CMD_LINE_ARGS=%*
|
||||||
|
|
||||||
|
%MAVEN_JAVA_EXE% ^
|
||||||
|
%JVM_CONFIG_MAVEN_PROPS% ^
|
||||||
|
%MAVEN_OPTS% ^
|
||||||
|
%MAVEN_DEBUG_OPTS% ^
|
||||||
|
-classpath %WRAPPER_JAR% ^
|
||||||
|
"-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" ^
|
||||||
|
%WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:error
|
||||||
|
set ERROR_CODE=1
|
||||||
|
|
||||||
|
:end
|
||||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||||
|
|
||||||
|
if not "%MAVEN_SKIP_RC%"=="" goto skipRcPost
|
||||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%USERPROFILE%\mavenrc_post.bat" call "%USERPROFILE%\mavenrc_post.bat"
|
||||||
|
if exist "%USERPROFILE%\mavenrc_post.cmd" call "%USERPROFILE%\mavenrc_post.cmd"
|
||||||
|
:skipRcPost
|
||||||
|
|
||||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||||
|
if "%MAVEN_BATCH_PAUSE%"=="on" pause
|
||||||
|
|
||||||
|
if "%MAVEN_TERMINATE_CMD%"=="on" exit %ERROR_CODE%
|
||||||
|
|
||||||
|
cmd /C exit /B %ERROR_CODE%
|
||||||
134
旧的java项目/pom.xml
Normal file
134
旧的java项目/pom.xml
Normal file
@@ -0,0 +1,134 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.7.6</version>
|
||||||
|
<relativePath/> <!-- lookup parent from repository -->
|
||||||
|
</parent>
|
||||||
|
<groupId>com.example</groupId>
|
||||||
|
<artifactId>sjkbf</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<name>sjkbf</name>
|
||||||
|
<description>Demo project for Spring Boot</description>
|
||||||
|
<properties>
|
||||||
|
<java.version>1.8</java.version>
|
||||||
|
</properties>
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-java</artifactId>
|
||||||
|
<version>8.0.16</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.coobird</groupId>
|
||||||
|
<artifactId>thumbnailator</artifactId>
|
||||||
|
<version>0.4.14</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-boot-starter</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- MyBatis-Plus Generator(改用官方版本) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>mybatis-plus-generator</artifactId>
|
||||||
|
<version>3.4.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- freemarker 模板引擎(没有用原生的模板引擎)-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.freemarker</groupId>
|
||||||
|
<artifactId>freemarker</artifactId>
|
||||||
|
<version>2.3.31</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
<version>5.7.16</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
|
||||||
|
<version>3.5.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- JWT-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-api</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-impl</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.jsonwebtoken</groupId>
|
||||||
|
<artifactId>jjwt-jackson</artifactId>
|
||||||
|
<version>0.11.5</version>
|
||||||
|
<scope>runtime</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi-ooxml</artifactId>
|
||||||
|
<version>4.1.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.guava</groupId>
|
||||||
|
<artifactId>guava</artifactId>
|
||||||
|
<version>31.1-jre</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-security</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>jakarta.validation</groupId>
|
||||||
|
<artifactId>jakarta.validation-api</artifactId>
|
||||||
|
<version>2.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.jsoup</groupId>
|
||||||
|
<artifactId>jsoup</artifactId>
|
||||||
|
<version>1.15.3</version> <!-- 版本号可根据需要调整 -->
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
package com.example.sjkbf;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateField;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import org.springframework.boot.ApplicationArguments;
|
||||||
|
import org.springframework.boot.ApplicationRunner;
|
||||||
|
import org.springframework.core.annotation.Order;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.io.LineNumberReader;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author lnj
|
||||||
|
* createTime 2018-11-07 22:37
|
||||||
|
**/
|
||||||
|
@Component
|
||||||
|
public class ApplicationRunnerImpl implements ApplicationRunner {
|
||||||
|
@Override
|
||||||
|
public void run(ApplicationArguments args) throws Exception {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
141
旧的java项目/src/main/java/com/example/sjkbf/CodeGenerator.java
Normal file
141
旧的java项目/src/main/java/com/example/sjkbf/CodeGenerator.java
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
package com.example.sjkbf;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||||
|
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
|
||||||
|
import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||||
|
import com.baomidou.mybatisplus.generator.InjectionConfig;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.*;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||||
|
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||||
|
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Scanner;
|
||||||
|
|
||||||
|
public class CodeGenerator {
|
||||||
|
|
||||||
|
|
||||||
|
//依赖
|
||||||
|
|
||||||
|
// compile group: 'com.baomidou', name: 'mybatis-plus-generator', version: '3.3.1.tmp'
|
||||||
|
// compile group: 'org.freemarker', name: 'freemarker', version: '2.3.31'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* 读取控制台内容
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public static String scanner(String tip) {
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
StringBuilder help = new StringBuilder();
|
||||||
|
help.append("请输入" + tip + ":");
|
||||||
|
System.out.println(help.toString());
|
||||||
|
if (scanner.hasNext()) {
|
||||||
|
String ipt = scanner.next();
|
||||||
|
if (StringUtils.isNotBlank(ipt)) {
|
||||||
|
return ipt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw new MybatisPlusException("请输入正确的" + tip + "!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 代码生成器
|
||||||
|
AutoGenerator mpg = new AutoGenerator();
|
||||||
|
|
||||||
|
// 全局配置
|
||||||
|
GlobalConfig gc = new GlobalConfig();
|
||||||
|
//获得当前文件路径
|
||||||
|
String projectPath = System.getProperty("user.dir");
|
||||||
|
gc.setOutputDir(projectPath + "/src/main/java");
|
||||||
|
// gc.setOutputDir("D:\\test");
|
||||||
|
gc.setAuthor("bozhiqiang");
|
||||||
|
////是否打开资源管理器
|
||||||
|
gc.setOpen(false);
|
||||||
|
// gc.setSwagger2(true); 实体属性 Swagger2 注解
|
||||||
|
//service接口:置生成的service接口名首字母是为I
|
||||||
|
gc.setServiceName("%sService");
|
||||||
|
mpg.setGlobalConfig(gc);
|
||||||
|
|
||||||
|
// 数据源配置
|
||||||
|
DataSourceConfig dsc = new DataSourceConfig();
|
||||||
|
dsc.setUrl("jdbc:mysql://110.42.251.214:3306/rindro?useUnicode=true&useSSL=false&characterEncoding=utf8&serverTimezone=UTC&allowPublicKeyRetrieval=true");
|
||||||
|
// dsc.setSchemaName("public");
|
||||||
|
dsc.setDriverName("com.mysql.cj.jdbc.Driver");
|
||||||
|
dsc.setUsername("root");
|
||||||
|
dsc.setPassword("Yosin0102!");
|
||||||
|
mpg.setDataSource(dsc);
|
||||||
|
|
||||||
|
// 包配置
|
||||||
|
PackageConfig pc = new PackageConfig();
|
||||||
|
pc.setModuleName(null);
|
||||||
|
pc.setParent("com.example.zyk");
|
||||||
|
//设置实体类包名 可不设 默认entity
|
||||||
|
// pc.setEntity("entity");
|
||||||
|
//设置mapper包名 可不设 默认 mapper
|
||||||
|
// pc.setMapper("mapper");
|
||||||
|
//设置service 包名 可不设默认 service
|
||||||
|
// pc.setService("service");
|
||||||
|
//设置controller 包名 可不设默认 controller
|
||||||
|
// pc.setController("controller")
|
||||||
|
mpg.setPackageInfo(pc);
|
||||||
|
|
||||||
|
// 自定义配置
|
||||||
|
InjectionConfig cfg = new InjectionConfig() {
|
||||||
|
@Override
|
||||||
|
public void initMap() {
|
||||||
|
// to do nothing
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 如果模板引擎是 freemarker
|
||||||
|
String templatePath = "/templates/mapper.xml.ftl";
|
||||||
|
// 如果模板引擎是 velocity
|
||||||
|
// String templatePath = "/templates/mapper.xml.vm";
|
||||||
|
|
||||||
|
// 自定义输出配置
|
||||||
|
List<FileOutConfig> focList = new ArrayList<>();
|
||||||
|
// 自定义配置会被优先输出
|
||||||
|
focList.add(new FileOutConfig(templatePath) {
|
||||||
|
@Override
|
||||||
|
public String outputFile(TableInfo tableInfo) {
|
||||||
|
// 自定义输出文件名 , 如果你 Entity 设置了前后缀、此处注意 xml 的名称会跟着发生变化!!
|
||||||
|
return projectPath + "/src/main/resources/mapper/"
|
||||||
|
+ "/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
cfg.setFileOutConfigList(focList);
|
||||||
|
mpg.setCfg(cfg);
|
||||||
|
|
||||||
|
// 配置模板
|
||||||
|
TemplateConfig templateConfig = new TemplateConfig();
|
||||||
|
|
||||||
|
templateConfig.setXml(null);
|
||||||
|
mpg.setTemplate(templateConfig);
|
||||||
|
|
||||||
|
// 策略配置
|
||||||
|
StrategyConfig strategy = new StrategyConfig();
|
||||||
|
//表映射实体---去除表前缀
|
||||||
|
strategy.setNaming(NamingStrategy.underline_to_camel);
|
||||||
|
//字段映射实体---去除下划线
|
||||||
|
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
|
||||||
|
//实体类开启Lombok
|
||||||
|
strategy.setEntityLombokModel(true);
|
||||||
|
//控制层接口使用Rest
|
||||||
|
strategy.setRestControllerStyle(true);
|
||||||
|
//设置要映射的表名
|
||||||
|
//String[] tableNames = {"表名1","表名2","","表名3","表名x"};
|
||||||
|
//strategy.setInclude(tableNames);
|
||||||
|
// strategy.setInclude("blog_tags","course","links","sys_settings","user_record"," user_say"); // 设置要映射的表名
|
||||||
|
strategy.setInclude(scanner("表名,多个英文逗号分割").split(","));
|
||||||
|
strategy.setControllerMappingHyphenStyle(true);
|
||||||
|
//去除表前缀
|
||||||
|
strategy.setTablePrefix("m_");
|
||||||
|
mpg.setStrategy(strategy);
|
||||||
|
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
|
||||||
|
mpg.execute();
|
||||||
|
}
|
||||||
|
}
|
||||||
110
旧的java项目/src/main/java/com/example/sjkbf/SaticScheduleTask.java
Normal file
110
旧的java项目/src/main/java/com/example/sjkbf/SaticScheduleTask.java
Normal file
@@ -0,0 +1,110 @@
|
|||||||
|
package com.example.sjkbf;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateField;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import cn.hutool.core.io.LineHandler;
|
||||||
|
import cn.hutool.core.io.file.Tailer;
|
||||||
|
import cn.hutool.core.io.watch.SimpleWatcher;
|
||||||
|
import cn.hutool.core.io.watch.WatchMonitor;
|
||||||
|
import cn.hutool.core.io.watch.watchers.DelayWatcher;
|
||||||
|
import cn.hutool.log.StaticLog;
|
||||||
|
import com.example.sjkbf.common.FileManage;
|
||||||
|
import com.example.sjkbf.controller.AccountCargoController;
|
||||||
|
import com.example.sjkbf.service.impl.ProjectPerServiceImpl;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.context.event.ContextRefreshedEvent;
|
||||||
|
import org.springframework.scheduling.annotation.EnableScheduling;
|
||||||
|
import org.springframework.scheduling.annotation.Scheduled;
|
||||||
|
|
||||||
|
import javax.annotation.PostConstruct;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.WatchEvent;
|
||||||
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Configuration //1.主要用于标记配置类,兼备Component的效果。
|
||||||
|
@EnableScheduling // 2.开启定时任务
|
||||||
|
public class SaticScheduleTask {
|
||||||
|
@Autowired
|
||||||
|
public ProjectPerServiceImpl projectPerService;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
FileManage fileManage;
|
||||||
|
|
||||||
|
private static ConfigurableApplicationContext context;
|
||||||
|
//3.添加定时任务
|
||||||
|
// @Scheduled(cron = "0 0 0/2 * * ?")
|
||||||
|
@PostConstruct
|
||||||
|
public void configureTasks() throws Exception {
|
||||||
|
fileManage.init();
|
||||||
|
|
||||||
|
projectPerService.initInfo();
|
||||||
|
|
||||||
|
WatchMonitor all = WatchMonitor.createAll(fileManage.getScriptfile(), new DelayWatcher(new SimpleWatcher(){
|
||||||
|
@Override
|
||||||
|
public void onModify(WatchEvent<?> event, Path currentPath) {
|
||||||
|
try {
|
||||||
|
projectPerService.initInfo();
|
||||||
|
|
||||||
|
}catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
StaticLog.error("重载项目配置文件出现异常");
|
||||||
|
}
|
||||||
|
System.out.println("重载配置文件");
|
||||||
|
}
|
||||||
|
}, 500));
|
||||||
|
|
||||||
|
all.setMaxDepth(4);
|
||||||
|
all.start();
|
||||||
|
|
||||||
|
// Tailer tailer = new Tailer(FileUtil.file(fileManage.getConfigfile()), new LineHandler() {
|
||||||
|
// @Override
|
||||||
|
// public void handle(String s) {
|
||||||
|
// try {
|
||||||
|
// projectPerService.initInfo();
|
||||||
|
//
|
||||||
|
// }catch (Exception e){
|
||||||
|
// e.printStackTrace();
|
||||||
|
// StaticLog.error("重载项目配置文件出现异常");
|
||||||
|
// }
|
||||||
|
// System.out.println("重载配置文件");
|
||||||
|
// }
|
||||||
|
// }, 1);
|
||||||
|
//
|
||||||
|
// //新建一个线程
|
||||||
|
// Thread thread = new Thread(
|
||||||
|
// tailer::start
|
||||||
|
// );
|
||||||
|
// thread.start();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
AccountCargoController cargoController;
|
||||||
|
|
||||||
|
// @Scheduled(cron = "0 0 1 * * ?")
|
||||||
|
// private void configureTasks2(){
|
||||||
|
// cargoController.save();
|
||||||
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
System.out.println(2620+1940+1450+741 - ((40+37 +94 +20)*2) -70);
|
||||||
|
System.out.println(6299*0.7);
|
||||||
|
System.out.println(4409-25-150-68-200-300-100-50+6+25-200-750-100-400-30-50+70+6-200-50);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
package com.example.sjkbf;
|
||||||
|
|
||||||
|
import cn.hutool.core.date.DateField;
|
||||||
|
import cn.hutool.core.date.DateTime;
|
||||||
|
import cn.hutool.core.date.DateUtil;
|
||||||
|
import cn.hutool.core.io.FileUtil;
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
|
||||||
|
import org.springframework.context.ConfigurableApplicationContext;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
@SpringBootApplication()
|
||||||
|
|
||||||
|
public class SjkbfApplication {
|
||||||
|
|
||||||
|
private static ConfigurableApplicationContext context;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws InterruptedException {
|
||||||
|
SpringApplication.run(SjkbfApplication.class, args);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 添加自定义关闭钩子,打印触发源
|
||||||
|
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
|
||||||
|
System.out.println("=====================================");
|
||||||
|
System.out.println("=== 自定义ShutdownHook触发!开始定位原因 ===");
|
||||||
|
System.out.println("触发时间:" + new java.util.Date());
|
||||||
|
System.out.println("当前线程:" + Thread.currentThread().getName());
|
||||||
|
// 打印所有线程的栈轨迹,找到触发关闭的源头
|
||||||
|
Thread.getAllStackTraces().forEach((thread, stackTraces) -> {
|
||||||
|
// 只打印关键线程(减少日志量)
|
||||||
|
if (thread.getName().contains("ShutdownHook") || thread.getName().contains("main")
|
||||||
|
|| thread.getName().contains("Task") || thread.getName().contains("Timer")) {
|
||||||
|
System.out.println("\n线程名称:" + thread.getName() + " (状态:" + thread.getState() + ")");
|
||||||
|
for (StackTraceElement elem : stackTraces) {
|
||||||
|
System.out.println("\t" + elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
System.out.println("=== ShutdownHook触发原因定位结束 ===");
|
||||||
|
System.out.println("=====================================");
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println("=== 应用触发关闭,开始重启上下文 ===");
|
||||||
|
// 关闭当前上下文
|
||||||
|
context.close();
|
||||||
|
// 重新启动上下文
|
||||||
|
context = SpringApplication.run(SjkbfApplication.class, args);
|
||||||
|
}, "Custom-Exit-Detector"));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.example.sjkbf.common;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Data
|
||||||
|
public class FileManage {
|
||||||
|
|
||||||
|
@Value("${pro.configfile}")
|
||||||
|
private String configfile;
|
||||||
|
|
||||||
|
@Value("${pro.userfile}")
|
||||||
|
private String file;
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${pro.filemap}")
|
||||||
|
private String filemap;
|
||||||
|
|
||||||
|
@Value("${pro.scriptfile}")
|
||||||
|
private String scriptfile;
|
||||||
|
|
||||||
|
@Value("${pro.dps}")
|
||||||
|
private String dpsfile;
|
||||||
|
|
||||||
|
private String dpsScriptfile;
|
||||||
|
|
||||||
|
|
||||||
|
public void init(){
|
||||||
|
|
||||||
|
String os = System.getProperty("os.name").toLowerCase();
|
||||||
|
if (os.contains("win")) {
|
||||||
|
dpsScriptfile = file +"dpsScript\\";
|
||||||
|
}else {
|
||||||
|
dpsScriptfile = file +"dpsScript/";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
package com.example.sjkbf.config.Configuration;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
@Target(ElementType.PARAMETER)
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
public @interface CurrentUserId {
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package com.example.sjkbf.config.Configuration;
|
||||||
|
|
||||||
|
import com.example.sjkbf.entity.AuthUser;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.MethodParameter;
|
||||||
|
import org.springframework.security.core.Authentication;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.web.bind.support.WebDataBinderFactory;
|
||||||
|
import org.springframework.web.context.request.NativeWebRequest;
|
||||||
|
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
|
||||||
|
import org.springframework.web.method.support.ModelAndViewContainer;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class WebMvcConfig implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
|
||||||
|
resolvers.add(new CurrentUserIdResolver());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class CurrentUserIdResolver implements HandlerMethodArgumentResolver {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean supportsParameter(MethodParameter parameter) {
|
||||||
|
return parameter.hasParameterAnnotation(CurrentUserId.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object resolveArgument(MethodParameter parameter,
|
||||||
|
ModelAndViewContainer mavContainer,
|
||||||
|
NativeWebRequest webRequest,
|
||||||
|
WebDataBinderFactory binderFactory) {
|
||||||
|
|
||||||
|
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
|
||||||
|
String userName = (String)authentication.getPrincipal();
|
||||||
|
return userName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
package com.example.sjkbf.config;
|
||||||
|
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
public class CorsConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsFilter corsFilter() {
|
||||||
|
// 1. 创建 CORS 配置对象
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
|
||||||
|
// 允许的域名(生产环境建议明确指定,而非使用通配符)
|
||||||
|
config.addAllowedOriginPattern("*"); // Spring Boot 2.4+ 使用 allowedOriginPatterns
|
||||||
|
// config.addAllowedOrigin("http://localhost:8080"); // 明确指定域名
|
||||||
|
|
||||||
|
// 允许的请求头
|
||||||
|
config.addAllowedHeader("*");
|
||||||
|
|
||||||
|
// 允许的 HTTP 方法
|
||||||
|
config.addAllowedMethod("GET");
|
||||||
|
config.addAllowedMethod("POST");
|
||||||
|
config.addAllowedMethod("PUT");
|
||||||
|
config.addAllowedMethod("DELETE");
|
||||||
|
config.addAllowedMethod("OPTIONS"); // 预检请求需要
|
||||||
|
|
||||||
|
// 是否允许发送 Cookie
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
|
||||||
|
// 预检请求缓存时间(秒)
|
||||||
|
config.setMaxAge(3600L);
|
||||||
|
|
||||||
|
// 2. 注册 CORS 配置应用到所有路径
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
|
||||||
|
// 3. 返回 CORS 过滤器
|
||||||
|
return new CorsFilter(source);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
package com.example.sjkbf.config;
|
||||||
|
|
||||||
|
import com.example.sjkbf.util.JwtTokenUtil;
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||||
|
import io.jsonwebtoken.JwtException;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
|
||||||
|
import org.springframework.security.core.GrantedAuthority;
|
||||||
|
import org.springframework.security.core.authority.SimpleGrantedAuthority;
|
||||||
|
import org.springframework.security.core.context.SecurityContextHolder;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter;
|
||||||
|
import javax.servlet.FilterChain;
|
||||||
|
import javax.servlet.ServletException;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import javax.servlet.http.HttpServletResponse;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private JwtTokenUtil jwtTokenUtil;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
|
||||||
|
throws ServletException, IOException {
|
||||||
|
|
||||||
|
|
||||||
|
// 1. 从请求头获取 Token
|
||||||
|
String token = jwtTokenUtil.getTokenFromRequest(request);
|
||||||
|
try {
|
||||||
|
// 2. Token 存在且有效(基础验证:签名、过期时间)
|
||||||
|
if (token != null && jwtTokenUtil.validateToken(token)) {
|
||||||
|
// 3. 直接从 Token 中解析用户信息和权限(无需查库)
|
||||||
|
String username = jwtTokenUtil.getUsernameFromToken(token);
|
||||||
|
List<GrantedAuthority> authorities = jwtTokenUtil.getAuthoritiesFromToken(token)
|
||||||
|
.stream()
|
||||||
|
.map(SimpleGrantedAuthority ::new)
|
||||||
|
.collect(Collectors.toList());
|
||||||
|
|
||||||
|
// 4. 构建 Authentication 对象(权限来自 Token)
|
||||||
|
UsernamePasswordAuthenticationToken authentication =
|
||||||
|
new UsernamePasswordAuthenticationToken(
|
||||||
|
username, // 主体可以是用户名(或自定义 User 对象)
|
||||||
|
null, // 凭证(密码)无需存储
|
||||||
|
authorities
|
||||||
|
);
|
||||||
|
|
||||||
|
// 5. 存入 SecurityContext(后续鉴权直接使用 Token 中的权限)
|
||||||
|
SecurityContextHolder.getContext().setAuthentication(authentication);
|
||||||
|
}
|
||||||
|
}catch (JwtException e){
|
||||||
|
sendErrorResponse(response, 4011, "请重新登录");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
// Token 解析失败(如篡改、过期),清理上下文
|
||||||
|
SecurityContextHolder.clearContext();
|
||||||
|
sendErrorResponse(response, 4013, "认证失败");
|
||||||
|
logger.error("认证失败:" + e.getMessage());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6. 继续过滤器链
|
||||||
|
chain.doFilter(request, response);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// 发送 JSON 错误响应
|
||||||
|
private void sendErrorResponse(HttpServletResponse response, int code, String message)
|
||||||
|
throws IOException {
|
||||||
|
response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
|
||||||
|
response.setContentType("application/json;charset=UTF-8");
|
||||||
|
|
||||||
|
Map<String, Object> errorData = new HashMap<>();
|
||||||
|
errorData.put("code", code);
|
||||||
|
errorData.put("msg", message);
|
||||||
|
|
||||||
|
response.getWriter().write(new ObjectMapper().writeValueAsString(errorData));
|
||||||
|
}
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user