Compare commits
2 Commits
65cce920f5
...
e054d90eb1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e054d90eb1 | ||
|
|
10569bd097 |
@@ -1,72 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.5)
|
|
||||||
|
|
||||||
project(singlechat.wt LANGUAGES CXX)
|
|
||||||
|
|
||||||
add_compile_options(-Wno-deprecated-declarations)
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_COMPILER "/usr/bin/g++-12")
|
|
||||||
|
|
||||||
# Set default build type if not specified
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set compiler flags based on build type
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
add_compile_options(-g)
|
|
||||||
else()
|
|
||||||
add_compile_options(-O2)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME}
|
|
||||||
src/main.cpp
|
|
||||||
src/broadcast.cpp
|
|
||||||
src/app.cpp
|
|
||||||
)
|
|
||||||
|
|
||||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
|
||||||
wt
|
|
||||||
wthttp
|
|
||||||
curl
|
|
||||||
xml2
|
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
|
||||||
)
|
|
||||||
|
|
||||||
find_package(Boost COMPONENTS system filesystem REQUIRED)
|
|
||||||
if(Boost_FOUND)
|
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} GraphicsMagick++ GraphicsMagick)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
find_package(PkgConfig)
|
|
||||||
pkg_check_modules(XML2 libxml-2.0)
|
|
||||||
if(XML2_FOUND)
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${XML2_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
find_package(PkgConfig)
|
|
||||||
pkg_check_modules(XML2 libxml-2.0)
|
|
||||||
if(XML2_FOUND)
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE ${XML2_INCLUDE_DIRS} /usr/include/GraphicsMagick)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
install(TARGETS ${PROJECT_NAME}
|
|
||||||
RUNTIME DESTINATION /opt/ypchat/bin
|
|
||||||
)
|
|
||||||
|
|
||||||
# Install docroot directory and handle logs setup
|
|
||||||
install(DIRECTORY docroot/
|
|
||||||
DESTINATION /opt/ypchat/docroot
|
|
||||||
)
|
|
||||||
install(CODE "file(MAKE_DIRECTORY /opt/ypchat/logs)")
|
|
||||||
install(CODE "execute_process(COMMAND chmod 777 /opt/ypchat/logs)")
|
|
||||||
|
|
||||||
@@ -1,71 +0,0 @@
|
|||||||
cmake_minimum_required(VERSION 3.5)
|
|
||||||
|
|
||||||
project(singlechat.wt LANGUAGES CXX)
|
|
||||||
add_compile_options(-Wno-deprecated-declarations)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 20)
|
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_CXX_COMPILER "/usr/bin/g++-12")
|
|
||||||
set(CMAKE_PREFIX_PATH "/usr")
|
|
||||||
|
|
||||||
# Set default build type if not specified
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
|
||||||
set(CMAKE_BUILD_TYPE Release)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Set compiler flags based on build type
|
|
||||||
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
|
|
||||||
add_compile_options(-g)
|
|
||||||
else()
|
|
||||||
add_compile_options(-O2)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(${PROJECT_NAME}
|
|
||||||
src/main.cpp
|
|
||||||
src/broadcast.h src/broadcast.cpp
|
|
||||||
src/app.h src/app.cpp
|
|
||||||
docroot/text.xml
|
|
||||||
docroot/ads.txt
|
|
||||||
docroot/links.csv
|
|
||||||
)
|
|
||||||
target_compile_features(${PROJECT_NAME} PRIVATE cxx_std_20)
|
|
||||||
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
|
|
||||||
target_link_libraries(${PROJECT_NAME}
|
|
||||||
wt
|
|
||||||
wthttp
|
|
||||||
curl
|
|
||||||
xml2
|
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
|
||||||
)
|
|
||||||
|
|
||||||
find_package(Boost COMPONENTS system filesystem REQUIRED)
|
|
||||||
if(UNIX)
|
|
||||||
# Ubuntu-spezifische Include-Verzeichnisse
|
|
||||||
find_package(PkgConfig)
|
|
||||||
pkg_check_modules(XML2 libxml-2.0)
|
|
||||||
if(XML2_FOUND)
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE /usr/include/GraphicsMagick ${XML2_INCLUDE_DIRS})
|
|
||||||
endif()
|
|
||||||
elseif(EXISTS "/etc/os-release" AND ("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux"))
|
|
||||||
# Tumbleweed-spezifische Include-Verzeichnisse
|
|
||||||
target_include_directories(${PROJECT_NAME} PRIVATE /usr/include/GraphicsMagick)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(Boost_FOUND)
|
|
||||||
include_directories(${Boost_INCLUDE_DIRS})
|
|
||||||
target_link_libraries(${PROJECT_NAME} ${Boost_LIBRARIES} GraphicsMagick++ GraphicsMagick)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
install(TARGETS ${PROJECT_NAME}
|
|
||||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
|
||||||
RUNTIME DESTINATION /opt/ypchat/bin
|
|
||||||
)
|
|
||||||
install(DIRECTORY docroot/
|
|
||||||
DESTINATION /opt/ypchat/docroot
|
|
||||||
)
|
|
||||||
install(CODE "file(MAKE_DIRECTORY /opt/ypchat/logs)")
|
|
||||||
install(CODE "execute_process(COMMAND chmod 777 /opt/ypchat/logs)")
|
|
||||||
@@ -1,517 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE QtCreatorProject>
|
|
||||||
<!-- Written by QtCreator 17.0.1, 2025-11-16T12:30:10. -->
|
|
||||||
<qtcreator>
|
|
||||||
<data>
|
|
||||||
<variable>EnvironmentId</variable>
|
|
||||||
<value type="QByteArray">{551ef6b3-a39b-43e2-9ee3-ad56e19ff4f4}</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
|
||||||
<value type="qlonglong">0</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoDetect">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
|
||||||
<value type="QString" key="language">Cpp</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
|
||||||
<value type="QString" key="language">QmlJS</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
|
||||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.LineEndingBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PreferAfterWhitespaceComments">0</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">2</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
|
||||||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
|
||||||
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="bool" key="AutoTest.ApplyFilter">false</value>
|
|
||||||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
|
||||||
<valuelist type="QVariantList" key="AutoTest.PathFilters"/>
|
|
||||||
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
|
||||||
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="ClangTools">
|
|
||||||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
|
||||||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
|
||||||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
|
||||||
<value type="int" key="ClangTools.ParallelJobs">8</value>
|
|
||||||
<value type="bool" key="ClangTools.PreferConfigFile">true</value>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
|
||||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="DeviceType">Desktop</value>
|
|
||||||
<value type="bool" key="HasPerBcDcs">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Importiertes Kit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Importiertes Kit</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{c305b734-2e7c-49c6-bd3a-cd5bcb4ae45e}</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
|
||||||
<value type="QString" key="CMake.Build.Type">Debug</value>
|
|
||||||
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
|
|
||||||
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
|
|
||||||
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
|
|
||||||
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
|
|
||||||
-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
|
|
||||||
<value type="QString" key="CMake.Source.Directory">/mnt/share/torsten/Programs/SingleChat</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/build</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug (importiert)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString"></value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Application Manager-Paket installieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">singlechat.wt</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">singlechat.wt</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/torsten/Programs/SingleChat/build/Debug</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
|
||||||
<value type="QString" key="CMake.Build.Type">Release</value>
|
|
||||||
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
|
|
||||||
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
|
|
||||||
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
|
|
||||||
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
|
|
||||||
-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
|
|
||||||
<value type="QString" key="CMake.Source.Directory">/mnt/share/torsten/Programs/SingleChat</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/build</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release (importiert)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">-1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">install</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Application Manager-Paket installieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
|
||||||
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
|
|
||||||
<value type="int" key="CMake.Configure.BaseEnvironment">2</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_COLOR_DIAGNOSTICS:BOOL=ON
|
|
||||||
-DCMAKE_CXX_COMPILER:FILEPATH=%{Compiler:Executable:Cxx}
|
|
||||||
-DQT_QMAKE_EXECUTABLE:FILEPATH=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_PROJECT_INCLUDE_BEFORE:FILEPATH=%{BuildConfig:BuildDirectory:NativeFilePath}/.qtc/package-manager/auto-setup.cmake
|
|
||||||
-DCMAKE_C_COMPILER:FILEPATH=%{Compiler:Executable:C}
|
|
||||||
-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DCMAKE_PREFIX_PATH:PATH=%{Qt:QT_INSTALL_PREFIX}</value>
|
|
||||||
<value type="QString" key="CMake.Source.Directory">/mnt/share/torsten/Programs/SingleChat</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/build</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release mit Debuginformationen (importiert)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">-1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">install</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Application Manager-Paket installieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">0</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">3</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString"></value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.CMakePackageStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.1">
|
|
||||||
<value type="QString" key="ApplicationManagerPlugin.Deploy.InstallPackageStep.Arguments">install-package --acknowledge</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Application Manager-Paket installieren</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.InstallPackageStep</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedHosts"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedRemotePaths"/>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.RunConfiguration.LastDeployedSysroots"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedLocalTimes"/>
|
|
||||||
<valuelist type="QVariantList" key="RemoteLinux.LastDeployedRemoteTimes"/>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">2</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ApplicationManagerPlugin.Deploy.Configuration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">2</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="int" key="Analyzer.Valgrind.Callgrind.CostFormat">0</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="bool" key="PE.EnvironmentAspect.PrintOnRun">false</value>
|
|
||||||
<value type="QString" key="PerfRecordArgsId">-e cpu-cycles --call-graph dwarf,4096 -F 250</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">singlechat.wt</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">singlechat.wt</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.RunConfiguration.Customized">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/torsten/Programs/SingleChat/build/Debug</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
|
||||||
<value type="qlonglong">1</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Version</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
</qtcreator>
|
|
||||||
@@ -1,387 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE QtCreatorProject>
|
|
||||||
<!-- Written by QtCreator 9.0.2, 2024-10-21T08:08:04. -->
|
|
||||||
<qtcreator>
|
|
||||||
<data>
|
|
||||||
<variable>EnvironmentId</variable>
|
|
||||||
<value type="QByteArray">{d36652ff-969b-426b-a63f-1edd325096c5}</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.ActiveTarget</variable>
|
|
||||||
<value type="qlonglong">0</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.EditorSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoIndent">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.AutoSpacesForTabs">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.CamelCaseNavigation">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.0">
|
|
||||||
<value type="QString" key="language">Cpp</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">CppGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="EditorConfiguration.CodeStyle.1">
|
|
||||||
<value type="QString" key="language">QmlJS</value>
|
|
||||||
<valuemap type="QVariantMap" key="value">
|
|
||||||
<value type="QByteArray" key="CurrentPreferences">QmlJSGlobal</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="EditorConfiguration.CodeStyle.Count">2</value>
|
|
||||||
<value type="QByteArray" key="EditorConfiguration.Codec">UTF-8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ConstrainTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.IndentSize">4</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.KeyboardTooltips">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.MarginColumn">80</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseHiding">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.MouseNavigation">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.PaddingMode">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.PreferSingleLineComments">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ScrollWheelZooming">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.ShowMargin">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.SmartBackspaceBehavior">0</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SmartSelectionChanging">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.SpacesForTabs">true</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabKeyBehavior">0</value>
|
|
||||||
<value type="int" key="EditorConfiguration.TabSize">8</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseGlobal">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.UseIndenter">false</value>
|
|
||||||
<value type="int" key="EditorConfiguration.Utf8BomBehavior">1</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.addFinalNewLine">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanIndentation">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.cleanWhitespace">true</value>
|
|
||||||
<value type="QString" key="EditorConfiguration.ignoreFileTypes">*.md, *.MD, Makefile</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.inEntireDocument">false</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.skipTrailingWhitespace">true</value>
|
|
||||||
<value type="bool" key="EditorConfiguration.tintMarginArea">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.PluginSettings</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<valuemap type="QVariantMap" key="AutoTest.ActiveFrameworks">
|
|
||||||
<value type="bool" key="AutoTest.Framework.Boost">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.CTest">false</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.Catch">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.GTest">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.QtQuickTest">true</value>
|
|
||||||
<value type="bool" key="AutoTest.Framework.QtTest">true</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="AutoTest.CheckStates"/>
|
|
||||||
<value type="int" key="AutoTest.RunAfterBuild">0</value>
|
|
||||||
<value type="bool" key="AutoTest.UseGlobal">true</value>
|
|
||||||
<valuemap type="QVariantMap" key="ClangTools">
|
|
||||||
<value type="bool" key="ClangTools.AnalyzeOpenFiles">true</value>
|
|
||||||
<value type="bool" key="ClangTools.BuildBeforeAnalysis">true</value>
|
|
||||||
<value type="QString" key="ClangTools.DiagnosticConfig">Builtin.DefaultTidyAndClazy</value>
|
|
||||||
<value type="int" key="ClangTools.ParallelJobs">8</value>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedDirs"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SelectedFiles"/>
|
|
||||||
<valuelist type="QVariantList" key="ClangTools.SuppressedDiagnostics"/>
|
|
||||||
<value type="bool" key="ClangTools.UseGlobalSettings">true</value>
|
|
||||||
</valuemap>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Target.0</variable>
|
|
||||||
<valuemap type="QVariantMap">
|
|
||||||
<value type="QString" key="DeviceType">Desktop</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Desktop</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Desktop</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">{15eefee5-3141-47ab-aab0-72db66b5555b}</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveBuildConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveDeployConfiguration">0</value>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.ActiveRunConfiguration">0</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.0">
|
|
||||||
<value type="QString" key="CMake.Build.Type">Release</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable}</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/build</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Debug</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.1">
|
|
||||||
<value type="QString" key="CMake.Build.Type">Release</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable}</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/../build-SingleChat-Desktop</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.2">
|
|
||||||
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable}</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/../build-SingleChat-Desktop</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release mit Debuginformationen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.3">
|
|
||||||
<value type="QString" key="CMake.Build.Type">RelWithDebInfo</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable}</value>
|
|
||||||
<value type="int" key="EnableQmlDebugging">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/../build-SingleChat-Desktop</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Profile</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.BuildConfiguration.4">
|
|
||||||
<value type="QString" key="CMake.Build.Type">MinSizeRel</value>
|
|
||||||
<value type="bool" key="CMake.Configure.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMake.Configure.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="CMake.Initial.Parameters">-DCMAKE_GENERATOR:STRING=Ninja Multi-Config
|
|
||||||
-DQT_QMAKE_EXECUTABLE:STRING=%{Qt:qmakeExecutable}
|
|
||||||
-DCMAKE_CXX_COMPILER:STRING=%{Compiler:Executable}</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.BuildConfiguration.BuildDirectory">/home/torsten/Programs/SingleChat/../build-SingleChat-Desktop</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">all</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Erstellen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Build</value>
|
|
||||||
</valuemap>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.1">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildStepList.Step.0">
|
|
||||||
<value type="QString" key="CMakeProjectManager.MakeStep.BuildPreset"></value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.BuildTargets">
|
|
||||||
<value type="QString">clean</value>
|
|
||||||
</valuelist>
|
|
||||||
<value type="bool" key="CMakeProjectManager.MakeStep.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="CMakeProjectManager.MakeStep.UserEnvironmentChanges"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildStep.Enabled">true</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.MakeStep</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">1</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Bereinigen</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Clean</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">2</value>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ClearSystemEnvironment">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.CustomParsers"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.BuildConfiguration.ParseStandardOutput">false</value>
|
|
||||||
<valuelist type="QVariantList" key="ProjectExplorer.BuildConfiguration.UserEnvironmentChanges"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Release (kleinstmöglich)</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeBuildConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.BuildConfigurationCount">5</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.DeployConfiguration.0">
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.BuildConfiguration.BuildStepList.0">
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.BuildStepList.StepsCount">0</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DefaultDisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">Deployment</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.BuildSteps.Deploy</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="int" key="ProjectExplorer.BuildConfiguration.BuildStepListCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.DeployConfiguration.CustomData"/>
|
|
||||||
<value type="bool" key="ProjectExplorer.DeployConfiguration.CustomDataEnabled">false</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">ProjectExplorer.DefaultDeployConfiguration</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.DeployConfigurationCount">1</value>
|
|
||||||
<valuemap type="QVariantMap" key="ProjectExplorer.Target.RunConfiguration.0">
|
|
||||||
<value type="bool" key="Analyzer.Perf.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.QmlProfiler.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="bool" key="Analyzer.Valgrind.Settings.UseGlobalSettings">true</value>
|
|
||||||
<value type="QString" key="Analyzer.Valgrind.ValgrindExecutable">/usr/bin/valgrind</value>
|
|
||||||
<valuelist type="QVariantList" key="CustomOutputParsers"/>
|
|
||||||
<value type="int" key="PE.EnvironmentAspect.Base">2</value>
|
|
||||||
<valuelist type="QVariantList" key="PE.EnvironmentAspect.Changes"/>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.DisplayName">singlechat.wt</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.ProjectConfiguration.Id">CMakeProjectManager.CMakeRunConfiguration.singlechat.wt</value>
|
|
||||||
<value type="QString" key="ProjectExplorer.RunConfiguration.BuildKey">singlechat.wt</value>
|
|
||||||
<value type="QString" key="RunConfiguration.Arguments">--docroot="../../docroot" --http-address=0.0.0.0 --http-port=5050</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebugger">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseCppDebuggerAuto">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseLibrarySearchPath">true</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebugger">false</value>
|
|
||||||
<value type="bool" key="RunConfiguration.UseQmlDebuggerAuto">true</value>
|
|
||||||
<value type="QString" key="RunConfiguration.WorkingDirectory.default">/home/torsten/Programs/SingleChat/build/Release</value>
|
|
||||||
</valuemap>
|
|
||||||
<value type="qlonglong" key="ProjectExplorer.Target.RunConfigurationCount">1</value>
|
|
||||||
</valuemap>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.TargetCount</variable>
|
|
||||||
<value type="qlonglong">1</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
<data>
|
|
||||||
<variable>Version</variable>
|
|
||||||
<value type="int">22</value>
|
|
||||||
</data>
|
|
||||||
</qtcreator>
|
|
||||||
@@ -67,9 +67,12 @@ const smileys = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
function sendMessage() {
|
function sendMessage() {
|
||||||
if (!message.value.trim() || !chatStore.currentConversation) return;
|
const trimmed = message.value.trim();
|
||||||
|
if (!trimmed) return;
|
||||||
|
const isCommand = trimmed.startsWith('/');
|
||||||
|
if (!isCommand && !chatStore.currentConversation) return;
|
||||||
|
|
||||||
chatStore.sendMessage(chatStore.currentConversation, message.value.trim());
|
chatStore.sendMessage(chatStore.currentConversation, trimmed);
|
||||||
message.value = '';
|
message.value = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,6 +185,10 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
handleWebSocketMessage({ type: 'historyResults', ...data });
|
handleWebSocketMessage({ type: 'historyResults', ...data });
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socketInstance.on('commandResult', (data) => {
|
||||||
|
handleWebSocketMessage({ type: 'commandResult', ...data });
|
||||||
|
});
|
||||||
|
|
||||||
socketInstance.on('unreadChats', (data) => {
|
socketInstance.on('unreadChats', (data) => {
|
||||||
handleWebSocketMessage({ type: 'unreadChats', ...data });
|
handleWebSocketMessage({ type: 'unreadChats', ...data });
|
||||||
});
|
});
|
||||||
@@ -287,6 +291,27 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
case 'historyResults':
|
case 'historyResults':
|
||||||
historyResults.value = data.results;
|
historyResults.value = data.results;
|
||||||
break;
|
break;
|
||||||
|
case 'commandResult': {
|
||||||
|
const lines = Array.isArray(data.lines) ? data.lines : [];
|
||||||
|
if (!currentConversation.value) {
|
||||||
|
errorMessage.value = lines.join(' | ');
|
||||||
|
setTimeout(() => {
|
||||||
|
errorMessage.value = null;
|
||||||
|
}, 5000);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const timestamp = new Date().toISOString();
|
||||||
|
for (const line of lines) {
|
||||||
|
messages.value.push({
|
||||||
|
from: 'System',
|
||||||
|
message: String(line),
|
||||||
|
timestamp,
|
||||||
|
self: false,
|
||||||
|
isImage: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
case 'unreadChats':
|
case 'unreadChats':
|
||||||
unreadChatsCount.value = data.count || 0;
|
unreadChatsCount.value = data.count || 0;
|
||||||
break;
|
break;
|
||||||
@@ -354,19 +379,23 @@ export const useChatStore = defineStore('chat', () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const messageId = Date.now().toString();
|
const messageId = Date.now().toString();
|
||||||
|
const trimmed = message.trim();
|
||||||
|
const isCommand = trimmed.startsWith('/');
|
||||||
socket.value.emit('message', {
|
socket.value.emit('message', {
|
||||||
toUserName,
|
toUserName,
|
||||||
message,
|
message: trimmed,
|
||||||
messageId
|
messageId
|
||||||
});
|
});
|
||||||
|
|
||||||
// Lokal hinzufügen
|
// Lokal hinzufügen (außer bei Commands, die serverseitig beantwortet werden)
|
||||||
messages.value.push({
|
if (!isCommand) {
|
||||||
from: userName.value,
|
messages.value.push({
|
||||||
message,
|
from: userName.value,
|
||||||
timestamp: new Date().toISOString(),
|
message: trimmed,
|
||||||
self: true
|
timestamp: new Date().toISOString(),
|
||||||
});
|
self: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Timeout zurücksetzen bei Aktivität
|
// Timeout zurücksetzen bei Aktivität
|
||||||
resetTimeoutTimer();
|
resetTimeoutTimer();
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ class Client {
|
|||||||
this.loginTimeStamp = new Date();
|
this.loginTimeStamp = new Date();
|
||||||
this.blockedUsers = new Set();
|
this.blockedUsers = new Set();
|
||||||
this.socket = null; // Socket.IO Socket-Objekt
|
this.socket = null; // Socket.IO Socket-Objekt
|
||||||
|
this.chatAuth = null; // { username, rights: Set<string> }
|
||||||
|
this.pendingChatLogin = null; // { step: 'username'|'password', username: string }
|
||||||
}
|
}
|
||||||
|
|
||||||
setActivity() {
|
setActivity() {
|
||||||
@@ -50,6 +52,104 @@ class Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const CHAT_USERS_FILE_NAME = 'chat-users.json';
|
||||||
|
const CHAT_RIGHTS = {
|
||||||
|
STAT: 'stat',
|
||||||
|
KICK: 'kick'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getLogsDir(__dirname) {
|
||||||
|
return join(__dirname, '../logs');
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureLogsDir(__dirname) {
|
||||||
|
const logsDir = getLogsDir(__dirname);
|
||||||
|
if (!existsSync(logsDir)) {
|
||||||
|
mkdirSync(logsDir, { recursive: true });
|
||||||
|
}
|
||||||
|
return logsDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getChatUsersPath(__dirname) {
|
||||||
|
return join(ensureLogsDir(__dirname), CHAT_USERS_FILE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
function sha256(value) {
|
||||||
|
return crypto.createHash('sha256').update(value).digest('hex');
|
||||||
|
}
|
||||||
|
|
||||||
|
function ensureChatUsersFile(__dirname) {
|
||||||
|
const usersPath = getChatUsersPath(__dirname);
|
||||||
|
if (existsSync(usersPath)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultUsers = [
|
||||||
|
{
|
||||||
|
username: 'admin',
|
||||||
|
passwordHash: `sha256:${sha256('changeme123')}`,
|
||||||
|
rights: [CHAT_RIGHTS.STAT, CHAT_RIGHTS.KICK]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
writeFileSync(usersPath, JSON.stringify(defaultUsers, null, 2), 'utf-8');
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadChatUsers(__dirname) {
|
||||||
|
ensureChatUsersFile(__dirname);
|
||||||
|
const usersPath = getChatUsersPath(__dirname);
|
||||||
|
const raw = readFileSync(usersPath, 'utf-8').trim();
|
||||||
|
if (!raw) return [];
|
||||||
|
|
||||||
|
let users = [];
|
||||||
|
try {
|
||||||
|
users = JSON.parse(raw);
|
||||||
|
} catch (error) {
|
||||||
|
throw new Error(`Ungültige ${CHAT_USERS_FILE_NAME}: ${error.message}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Array.isArray(users)) {
|
||||||
|
throw new Error(`${CHAT_USERS_FILE_NAME} muss ein Array sein`);
|
||||||
|
}
|
||||||
|
|
||||||
|
return users
|
||||||
|
.filter((entry) => entry && typeof entry.username === 'string')
|
||||||
|
.map((entry) => ({
|
||||||
|
username: entry.username.trim(),
|
||||||
|
passwordHash: typeof entry.passwordHash === 'string' ? entry.passwordHash.trim() : '',
|
||||||
|
rights: Array.isArray(entry.rights) ? entry.rights.map((r) => String(r).toLowerCase()) : []
|
||||||
|
}))
|
||||||
|
.filter((entry) => entry.username && entry.passwordHash);
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseLoginRecord(line) {
|
||||||
|
const trimmed = line.trim();
|
||||||
|
if (!trimmed) return null;
|
||||||
|
const parts = trimmed.split(',');
|
||||||
|
if (parts.length < 5) return null;
|
||||||
|
|
||||||
|
const timestamp = parts[0].trim();
|
||||||
|
const userName = parts[1].trim();
|
||||||
|
const gender = parts[parts.length - 1].trim();
|
||||||
|
const ageRaw = parts[parts.length - 2].trim();
|
||||||
|
const country = parts.slice(2, parts.length - 2).join(',').trim();
|
||||||
|
const age = Number.parseInt(ageRaw, 10);
|
||||||
|
|
||||||
|
const date = new Date(timestamp);
|
||||||
|
if (!timestamp || !userName || !country || Number.isNaN(age) || Number.isNaN(date.getTime())) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
timestamp,
|
||||||
|
date,
|
||||||
|
day: timestamp.slice(0, 10),
|
||||||
|
userName,
|
||||||
|
country,
|
||||||
|
age,
|
||||||
|
gender
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
let clients = new Map();
|
let clients = new Map();
|
||||||
let conversations = new Map(); // Key: "user1:user2" (alphabetisch sortiert)
|
let conversations = new Map(); // Key: "user1:user2" (alphabetisch sortiert)
|
||||||
|
|
||||||
@@ -223,6 +323,313 @@ export function setupBroadcast(io, __dirname) {
|
|||||||
downloadCountries();
|
downloadCountries();
|
||||||
setInterval(downloadCountries, 24 * 60 * 60 * 1000); // Täglich aktualisieren
|
setInterval(downloadCountries, 24 * 60 * 60 * 1000); // Täglich aktualisieren
|
||||||
|
|
||||||
|
function sendCommandResult(socket, lines) {
|
||||||
|
const payload = Array.isArray(lines) ? lines : [String(lines)];
|
||||||
|
socket.emit('commandResult', { lines: payload });
|
||||||
|
}
|
||||||
|
|
||||||
|
function hasRight(client, right) {
|
||||||
|
return !!client.chatAuth && client.chatAuth.rights instanceof Set && client.chatAuth.rights.has(right);
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLoginsPath() {
|
||||||
|
return join(ensureLogsDir(__dirname), 'logins.log');
|
||||||
|
}
|
||||||
|
|
||||||
|
function readLoginRecords() {
|
||||||
|
const logPath = getLoginsPath();
|
||||||
|
if (!existsSync(logPath)) return [];
|
||||||
|
const raw = readFileSync(logPath, 'utf-8');
|
||||||
|
return raw
|
||||||
|
.split('\n')
|
||||||
|
.map(parseLoginRecord)
|
||||||
|
.filter(Boolean);
|
||||||
|
}
|
||||||
|
|
||||||
|
function aggregateTop(items, keySelector, limit = 10) {
|
||||||
|
const counts = new Map();
|
||||||
|
for (const item of items) {
|
||||||
|
const key = keySelector(item);
|
||||||
|
counts.set(key, (counts.get(key) || 0) + 1);
|
||||||
|
}
|
||||||
|
return Array.from(counts.entries())
|
||||||
|
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]))
|
||||||
|
.slice(0, limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function buildAllStats(records) {
|
||||||
|
if (records.length === 0) {
|
||||||
|
return ['Keine Login-Daten vorhanden.'];
|
||||||
|
}
|
||||||
|
|
||||||
|
const today = new Date().toISOString().slice(0, 10);
|
||||||
|
const todayCount = records.filter((r) => r.day === today).length;
|
||||||
|
const uniqueNames = new Set(records.map((r) => r.userName)).size;
|
||||||
|
const ages = records.map((r) => r.age);
|
||||||
|
const minAge = Math.min(...ages);
|
||||||
|
const maxAge = Math.max(...ages);
|
||||||
|
const youngest = records.find((r) => r.age === minAge);
|
||||||
|
const oldest = records.find((r) => r.age === maxAge);
|
||||||
|
const topCountries = aggregateTop(records, (r) => r.country, 5)
|
||||||
|
.map(([name, count]) => `${name}(${count})`)
|
||||||
|
.join(', ');
|
||||||
|
|
||||||
|
return [
|
||||||
|
`Logins gesamt: ${records.length}`,
|
||||||
|
`Logins heute (${today}): ${todayCount}`,
|
||||||
|
`Unterschiedliche Namen: ${uniqueNames}`,
|
||||||
|
`Jüngster Nutzer: ${youngest.userName} (${youngest.age})`,
|
||||||
|
`Ältester Nutzer: ${oldest.userName} (${oldest.age})`,
|
||||||
|
`Top Länder: ${topCountries || 'keine'}`
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeStatsCommand(socket, client, parts) {
|
||||||
|
if (!hasRight(client, CHAT_RIGHTS.STAT)) {
|
||||||
|
sendCommandResult(socket, 'Keine Berechtigung: Recht "stat" fehlt.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const records = readLoginRecords();
|
||||||
|
if (records.length === 0) {
|
||||||
|
sendCommandResult(socket, 'Keine Login-Daten vorhanden.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sub = (parts[1] || '').toLowerCase();
|
||||||
|
|
||||||
|
if (!sub || sub === 'help') {
|
||||||
|
sendCommandResult(socket, [
|
||||||
|
'Stat-Befehle:',
|
||||||
|
'/stat today',
|
||||||
|
'/stat date YYYY-MM-DD',
|
||||||
|
'/stat range YYYY-MM-DD YYYY-MM-DD',
|
||||||
|
'/stat ages',
|
||||||
|
'/stat names',
|
||||||
|
'/stat countries',
|
||||||
|
'/all-stats'
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub === 'today') {
|
||||||
|
const day = new Date().toISOString().slice(0, 10);
|
||||||
|
const dayRecords = records.filter((r) => r.day === day);
|
||||||
|
sendCommandResult(socket, `Logins heute (${day}): ${dayRecords.length}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub === 'date') {
|
||||||
|
const day = parts[2];
|
||||||
|
if (!day || !/^\d{4}-\d{2}-\d{2}$/.test(day)) {
|
||||||
|
sendCommandResult(socket, 'Nutzung: /stat date YYYY-MM-DD');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const dayRecords = records.filter((r) => r.day === day);
|
||||||
|
sendCommandResult(socket, `Logins am ${day}: ${dayRecords.length}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub === 'range') {
|
||||||
|
const from = parts[2];
|
||||||
|
const to = parts[3];
|
||||||
|
if (!from || !to || !/^\d{4}-\d{2}-\d{2}$/.test(from) || !/^\d{4}-\d{2}-\d{2}$/.test(to)) {
|
||||||
|
sendCommandResult(socket, 'Nutzung: /stat range YYYY-MM-DD YYYY-MM-DD');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const filtered = records.filter((r) => r.day >= from && r.day <= to);
|
||||||
|
const perDay = aggregateTop(filtered, (r) => r.day, 1000)
|
||||||
|
.sort((a, b) => a[0].localeCompare(b[0]))
|
||||||
|
.map(([day, count]) => `${day}: ${count}`);
|
||||||
|
sendCommandResult(socket, [`Logins ${from} bis ${to}: ${filtered.length}`, ...perDay]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub === 'ages') {
|
||||||
|
const ages = records.map((r) => r.age);
|
||||||
|
const minAge = Math.min(...ages);
|
||||||
|
const maxAge = Math.max(...ages);
|
||||||
|
const youngest = records.find((r) => r.age === minAge);
|
||||||
|
const oldest = records.find((r) => r.age === maxAge);
|
||||||
|
sendCommandResult(socket, [
|
||||||
|
`Jüngster Nutzer: ${youngest.userName} (${youngest.age})`,
|
||||||
|
`Ältester Nutzer: ${oldest.userName} (${oldest.age})`
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub === 'names') {
|
||||||
|
const topNames = aggregateTop(records, (r) => r.userName, 20);
|
||||||
|
sendCommandResult(socket, [
|
||||||
|
`Namen gesamt (verschieden): ${new Set(records.map((r) => r.userName)).size}`,
|
||||||
|
...topNames.map(([name, count]) => `${name}: ${count}`)
|
||||||
|
]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sub === 'countries') {
|
||||||
|
const topCountries = aggregateTop(records, (r) => r.country, 20);
|
||||||
|
sendCommandResult(socket, topCountries.map(([country, count]) => `${country}: ${count}`));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommandResult(socket, 'Unbekannter /stat-Befehl. Nutze /stat help');
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeAllStatsCommand(socket, client) {
|
||||||
|
if (!hasRight(client, CHAT_RIGHTS.STAT)) {
|
||||||
|
sendCommandResult(socket, 'Keine Berechtigung: Recht "stat" fehlt.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sendCommandResult(socket, buildAllStats(readLoginRecords()));
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeKickCommand(socket, client, parts) {
|
||||||
|
if (!hasRight(client, CHAT_RIGHTS.KICK)) {
|
||||||
|
sendCommandResult(socket, 'Keine Berechtigung: Recht "kick" fehlt.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetName = (parts[1] || '').trim();
|
||||||
|
if (!targetName) {
|
||||||
|
sendCommandResult(socket, 'Nutzung: /kick <username>');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let targetSessionId = null;
|
||||||
|
let targetClient = null;
|
||||||
|
for (const [sid, c] of clients.entries()) {
|
||||||
|
if (c.userName === targetName && c.socket && c.socket.connected) {
|
||||||
|
targetSessionId = sid;
|
||||||
|
targetClient = c;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!targetClient) {
|
||||||
|
sendCommandResult(socket, `User "${targetName}" ist nicht online.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetClient.socket) {
|
||||||
|
targetClient.socket.emit('error', { message: 'Du wurdest vom Chat getrennt (kick).' });
|
||||||
|
targetClient.socket.disconnect(true);
|
||||||
|
}
|
||||||
|
clients.delete(targetSessionId);
|
||||||
|
broadcastUserList();
|
||||||
|
sendCommandResult(socket, `User "${targetName}" wurde gekickt.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
function verifyChatUser(username, password) {
|
||||||
|
const users = loadChatUsers(__dirname);
|
||||||
|
const user = users.find((u) => u.username.toLowerCase() === username.toLowerCase());
|
||||||
|
if (!user) return null;
|
||||||
|
|
||||||
|
const [algo, hash] = user.passwordHash.split(':');
|
||||||
|
if (algo !== 'sha256' || !hash) return null;
|
||||||
|
const inputHash = sha256(password);
|
||||||
|
if (inputHash !== hash) return null;
|
||||||
|
|
||||||
|
return {
|
||||||
|
username: user.username,
|
||||||
|
rights: new Set(user.rights)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function executeCommand(socket, client, rawInput) {
|
||||||
|
const input = rawInput.trim();
|
||||||
|
|
||||||
|
if (client.pendingChatLogin) {
|
||||||
|
if (client.pendingChatLogin.step === 'username') {
|
||||||
|
const enteredUser = input;
|
||||||
|
if (!enteredUser) {
|
||||||
|
sendCommandResult(socket, 'Username darf nicht leer sein. Bitte Username eingeben:');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
client.pendingChatLogin = { step: 'password', username: enteredUser };
|
||||||
|
sendCommandResult(socket, 'Passwort eingeben:');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (client.pendingChatLogin.step === 'password') {
|
||||||
|
const username = client.pendingChatLogin.username;
|
||||||
|
const auth = verifyChatUser(username, input);
|
||||||
|
client.pendingChatLogin = null;
|
||||||
|
if (!auth) {
|
||||||
|
sendCommandResult(socket, 'Login fehlgeschlagen. Benutzername oder Passwort falsch.');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
client.chatAuth = auth;
|
||||||
|
sendCommandResult(
|
||||||
|
socket,
|
||||||
|
`Login erfolgreich als ${auth.username}. Rechte: ${Array.from(auth.rights).join(', ') || 'keine'}`
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!input.startsWith('/')) return false;
|
||||||
|
|
||||||
|
const parts = input.split(/\s+/);
|
||||||
|
const command = parts[0].toLowerCase();
|
||||||
|
|
||||||
|
if (command === '/login') {
|
||||||
|
const username = (parts[1] || '').trim();
|
||||||
|
if (username) {
|
||||||
|
client.pendingChatLogin = { step: 'password', username };
|
||||||
|
sendCommandResult(socket, 'Passwort eingeben:');
|
||||||
|
} else {
|
||||||
|
client.pendingChatLogin = { step: 'username', username: '' };
|
||||||
|
sendCommandResult(socket, 'Username eingeben:');
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === '/logout-admin') {
|
||||||
|
const wasLoggedIn = !!client.chatAuth;
|
||||||
|
client.chatAuth = null;
|
||||||
|
client.pendingChatLogin = null;
|
||||||
|
sendCommandResult(
|
||||||
|
socket,
|
||||||
|
wasLoggedIn
|
||||||
|
? 'Admin/Command-Login wurde abgemeldet.'
|
||||||
|
: 'Es war kein Admin/Command-Login aktiv.'
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === '/whoami-rights') {
|
||||||
|
if (!client.chatAuth) {
|
||||||
|
sendCommandResult(socket, 'Nicht per Command-Login angemeldet.');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
sendCommandResult(socket, [
|
||||||
|
`Angemeldet als: ${client.chatAuth.username}`,
|
||||||
|
`Rechte: ${Array.from(client.chatAuth.rights).join(', ') || 'keine'}`
|
||||||
|
]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === '/stat') {
|
||||||
|
executeStatsCommand(socket, client, parts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === '/all-stats') {
|
||||||
|
executeAllStatsCommand(socket, client);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (command === '/kick') {
|
||||||
|
executeKickCommand(socket, client, parts);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
sendCommandResult(socket, `Unbekannter Befehl: ${command}`);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
// Socket.IO-Verbindungshandler
|
// Socket.IO-Verbindungshandler
|
||||||
io.on('connection', (socket) => {
|
io.on('connection', (socket) => {
|
||||||
const request = socket.handshake;
|
const request = socket.handshake;
|
||||||
@@ -598,6 +1005,11 @@ export function setupBroadcast(io, __dirname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { toUserName, message, messageId, isImage, imageType, imageUrl } = data;
|
const { toUserName, message, messageId, isImage, imageType, imageUrl } = data;
|
||||||
|
|
||||||
|
// Chat-Befehle werden direkt serverseitig verarbeitet
|
||||||
|
if (!isImage && typeof message === 'string' && executeCommand(socket, client, message)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (!toUserName) {
|
if (!toUserName) {
|
||||||
socket.emit('error', { message: 'Empfänger fehlt' });
|
socket.emit('error', { message: 'Empfänger fehlt' });
|
||||||
|
|||||||
1692
src/app.cpp
1692
src/app.cpp
File diff suppressed because it is too large
Load Diff
229
src/app.h
229
src/app.h
@@ -1,229 +0,0 @@
|
|||||||
#ifndef APP_H
|
|
||||||
#define APP_H
|
|
||||||
|
|
||||||
#include <Wt/WApplication.h>
|
|
||||||
#include <Wt/WEnvironment.h>
|
|
||||||
#include "broadcast.h"
|
|
||||||
#include "curl/curl.h"
|
|
||||||
#include <libxml2/libxml/tree.h>
|
|
||||||
#include <libxml2/libxml/xpath.h>
|
|
||||||
#include <unordered_set>
|
|
||||||
|
|
||||||
namespace Magick {
|
|
||||||
class Image;
|
|
||||||
class Blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
class App : public Wt::WApplication, public Client {
|
|
||||||
public:
|
|
||||||
App(const Wt::WEnvironment& env, Broadcast& server);
|
|
||||||
~App();
|
|
||||||
|
|
||||||
private:
|
|
||||||
const std::string adminName {"comiciusadmin"};
|
|
||||||
const std::string adminPassword {"p3Lv9!7?+Qq"};
|
|
||||||
|
|
||||||
// Key: short gender code used in the protocol, Value: translation id for display text
|
|
||||||
std::map<Wt::WString, Wt::WString> genders_ {
|
|
||||||
{"F", "gender_female"},
|
|
||||||
{"M", "gender_male"},
|
|
||||||
{"P", "gender_pair"},
|
|
||||||
{"TF", "gender_trans_mf"},
|
|
||||||
{"TM", "gender_trans_fm"}
|
|
||||||
};
|
|
||||||
std::vector<std::string> notAllowedNickPhrases_ {
|
|
||||||
"whore",
|
|
||||||
"hitler",
|
|
||||||
"nazi",
|
|
||||||
"admin"
|
|
||||||
};
|
|
||||||
struct Smiley {
|
|
||||||
std::string code;
|
|
||||||
std::string tooltip;
|
|
||||||
Smiley()=default;
|
|
||||||
Smiley(std::string code_, std::string tooltip_): code(code_), tooltip(tooltip_) {};
|
|
||||||
};
|
|
||||||
std::unordered_map<std::string, Smiley> smileys_ {
|
|
||||||
{":)", Smiley("1F642", "Smile")},
|
|
||||||
{":D", Smiley("1F600", "Laugh")},
|
|
||||||
{":(", Smiley("1F641", "Sad")},
|
|
||||||
{";)", Smiley("1F609", "Twinkle")},
|
|
||||||
{":p", Smiley("1F60B", "Tongue")},
|
|
||||||
{";p", Smiley("1F61C", "Twinkle tongue")},
|
|
||||||
{"O)", Smiley("1F607", "Angel")},
|
|
||||||
{":*", Smiley("1F617", "Kiss")},
|
|
||||||
{"(h)", Smiley("1FA77", "Heart")},
|
|
||||||
{"xD", Smiley("1F602", "Laughing hard")},
|
|
||||||
{":@", Smiley("1F635", "Confused")},
|
|
||||||
{":O", Smiley("1F632", "Surprised")},
|
|
||||||
{":3", Smiley("1F63A", "Cat face")},
|
|
||||||
{":|", Smiley("1F610", "Neutral")},
|
|
||||||
{":/", Smiley("1FAE4", "Skeptical")},
|
|
||||||
{":#", Smiley("1F912", "Sick")},
|
|
||||||
{"#)", Smiley("1F973", "Partied")},
|
|
||||||
{"%)", Smiley("1F974", "Drunk")},
|
|
||||||
{"(t)", Smiley("1F44D", "Thumbs up")},
|
|
||||||
{":'(", Smiley("1F622", "Cry")}
|
|
||||||
};
|
|
||||||
struct Search {
|
|
||||||
Wt::WContainerWidget *outputContainer = nullptr;
|
|
||||||
Wt::WString userName{""};
|
|
||||||
int minAge{18};
|
|
||||||
int maxAge{150};
|
|
||||||
std::unordered_set<std::string> gender;
|
|
||||||
std::unordered_set<std::string> countries;
|
|
||||||
Search()=default;
|
|
||||||
Search(Wt::WContainerWidget *outputContainer_):
|
|
||||||
outputContainer(outputContainer_) {
|
|
||||||
set = true;
|
|
||||||
gender.insert("All");
|
|
||||||
countries.insert("All");
|
|
||||||
}
|
|
||||||
bool set = false;
|
|
||||||
};
|
|
||||||
Wt::WString smileyPlaceholder_ = "&#x{1};";
|
|
||||||
const Wt::WEnvironment &env_;
|
|
||||||
Broadcast &server_;
|
|
||||||
Wt::WContainerWidget *menuContainer_;
|
|
||||||
Wt::WContainerWidget *userListContainer_;
|
|
||||||
Wt::WContainerWidget *contentContainer_;
|
|
||||||
Wt::JSignal<std::string, std::string> updateLocationSignal_;
|
|
||||||
std::string responseData_{""};
|
|
||||||
Wt::WPushButton *inbox_;
|
|
||||||
std::vector<std::string> searchResults_;
|
|
||||||
std::string currentConversationWith_{""};
|
|
||||||
bool inboxOpen_{false};
|
|
||||||
std::shared_ptr<int> messageCursorPosition_;
|
|
||||||
std::unique_ptr<Wt::WSound> messageReceived_;
|
|
||||||
Search searchFields;
|
|
||||||
Wt::WTimer *loginTimer_;
|
|
||||||
Wt::WTimer *timeoutRemainingTimer_;
|
|
||||||
bool isLoggedInAsAdmin {false};
|
|
||||||
void setMetaTags();
|
|
||||||
void initLocale();
|
|
||||||
Wt::WLocale determineLocaleFromBrowser() const;
|
|
||||||
void initApp();
|
|
||||||
void reSetUser();
|
|
||||||
Wt::WVBoxLayout *createVerticalLayout();
|
|
||||||
Wt::WHBoxLayout *createActionLayout(Wt::WVBoxLayout *verticalContainer);
|
|
||||||
void createUserListContainer(Wt::WHBoxLayout *layout);
|
|
||||||
void createContentContainer(Wt::WHBoxLayout *layout);
|
|
||||||
void createHeadContainer(Wt::WVBoxLayout *layout);
|
|
||||||
void createMenuContainer(Wt::WVBoxLayout *layout);
|
|
||||||
void showLogin();
|
|
||||||
void incomingBroadcast();
|
|
||||||
void startChat();
|
|
||||||
void updateLocation();
|
|
||||||
static size_t WriteCallback(void *contents, size_t size, size_t nmemb, std::string *output) {
|
|
||||||
size_t totalSize = size * nmemb;
|
|
||||||
output->append(reinterpret_cast<const char *>(contents), totalSize);
|
|
||||||
return totalSize;
|
|
||||||
};
|
|
||||||
void populateCountryComboBox(Wt::WComboBox *countryWidget);
|
|
||||||
void handleLogin(Wt::WLineEdit *userName, Wt::WComboBox *countryWidget, Wt::WSpinBox *ageWidget, Wt::WComboBox *genderWidget);
|
|
||||||
void populateGenderComboBox(Wt::WComboBox *genderWidget);
|
|
||||||
std::string getGenderShortByGender(std::string gender);
|
|
||||||
void updateUserlist(Wt::Json::Array userList, int size);
|
|
||||||
std::vector<Wt::Json::Object> sortUserList(Wt::Json::Array unsortedUserList);
|
|
||||||
void createMenu();
|
|
||||||
void addLeaveButton();
|
|
||||||
void logout();
|
|
||||||
void addHistoryButton();
|
|
||||||
void addIdentifier();
|
|
||||||
void addSearchButton();
|
|
||||||
void addInboxButton();
|
|
||||||
void showSearchWindow();
|
|
||||||
void startSearch();
|
|
||||||
void showSearch(Wt::Json::Object broadcast);
|
|
||||||
template<class Class> Class *addSearchItemLine(Wt::WVBoxLayout *layout, std::string label, std::unique_ptr<Wt::WContainerWidget> additionalItem = nullptr);
|
|
||||||
Wt::WContainerWidget *addSearchItemContainer(Wt::WVBoxLayout *layout, std::string label);
|
|
||||||
void openInbox();
|
|
||||||
bool isNickAllowed(const std::string &nick);
|
|
||||||
bool compareJsonObjects(const Wt::Json::Object &obj1, const Wt::Json::Object &obj2);
|
|
||||||
void requestConversation(std::string conversationWith);
|
|
||||||
void showConversation(Wt::Json::Object data);
|
|
||||||
void sendMessage(Wt::WLineEdit *inputLine);
|
|
||||||
void renderConversation(Wt::Json::Object conversation);
|
|
||||||
void showUnreadMessages(Wt::Json::Object data);
|
|
||||||
void showOpenInbox(Wt::Json::Object data);
|
|
||||||
void updateUserinfo(Wt::Json::Object data);
|
|
||||||
std::unique_ptr<Wt::WContainerWidget> createSmileysBar(Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
|
|
||||||
void toggleSmileysBar(Wt::WContainerWidget *smileyBar);
|
|
||||||
void systemEvent(Wt::Json::Object broadcast);
|
|
||||||
void addStartChatButton(Wt::WGridLayout *contentGrid, Wt::WLineEdit *userName, Wt::WComboBox *country, Wt::WSpinBox *age, Wt::WComboBox *gender);
|
|
||||||
Wt::WComboBox *addCountrySelection(Wt::WGridLayout *contentGrid);
|
|
||||||
Wt::WSpinBox *addAgeInput(Wt::WGridLayout *contentGrid);
|
|
||||||
Wt::WLineEdit *addUsernameInput(Wt::WGridLayout *contentGrid);
|
|
||||||
Wt::WComboBox *addGenderSelection(Wt::WGridLayout *contentGrid);
|
|
||||||
void createLoginContainer();
|
|
||||||
void connectToServer();
|
|
||||||
void setUserData(const std::string &nick, Wt::WComboBox *countryWidget, Wt::WSpinBox *ageWidget, Wt::WComboBox *genderWidget);
|
|
||||||
void validateAge(Wt::WSpinBox *ageWidget);
|
|
||||||
bool isGenderSelected(Wt::WComboBox *genderWidget);
|
|
||||||
void validateGender(Wt::WComboBox *genderWidget);
|
|
||||||
bool isNameAlreadyInUse(const std::string &nick);
|
|
||||||
bool isInvalidName(const std::string &nick);
|
|
||||||
void validateName(const std::string &nick);
|
|
||||||
std::string extractTrimmedUserName(Wt::WLineEdit *userName);
|
|
||||||
Wt::WPushButton *createSendButton(Wt::WHBoxLayout *inputLayout, Wt::WLineEdit *inputLine);
|
|
||||||
Wt::WContainerWidget *createSmileyBar(Wt::WContainerWidget *parent, Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
|
|
||||||
Wt::WContainerWidget *createSmileyButton(Wt::WHBoxLayout *inputLayout, Wt::WLineEdit *inputLine, std::shared_ptr<int> cursorPosition);
|
|
||||||
Wt::WImage *createSendImageButton(Wt::WHBoxLayout *inputLayout);
|
|
||||||
Wt::WLineEdit *createInputLine(Wt::WHBoxLayout *inputLayout);
|
|
||||||
Wt::WContainerWidget *createInputContainer(Wt::WVBoxLayout *layout);
|
|
||||||
std::unique_ptr<Wt::WText> createInfoText(Wt::Json::Object userData);
|
|
||||||
Wt::WContainerWidget *createInfoWidget(Wt::WVBoxLayout *layout, Wt::Json::Object userData);
|
|
||||||
void setupConversationUI(Wt::Json::Object userData);
|
|
||||||
bool shouldShowConversation(Wt::Json::Object userData);
|
|
||||||
Wt::Json::Object extractUserData(Wt::Json::Object data);
|
|
||||||
std::unique_ptr<Wt::WPushButton> createBlockButton(Wt::Json::Object userData);
|
|
||||||
std::string replaceSmileys(std::string outputText);
|
|
||||||
void renderChatLine(Wt::Json::Object &line, Wt::Json::Object conversation, Wt::WContainerWidget *outputContainer);
|
|
||||||
std::string getChatLineWriter(Wt::Json::Object &line, Wt::Json::Object conversation);
|
|
||||||
void renderChatLines(Wt::Json::Object conversation, Wt::WContainerWidget *outputContainer);
|
|
||||||
void updateOutputContainer(Wt::Json::Object conversation);
|
|
||||||
void handleException(const std::exception &e);
|
|
||||||
void processXmlNode(xmlNodePtr node);
|
|
||||||
void parseXmlDocument(xmlDocPtr doc);
|
|
||||||
void processCurlResponse();
|
|
||||||
void performCurlRequest(CURL *curl);
|
|
||||||
void setCurlOptions(CURL *curl, const std::string &apiUrl);
|
|
||||||
std::string buildApiUrl(const std::string &userIP);
|
|
||||||
std::string getUserIP();
|
|
||||||
Wt::WWebWidget *createImageElement(Wt::Json::Object &line, const std::string &writer, Wt::WContainerWidget *outputContainer, std::string id);
|
|
||||||
Wt::WWebWidget *createTextElement(const std::string &writer, const std::string &text, Wt::WContainerWidget *outputContainer, std::string id);
|
|
||||||
void createImprintContainer(Wt::WVBoxLayout *containerLayout);
|
|
||||||
Wt::WContainerWidget *setupSearchButton(Wt::WVBoxLayout *contentLayout);
|
|
||||||
void restoreSearchFields(Wt::WContainerWidget *searchResultContainer, Wt::WLineEdit *userNameEdit, Wt::WSpinBox *minAgeEdit, Wt::WSpinBox *maxAgeEdit, Wt::WContainerWidget *countryDropDownContainer, Wt::WContainerWidget *gendersDropDownContainer, Wt::WContainerWidget *countryOpenList, Wt::WContainerWidget *gendersOpenList);
|
|
||||||
Wt::WLineEdit *setupNameSearchField(Wt::WVBoxLayout *contentLayout);
|
|
||||||
std::pair<Wt::WContainerWidget *, Wt::WContainerWidget *> setupGendersDropDown(Wt::WVBoxLayout *contentLayout);
|
|
||||||
std::pair<Wt::WContainerWidget *, Wt::WContainerWidget *> setupCountryDropDown(Wt::WVBoxLayout *contentLayout);
|
|
||||||
std::pair<Wt::WSpinBox*, Wt::WSpinBox*> setupSearchFields(Wt::WVBoxLayout *contentLayout);
|
|
||||||
Wt::WVBoxLayout *resetSearchFields();
|
|
||||||
void itemChanged(Wt::WCheckBox *item, Wt::WContainerWidget *dropDownContainer, Wt::WContainerWidget *openButton, std::unordered_set<std::string> *saveItems);
|
|
||||||
void addItem(const std::string &country, Wt::WContainerWidget *dropDownContainer, Wt::WContainerWidget *container, std::unordered_set<std::string> *saveItems, bool isSelected = false);
|
|
||||||
void addUserItemToLayout(Wt::WVBoxLayout *layout, Wt::Json::Object userObject);
|
|
||||||
std::unordered_set<std::string> gendersListToShortGendersList(std::unordered_set<std::string> gendersList);
|
|
||||||
std::string genderShortOfGender(const std::string incomingGender);
|
|
||||||
void extendSearchResultIfNeeded(Wt::Json::Object broadcast);
|
|
||||||
void removeUserFromSearch(Wt::Json::Object broadcast);
|
|
||||||
void requestHistory();
|
|
||||||
void showHistory(Wt::Json::Object broadcast);
|
|
||||||
void connectionTimedOut();
|
|
||||||
void addLoginTimeView();
|
|
||||||
void addTimeoutView();
|
|
||||||
void showPartnerSites();
|
|
||||||
void sendImage();
|
|
||||||
void imageUploaded(Wt::WFileUpload *fileWidget, std::shared_ptr<Magick::Blob> localImage, Wt::WImage *image, Wt::WPushButton *okButton);
|
|
||||||
std::list<Magick::Image> resizeImages(std::list<Magick::Image>& images, int maxWidth, int maxHeight);
|
|
||||||
bool isAnimatedGIF(const Magick::Blob &blob);
|
|
||||||
void showStandardPage();
|
|
||||||
void onInternalPathChanged(const std::string &path);
|
|
||||||
void showAdminPage(std::string page);
|
|
||||||
void showAdminLogin(std::string page);
|
|
||||||
void showPageNotExists();
|
|
||||||
void showAdminLogins();
|
|
||||||
void showAdminStarts();
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // APP_H
|
|
||||||
@@ -1,770 +0,0 @@
|
|||||||
#include "broadcast.h"
|
|
||||||
#include <Wt/WApplication.h>
|
|
||||||
#include <Wt/WAny.h>
|
|
||||||
#include <Wt/Json/Array.h>
|
|
||||||
#include <Wt/Json/Serializer.h>
|
|
||||||
#include <Wt/Json/Parser.h>
|
|
||||||
#include <Wt/Json/Object.h>
|
|
||||||
#include <Wt/Auth/HashFunction.h>
|
|
||||||
#include <Wt/WLocalDateTime.h>
|
|
||||||
#include <Wt/Utils.h>
|
|
||||||
#include <fstream>
|
|
||||||
#include <iostream>
|
|
||||||
#include <sstream>
|
|
||||||
#include <vector>
|
|
||||||
#include <curl/curl.h>
|
|
||||||
#include <boost/algorithm/string.hpp>
|
|
||||||
#include <Magick++.h>
|
|
||||||
|
|
||||||
Broadcast::Broadcast(Wt::WServer *server):
|
|
||||||
wtServer_(server) {
|
|
||||||
downloadCountries();
|
|
||||||
thread_ = std::thread(std::bind(&Broadcast::run, this));
|
|
||||||
lastTimeoutCheck_ = Wt::WDateTime::currentDateTime();
|
|
||||||
checkAndLogStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::checkAndLogStart() {
|
|
||||||
const std::string logFilePath = "/opt/ypchat/logs/starts.log";
|
|
||||||
std::ifstream infile(logFilePath);
|
|
||||||
if (!infile.good()) {
|
|
||||||
std::ofstream outfile(logFilePath);
|
|
||||||
outfile.close();
|
|
||||||
}
|
|
||||||
infile.close();
|
|
||||||
Wt::WDateTime now = Wt::WDateTime::currentDateTime();
|
|
||||||
std::string timestamp = now.toString("yyyy-MM-dd HH:mm:ss").toUTF8();
|
|
||||||
std::ofstream outfile(logFilePath, std::ios_base::app);
|
|
||||||
if (outfile.is_open()) {
|
|
||||||
outfile << timestamp << std::endl;
|
|
||||||
outfile.close();
|
|
||||||
} else {
|
|
||||||
std::cerr << "Fehler beim Öffnen der Datei: " << logFilePath << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Broadcast::~Broadcast() {
|
|
||||||
stop_ = true;
|
|
||||||
thread_.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::connect(Client *client, const std::function<void ()> &fct) {
|
|
||||||
connections_.push_back(std::make_unique<Connection>(Wt::WApplication::instance()->sessionId(), client, fct));
|
|
||||||
auto userlistBroadcast = createUserList();
|
|
||||||
auto newUserBroadcast = Wt::Json::Object{
|
|
||||||
{"type", "newuser"},
|
|
||||||
{"data", client->json()},
|
|
||||||
};
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
connection->addBroadcast(userlistBroadcast);
|
|
||||||
connection->addBroadcast(newUserBroadcast);
|
|
||||||
}
|
|
||||||
logClientLogin(client->json());
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::logClientLogin(const Wt::Json::Object &clientJson) {
|
|
||||||
const std::string logFilePath = "../logs/logins.log";
|
|
||||||
Wt::Json::Array logArray;
|
|
||||||
std::ifstream infile(logFilePath);
|
|
||||||
if (infile.is_open()) {
|
|
||||||
std::stringstream buffer;
|
|
||||||
buffer << infile.rdbuf();
|
|
||||||
std::string fileContent = buffer.str();
|
|
||||||
infile.close();
|
|
||||||
if (!fileContent.empty()) {
|
|
||||||
Wt::Json::parse(fileContent, logArray);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Zeitstempel hinzufügen
|
|
||||||
Wt::Json::Object logEntry = clientJson;
|
|
||||||
Wt::WDateTime now = Wt::WDateTime::currentDateTime();
|
|
||||||
std::string timestamp = now.toString("yyyy-MM-dd HH:mm:ss").toUTF8();
|
|
||||||
logEntry["timestamp"] = Wt::Json::Value(timestamp);
|
|
||||||
|
|
||||||
logArray.push_back(logEntry);
|
|
||||||
std::ofstream outfile(logFilePath);
|
|
||||||
if (outfile.is_open()) {
|
|
||||||
outfile << Wt::Json::serialize(logArray) << std::endl;
|
|
||||||
outfile.close();
|
|
||||||
} else {
|
|
||||||
std::cerr << "Fehler beim Öffnen der Datei: " << logFilePath << std::endl;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::disconnect(Client *client) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
for (unsigned int i = 0; i < connections_.size(); ++ i) {
|
|
||||||
if (connections_[i]->client() == client) {
|
|
||||||
connections_.erase(connections_.begin() + i);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Wt::Json::Object leftBroadcast{
|
|
||||||
{"type", "userleft"},
|
|
||||||
{"data", Wt::Json::Value(client->userName)}
|
|
||||||
};
|
|
||||||
auto userlistBroadcast = createUserList();
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
connection->addBroadcast(userlistBroadcast);
|
|
||||||
connection->addBroadcast(leftBroadcast);
|
|
||||||
}
|
|
||||||
auto sessionId = sessionIdForUserName(client->userName);
|
|
||||||
for (auto it = conversations_.begin(); it != conversations_.end();) {
|
|
||||||
if (it->first.find(sessionId + "/") == 0 || it->first.rfind("/" + sessionId) == it->first.size() - sessionId.length() - 1) {
|
|
||||||
it = conversations_.erase(it);
|
|
||||||
} else {
|
|
||||||
++it;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::addToDisconnectList(Client *client) {
|
|
||||||
toDisconnect_.push_back(client);
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::reSetUser(std::string oldSessionId, std::string newSessionId) {
|
|
||||||
for (auto& connection : connections_) {
|
|
||||||
if (connection->setSessionId(oldSessionId, newSessionId)) {
|
|
||||||
Wt::Json::Object userData {
|
|
||||||
{"gender", Wt::Json::Value(connection->gender())},
|
|
||||||
{"country", Wt::Json::Value(connection->country())},
|
|
||||||
{"iso-country-code", Wt::Json::Value(getCountryIsoCodeByCountry(connection->country()))},
|
|
||||||
{"username", Wt::Json::Value(connection->userName())},
|
|
||||||
{"age", Wt::Json::Value(connection->age())},
|
|
||||||
};
|
|
||||||
reSetSessionIdInMessages(oldSessionId, newSessionId);
|
|
||||||
return userData;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return {};
|
|
||||||
}
|
|
||||||
|
|
||||||
int Broadcast::count() const {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
return connections_.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Broadcast::userNameForSessionId(std::string sessionId) {
|
|
||||||
for (const auto &connection: connections_) {
|
|
||||||
if (sessionId == connection->sessionId()) {
|
|
||||||
return connection->userName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Broadcast::sessionIdForUserName(std::string userName) {
|
|
||||||
for (const auto &connection: connections_) {
|
|
||||||
if (userName == connection->userName()) {
|
|
||||||
return connection->sessionId();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::userForSessionId(std::string sessionId) {
|
|
||||||
for (const auto &connection: connections_) {
|
|
||||||
if (sessionId == connection->sessionId()) {
|
|
||||||
return connection->client()->json();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Wt::Json::Object{};
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::userForUserName(std::string userName) {
|
|
||||||
for (const auto &connection: connections_) {
|
|
||||||
if (userName == connection->userName()) {
|
|
||||||
return connection->client()->json();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return Wt::Json::Object{};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::changeClientForSessionId(std::string sessionId, Client *client) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
if (sessionId == connection->sessionId()) {
|
|
||||||
connection->setClient(client);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Broadcast::nameIsFree(std::string userNameToCheck) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
if (connection->userName() == userNameToCheck) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::run() {
|
|
||||||
Wt::Json::Object timedoutBroadcast {
|
|
||||||
{"type", "timedout"},
|
|
||||||
{"data", "dummy"}
|
|
||||||
};
|
|
||||||
for (;;) {
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(200));
|
|
||||||
for (auto clientToDisconnect: toDisconnect_) {
|
|
||||||
disconnect(clientToDisconnect);
|
|
||||||
}
|
|
||||||
toDisconnect_.clear();
|
|
||||||
if (stop_) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
if (connection->client()->activitiesTimedOut()) {
|
|
||||||
auto sessionId = connection->sessionId();
|
|
||||||
toDisconnect_.push_back(connection->client());
|
|
||||||
addMessageToSessionBroadcast(sessionId, timedoutBroadcast);
|
|
||||||
}
|
|
||||||
if (connection->getBroadcasts().size() == 0) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Wt::WServer::instance()->post(connection->sessionId(), connection->fct());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::logoutBroadcast() {
|
|
||||||
return Wt::Json::Object{
|
|
||||||
{"type", "logout"}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::downloadCountries() {
|
|
||||||
CURL* curl = curl_easy_init();
|
|
||||||
if (!curl) {
|
|
||||||
std::cerr << "Failed to initialize CURL." << std::endl;
|
|
||||||
}
|
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, countriesDownloadUrl_.toUTF8().c_str());
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback);
|
|
||||||
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &responseData_);
|
|
||||||
CURLcode res = curl_easy_perform(curl);
|
|
||||||
curl_easy_cleanup(curl);
|
|
||||||
if (res != CURLE_OK) {
|
|
||||||
std::cerr << "Failed to download data: " << curl_easy_strerror(res) << std::endl;
|
|
||||||
}
|
|
||||||
parseCountriesData();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::map<Wt::WString, Wt::WString> Broadcast::countries() {
|
|
||||||
return countriesMap_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::WString Broadcast::getCountryIsoCodeByCountry(Wt::WString country) {
|
|
||||||
for (const auto &countryItem: countriesMap_) {
|
|
||||||
if (countryItem.first == country) {
|
|
||||||
return countryItem.second;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return "";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Wt::Json::Object> Broadcast::getBroadcastsForSession(std::string sessionId) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
if (connection->sessionId() == sessionId) {
|
|
||||||
return connection->getBroadcasts(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return std::list<Wt::Json::Object>();
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::addMessage(std::string fromSessionId, std::string toUserName, Message message) {
|
|
||||||
auto toSessionId = sessionIdForUserName(toUserName);
|
|
||||||
if (toSessionId == "") {
|
|
||||||
return Wt::Json::Object{
|
|
||||||
{"type", "system"},
|
|
||||||
{"data", "User left the chat."}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
auto fromUserName = userNameForSessionId(fromSessionId);
|
|
||||||
if (blockings_[toUserName].find(fromUserName) != blockings_[toUserName].end()) {
|
|
||||||
sendBlockedMessage(fromSessionId, toUserName);
|
|
||||||
}
|
|
||||||
auto id1 = fromSessionId + "/" + toSessionId;
|
|
||||||
auto id2 = toSessionId + "/" + fromSessionId;
|
|
||||||
auto it = conversations_.find(id1);
|
|
||||||
if (it == conversations_.end()) {
|
|
||||||
it = conversations_.find(id2);
|
|
||||||
}
|
|
||||||
if (it == conversations_.end()) {
|
|
||||||
MessageQueue messageQueue;
|
|
||||||
messageQueue.messages.push_back(message);
|
|
||||||
auto [newIt, success] = conversations_.emplace(id1, MessageQueue{});
|
|
||||||
it = newIt;
|
|
||||||
}
|
|
||||||
it->second.messages.push_back(message);
|
|
||||||
it->second.user1Read = false;
|
|
||||||
it->second.user2Read = false;
|
|
||||||
sendMessageQueueToSession(fromSessionId, userNameForSessionId(fromSessionId), toUserName, it->second.messages);
|
|
||||||
sendMessageQueueToSession(toSessionId, userNameForSessionId(fromSessionId), toUserName, it->second.messages);
|
|
||||||
sendMessageCount(toSessionId);
|
|
||||||
return Wt::Json::Object{
|
|
||||||
{"type", "dummy"},
|
|
||||||
{"data", "Message added to users queues."}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::addImage(std::string fromSessionId, std::string toUserName, std::shared_ptr<Magick::Blob> image) {
|
|
||||||
auto message = Message(fromSessionId, image);
|
|
||||||
return addMessage(fromSessionId, toUserName, message);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::setConversationRead(std::string readingUserSessionId, std::string secondUserName) {
|
|
||||||
auto toSessionId = sessionIdForUserName(secondUserName);
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
if (toSessionId == "") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto id1 = readingUserSessionId + "/" + toSessionId;
|
|
||||||
auto id2 = toSessionId + "/" + readingUserSessionId;
|
|
||||||
auto it = conversations_.find(id1);
|
|
||||||
if (it != conversations_.end()) {
|
|
||||||
it->second.user1Read = true;
|
|
||||||
} else {
|
|
||||||
it = conversations_.find(id2);
|
|
||||||
if (it != conversations_.end()) {
|
|
||||||
it->second.user2Read = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendMessageCount(readingUserSessionId);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendConversation(std::string sessionId1, std::string userName2) {
|
|
||||||
auto sessionId2 = sessionIdForUserName(userName2);
|
|
||||||
auto userName1 = userNameForSessionId(sessionId1);
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
auto id1 = sessionId1 + "/" + sessionId2;
|
|
||||||
auto id2 = sessionId2 + "/" + sessionId1;
|
|
||||||
auto it = conversations_.find(id1);
|
|
||||||
if (it == conversations_.end()) {
|
|
||||||
it = conversations_.find(id2);
|
|
||||||
if (it == conversations_.end()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
sendMessageQueueToSession(sessionId1, userName1, userName2, it->second.messages);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendOpenConversations(std::string forSessionId) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
Wt::Json::Array conversationsWithList;
|
|
||||||
for (const auto &conversation: conversations_) {
|
|
||||||
const auto key = conversation.first;
|
|
||||||
const auto data = conversation.second;
|
|
||||||
if ((key.compare(0, forSessionId.length() + 1, forSessionId + "/") == 0
|
|
||||||
&& !data.user1Read)
|
|
||||||
|| (key.compare(key.length() - forSessionId.length() - 1, forSessionId.length() + 1, "/" + forSessionId) == 0
|
|
||||||
&& !data.user2Read)) {
|
|
||||||
std::size_t found = key.find("/");
|
|
||||||
if (found != std::string::npos) {
|
|
||||||
std::string firstSessionId = key.substr(0, found);
|
|
||||||
std::string secondSessionId = key.substr(found + 1);
|
|
||||||
auto userData = forSessionId == firstSessionId ? userForSessionId(secondSessionId) : userForSessionId(firstSessionId);
|
|
||||||
conversationsWithList.push_back(userData);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Wt::Json::Object data{
|
|
||||||
{"type", "openconversations"},
|
|
||||||
{"data", conversationsWithList}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(forSessionId, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendUserInformation(std::string sendToSessionId, std::string userName, std::string requestingUserName) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
auto userData = userForUserName(userName);
|
|
||||||
if (blockings_.find(userName) == blockings_.end()) {
|
|
||||||
blockings_[userName] = std::set<std::string>();
|
|
||||||
}
|
|
||||||
userData["blocked"] = (blockings_.find(userName) != blockings_.end() && blockings_[userName].find(requestingUserName) != blockings_[userName].end());
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "userinfo"},
|
|
||||||
{"data", userData}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sendToSessionId, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::toggleBlockUser(std::string blockingUserName, std::string blockedUser, std::string blockingUserSessionId) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
if (blockings_.find(blockedUser) == blockings_.end()) {
|
|
||||||
blockings_[blockedUser] = std::set<std::string>();
|
|
||||||
}
|
|
||||||
if (blockings_[blockedUser].find(blockingUserName) != blockings_[blockedUser].end()) {
|
|
||||||
blockings_[blockedUser].erase(blockingUserName);
|
|
||||||
sendUnblockDone(blockingUserSessionId, blockedUser);
|
|
||||||
} else {
|
|
||||||
blockings_[blockedUser].insert(blockingUserName);
|
|
||||||
sendBlockDone(blockingUserSessionId, blockedUser);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::requestConversation(std::string sendToSessionId, std::string withUserName, std::string requestingUserName) {
|
|
||||||
auto userData = userForUserName(withUserName);
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
if (blockings_.find(withUserName) == blockings_.end()) {
|
|
||||||
blockings_[withUserName] = std::set<std::string>();
|
|
||||||
}
|
|
||||||
userData["blocked"] = !(blockings_.find(withUserName) == blockings_.end() || blockings_[withUserName].find(requestingUserName) == blockings_[withUserName].end());
|
|
||||||
auto sessionId2 = sessionIdForUserName(withUserName);
|
|
||||||
auto id1 = sendToSessionId + "/" + sessionId2;
|
|
||||||
auto id2 = sessionId2 + "/" + sendToSessionId;
|
|
||||||
auto it = conversations_.find(id1);
|
|
||||||
if (it == conversations_.end()) {
|
|
||||||
it = conversations_.find(id2);
|
|
||||||
if (it == conversations_.end()) {
|
|
||||||
MessageQueue messageQueue;
|
|
||||||
auto [newIt, success] = conversations_.emplace(id1, MessageQueue{});
|
|
||||||
it = newIt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "conversation-start"},
|
|
||||||
{"data", userData},
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sendToSessionId, broadcast);
|
|
||||||
Wt::Json::Array messagesJson;
|
|
||||||
for (Broadcast::Message &message: it->second.messages) {
|
|
||||||
messagesJson.push_back(message.json());
|
|
||||||
}
|
|
||||||
broadcast = {
|
|
||||||
{"type", "messagequeue"},
|
|
||||||
{"user1", Wt::Json::Value(requestingUserName)},
|
|
||||||
{"user2", Wt::Json::Value(withUserName)},
|
|
||||||
{"sessionid1", Wt::Json::Value(sendToSessionId)},
|
|
||||||
{"sessionid2", Wt::Json::Value(sessionId2)},
|
|
||||||
{"data", messagesJson}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sendToSessionId, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::userSearch(std::string toSession, std::string nameIncludes, int minAge, int maxAge, std::unordered_set<std::string> countries, std::unordered_set<std::string> genders, std::string excludeName) {
|
|
||||||
Wt::Json::Array searchResult;
|
|
||||||
for (const auto &user: connections_) {
|
|
||||||
if (
|
|
||||||
(nameIncludes == "" || user->userName().find(nameIncludes) != std::string::npos)
|
|
||||||
&& (minAge <= user->age())
|
|
||||||
&& (maxAge >= user->age())
|
|
||||||
&& (countries.contains("All") || countries.contains(user->country()) || countries.size() == 0)
|
|
||||||
&& (genders.contains("All") || genders.contains(user->gender()) || genders.size() == 0)
|
|
||||||
&& (user->userName() != excludeName)
|
|
||||||
) {
|
|
||||||
searchResult.push_back(user->client()->json());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "search-result"},
|
|
||||||
{"data", searchResult}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(toSession, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendHistory(std::string toSession) {
|
|
||||||
std::unique_lock<std::mutex> lock(mutex_);
|
|
||||||
Wt::Json::Array filteredConversationsPartners;
|
|
||||||
for (const auto& pair : conversations_) {
|
|
||||||
const std::string& key = pair.first;
|
|
||||||
if (key.rfind(toSession + "/", 0) == 0 || key.find("/" + toSession) == key.size() - toSession.length() - 1) {
|
|
||||||
std::string partnerId;
|
|
||||||
if (key.rfind(toSession + "/", 0) == 0) {
|
|
||||||
partnerId = key.substr(toSession.size() + 1);
|
|
||||||
} else {
|
|
||||||
partnerId = key.substr(0, key.size() - toSession.size() - 1);
|
|
||||||
}
|
|
||||||
auto partner = userForSessionId(partnerId);
|
|
||||||
filteredConversationsPartners.push_back(Wt::Json::Value(partner));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "history"},
|
|
||||||
{"data", filteredConversationsPartners}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(toSession, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Broadcast::parseCountriesData() {
|
|
||||||
std::istringstream iss(responseData_);
|
|
||||||
std::string line;
|
|
||||||
while (std::getline(iss, line)) {
|
|
||||||
line.erase(std::remove_if(line.begin(), line.end(), [](char c) { return !std::isprint(c) && c != ' '; }), line.end());
|
|
||||||
std::vector<std::string> tokens;
|
|
||||||
boost::split(tokens, line, boost::is_any_of(","));
|
|
||||||
if (tokens.size() == 2) {
|
|
||||||
auto name = tokens[0];
|
|
||||||
auto code = tokens[1];
|
|
||||||
std::transform(code.begin(), code.end(), code.begin(), ::tolower);
|
|
||||||
countriesMap_[name] = code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::reSetSessionIdInMessages(std::string oldSessionId, std::string newSessionId) {
|
|
||||||
for (auto &conversation: conversations_) {
|
|
||||||
conversation.second.setNewSesionId(oldSessionId, newSessionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::createUserList() {
|
|
||||||
Wt::Json::Array userList;
|
|
||||||
for (const auto &connection: connections_) {
|
|
||||||
Wt::Json::Object user;
|
|
||||||
user["name"] = Wt::asString(connection->userName());
|
|
||||||
user["age"] = connection->age();
|
|
||||||
user["gender"] = Wt::asString(connection->gender());
|
|
||||||
user["country"] = Wt::asString(connection->country());
|
|
||||||
user["isoCountryCode"] = getCountryIsoCodeByCountry(connection->country());
|
|
||||||
userList.push_back(user);
|
|
||||||
}
|
|
||||||
Wt::Json::Object data;
|
|
||||||
data["data"] = userList;
|
|
||||||
data["type"] = "userlist";
|
|
||||||
data["count"] = (int)userList.size();
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendMessageQueueToSession(std::string receiverSessionId, std::string user1, std::string user2, std::vector<Message> messages) {
|
|
||||||
Wt::Json::Array messagesJson;
|
|
||||||
for (Broadcast::Message &message: messages) {
|
|
||||||
messagesJson.push_back(message.json());
|
|
||||||
}
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "messagequeue"},
|
|
||||||
{"user1", Wt::Json::Value(user1)},
|
|
||||||
{"user2", Wt::Json::Value(user2)},
|
|
||||||
{"sessionid1", Wt::Json::Value(sessionIdForUserName(user1))},
|
|
||||||
{"sessionid2", Wt::Json::Value(sessionIdForUserName(user2))},
|
|
||||||
{"data", messagesJson}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(receiverSessionId, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::addMessageToSessionBroadcast(std::string sessionId, Wt::Json::Object message) {
|
|
||||||
for (auto &connection: connections_) {
|
|
||||||
if (connection->sessionId() == sessionId) {
|
|
||||||
connection->addBroadcast(message);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendMessageCount(std::string sessionId) {
|
|
||||||
int count{0};
|
|
||||||
for (const auto &conversation: conversations_) {
|
|
||||||
const auto key = conversation.first;
|
|
||||||
const auto data = conversation.second;
|
|
||||||
if ((key.compare(0, sessionId.length() + 1, sessionId + "/") == 0
|
|
||||||
&& !data.user1Read)
|
|
||||||
|| (key.compare(key.length() - sessionId.length() - 1, sessionId.length() + 1, "/" + sessionId) == 0
|
|
||||||
&& !data.user2Read)) {
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "unread-chats"},
|
|
||||||
{"data", count}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sessionId, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendBlockedMessage(std::string sessionId, std::string toUserName) {
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "system"},
|
|
||||||
{"related-user", Wt::WString(toUserName)},
|
|
||||||
{"data", "The user has blocked you."}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sessionId, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendBlockDone(std::string sessionId, std::string toUserName) {
|
|
||||||
addMessage(sessionId, toUserName, Message("Conversation is blocked."));
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "system"},
|
|
||||||
{"related-user", Wt::WString(toUserName)},
|
|
||||||
{"data", "blocked"}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sessionId, broadcast);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::sendUnblockDone(std::string sessionId, std::string toUserName) {
|
|
||||||
addMessage(sessionId, toUserName, Message("Conversation is unblocked."));
|
|
||||||
Wt::Json::Object broadcast{
|
|
||||||
{"type", "system"},
|
|
||||||
{"related-user", Wt::WString(toUserName)},
|
|
||||||
{"data", "unblocked"}
|
|
||||||
};
|
|
||||||
addMessageToSessionBroadcast(sessionId, broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Broadcast::WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output) {
|
|
||||||
size_t total_size = size * nmemb;
|
|
||||||
output->append(reinterpret_cast<char*>(contents), total_size);
|
|
||||||
return total_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
Broadcast::Connection::Connection(const std::string &id, Client *client, const std::function<void ()> &fct):
|
|
||||||
sessionId_(id),
|
|
||||||
client_(client),
|
|
||||||
fct_(fct) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Client *Broadcast::Connection::client() const {
|
|
||||||
return client_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Broadcast::Connection::sessionId() const {
|
|
||||||
return sessionId_;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Broadcast::Connection::userName() const {
|
|
||||||
return client_->userName;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Broadcast::Connection::country() const {
|
|
||||||
return client_->country;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Broadcast::Connection::age() const {
|
|
||||||
return client_->age;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string Broadcast::Connection::gender() const {
|
|
||||||
return client_->gender;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::Connection::setClient(Client *client) {
|
|
||||||
client_ = client;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::Connection::addBroadcast(Wt::Json::Object broadcast) {
|
|
||||||
broadcastFifo.push_back(broadcast);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::list<Wt::Json::Object> Broadcast::Connection::getBroadcasts(bool clear) {
|
|
||||||
auto broadcastCopy = broadcastFifo;
|
|
||||||
if (clear) {
|
|
||||||
broadcastFifo.clear();
|
|
||||||
}
|
|
||||||
return broadcastCopy;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Broadcast::Connection::setSessionId(std::string searchedSessionId, std::string newSessionId) {
|
|
||||||
if (searchedSessionId == sessionId_) {
|
|
||||||
sessionId_ = newSessionId;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::function<void ()> Broadcast::Connection::fct() {
|
|
||||||
return fct_;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void Client::setActivity() {
|
|
||||||
lastActivity_ = Wt::WDateTime::currentDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Client::activitiesTimedOut() {
|
|
||||||
auto timeDifference = lastActivity_.secsTo(Wt::WDateTime::currentDateTime());
|
|
||||||
return timeDifference > timeoutSeconds;
|
|
||||||
}
|
|
||||||
|
|
||||||
int Client::currentlyLoggedInSeconds() {
|
|
||||||
auto currentDateTime = Wt::WDateTime::currentDateTime();
|
|
||||||
return loginTimeStamp_.secsTo(currentDateTime);
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Client::json() {
|
|
||||||
return Wt::Json::Object{
|
|
||||||
{"name", Wt::WString(userName)},
|
|
||||||
{"gender", Wt::WString(gender)},
|
|
||||||
{"isoCountryCode", Wt::WString(isoCountryCode)},
|
|
||||||
{"country", Wt::WString(country)},
|
|
||||||
{"age", age}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
int Client::remainingSecondsToTimeout(){
|
|
||||||
auto timeDifference = lastActivity_.secsTo(Wt::WDateTime::currentDateTime());
|
|
||||||
return timeoutSeconds - timeDifference;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Client::setLoggedIn() {
|
|
||||||
loginTimeStamp_ = Wt::WDateTime::currentDateTime();
|
|
||||||
lastActivity_ = loginTimeStamp_;
|
|
||||||
}
|
|
||||||
|
|
||||||
Broadcast::Message::Message(std::string fromSessionId_, Wt::WString message_):
|
|
||||||
fromSessionId(fromSessionId_),
|
|
||||||
sendType("text"),
|
|
||||||
message(message_) {
|
|
||||||
auto timestamp = std::time(nullptr);
|
|
||||||
auto combinedString = std::to_string(timestamp) + fromSessionId_;
|
|
||||||
Wt::Auth::SHA1HashFunction hashObj;
|
|
||||||
auto hash = hashObj.compute(combinedString, "salt");
|
|
||||||
messageId = Wt::WString(hash);
|
|
||||||
sendTime = Wt::WDateTime::currentDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
Broadcast::Message::Message(std::string fromSessionId_, std::shared_ptr<Magick::Blob> imageBlob):
|
|
||||||
fromSessionId(fromSessionId_),
|
|
||||||
sendType("image") {
|
|
||||||
auto timestamp = std::time(nullptr);
|
|
||||||
auto combinedString = std::to_string(timestamp) + fromSessionId_;
|
|
||||||
Wt::Auth::SHA1HashFunction hashObj;
|
|
||||||
auto hash = hashObj.compute(combinedString, "salt");
|
|
||||||
messageId = Wt::WString(hash);
|
|
||||||
sendTime = Wt::WDateTime::currentDateTime();
|
|
||||||
Magick::Image image_;
|
|
||||||
image_.read(*imageBlob);
|
|
||||||
std::string imageData(reinterpret_cast<const char*>(imageBlob->data()), imageBlob->length());
|
|
||||||
std::string imageFormat = image_.magick();
|
|
||||||
image = {
|
|
||||||
{"width", Wt::Json::Value((int)image_.columns())},
|
|
||||||
{"height", Wt::Json::Value((int)image_.rows())},
|
|
||||||
{"imageblobbase64", Wt::Json::Value(Wt::Utils::base64Encode(imageData))},
|
|
||||||
{"type", Wt::Json::Value(imageFormat)}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
Broadcast::Message::Message(Wt::WString message_):
|
|
||||||
systemMessage(true),
|
|
||||||
sendType("text"),
|
|
||||||
message (message_) {
|
|
||||||
auto timestamp = std::time(nullptr);
|
|
||||||
auto combinedString = std::to_string(timestamp) + "system09715";
|
|
||||||
Wt::Auth::SHA1HashFunction hashObj;
|
|
||||||
auto hash = hashObj.compute(combinedString, "salt");
|
|
||||||
messageId = Wt::WString(hash);
|
|
||||||
sendTime = Wt::WDateTime::currentDateTime();
|
|
||||||
}
|
|
||||||
|
|
||||||
Wt::Json::Object Broadcast::Message::json() {
|
|
||||||
auto json = Wt::Json::Object();
|
|
||||||
json["sender"] = Wt::Json::Value(fromSessionId);
|
|
||||||
json["type"] = Wt::Json::Value(sendType);
|
|
||||||
json["string"] = Wt::Json::Value(message);
|
|
||||||
json["image"] = Wt::Json::Value(image);
|
|
||||||
json["id"] = Wt::Json::Value(messageId);
|
|
||||||
json["timestamp"] = sendTime.toString();
|
|
||||||
return json;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::Message::setNewSesionId(std::string oldSessionId, std::string newSessionId) {
|
|
||||||
if (fromSessionId == oldSessionId) {
|
|
||||||
fromSessionId = newSessionId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Broadcast::MessageQueue::setNewSesionId(std::string oldSessionId, std::string newSessionId) {
|
|
||||||
for (auto &message: messages) {
|
|
||||||
message.setNewSesionId(oldSessionId, newSessionId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
154
src/broadcast.h
154
src/broadcast.h
@@ -1,154 +0,0 @@
|
|||||||
#ifndef BROADCAST_H
|
|
||||||
#define BROADCAST_H
|
|
||||||
|
|
||||||
#include <thread>
|
|
||||||
#include <mutex>
|
|
||||||
#include <functional>
|
|
||||||
#include <map>
|
|
||||||
#include <list>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <Wt/WServer.h>
|
|
||||||
#include <Wt/WDate.h>
|
|
||||||
#include <Wt/Json/Object.h>
|
|
||||||
|
|
||||||
namespace Magick {
|
|
||||||
class Image;
|
|
||||||
class Blob;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct ConversationItem {
|
|
||||||
Wt::WDateTime timestamp;
|
|
||||||
bool selfSend;
|
|
||||||
Wt::WString text;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Client {
|
|
||||||
public:
|
|
||||||
std::string gender;
|
|
||||||
std::string country;
|
|
||||||
std::string isoCountryCode;
|
|
||||||
std::string userName;
|
|
||||||
int age;
|
|
||||||
std::unordered_map<std::string, std::vector<ConversationItem> > conversations;
|
|
||||||
void setActivity();
|
|
||||||
bool activitiesTimedOut();
|
|
||||||
int currentlyLoggedInSeconds();
|
|
||||||
virtual void incomingBroadcast() { std::cout << "incoming" << std::endl;};
|
|
||||||
Wt::Json::Object json();
|
|
||||||
int remainingSecondsToTimeout();
|
|
||||||
protected:
|
|
||||||
void setLoggedIn();
|
|
||||||
void setLoggedOut();
|
|
||||||
private:
|
|
||||||
const int timeoutSeconds {1800};
|
|
||||||
Wt::WDateTime lastActivity_;
|
|
||||||
Wt::WDateTime loginTimeStamp_;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Broadcast {
|
|
||||||
public:
|
|
||||||
struct Message {
|
|
||||||
Message()= default;
|
|
||||||
Message(std::string fromSessionId_, Wt::WString message_);
|
|
||||||
Message(std::string fromSessionId_, std::shared_ptr<Magick::Blob> image_);
|
|
||||||
Message(Wt::WString message_);
|
|
||||||
bool systemMessage{false};
|
|
||||||
std::string fromSessionId;
|
|
||||||
std::string sendType;
|
|
||||||
Wt::WDateTime sendTime;
|
|
||||||
Wt::WString message;
|
|
||||||
Wt::WString messageId;
|
|
||||||
Wt::Json::Object image;
|
|
||||||
Wt::Json::Object json();
|
|
||||||
void setNewSesionId(std::string oldSessionId, std::string newSessionId);
|
|
||||||
};
|
|
||||||
struct MessageQueue {
|
|
||||||
bool user1Read{false};
|
|
||||||
bool user2Read{false};
|
|
||||||
std::vector<Message> messages;
|
|
||||||
void setNewSesionId(std::string oldSessionId, std::string newSessionId);
|
|
||||||
};
|
|
||||||
Broadcast(Wt::WServer *server);
|
|
||||||
~Broadcast();
|
|
||||||
void connect(Client *client, const std::function<void ()> &fct);
|
|
||||||
void disconnect(Client *client);
|
|
||||||
void addToDisconnectList(Client *client);
|
|
||||||
Wt::Json::Object reSetUser(std::string oldSessionId, std::string newSessionId);
|
|
||||||
int count() const;
|
|
||||||
std::string userNameForSessionId(std::string sessionId);
|
|
||||||
std::string sessionIdForUserName(std::string userName);
|
|
||||||
Wt::Json::Object userForSessionId(std::string sessionId);
|
|
||||||
Wt::Json::Object userForUserName(std::string userName);
|
|
||||||
void changeClientForSessionId(std::string sessionId, Client *client);
|
|
||||||
bool nameIsFree(std::string userNameToCheck);
|
|
||||||
void downloadCountries();
|
|
||||||
std::map<Wt::WString, Wt::WString> countries();
|
|
||||||
Wt::WString getCountryIsoCodeByCountry(Wt::WString country);
|
|
||||||
std::list<Wt::Json::Object> getBroadcastsForSession(std::string sessionId);
|
|
||||||
Wt::Json::Object addMessage(std::string fromSessionId, std::string toUserName, Message message);
|
|
||||||
Wt::Json::Object addImage(std::string fromSessionId, std::string toUserName, std::shared_ptr<Magick::Blob> image);
|
|
||||||
void setConversationRead(std::string readingUserSessionId, std::string secondUserName);
|
|
||||||
void sendConversation(std::string sessionId1, std::string userName2);
|
|
||||||
void sendOpenConversations(std::string forSessionId);
|
|
||||||
void sendUserInformation(std::string sendToSessionId, std::string userName, std::string requestingUserName);
|
|
||||||
void toggleBlockUser(std::string blockingUserName, std::string blockedUser, std::string blockingUserSessionId);
|
|
||||||
void requestConversation(std::string sendToSessionId, std::string withUserName, std::string requestingUserName);
|
|
||||||
void userSearch(std::string toSession, std::string nameIncludes, int minAge, int maxAge,
|
|
||||||
std::unordered_set<std::string> countries, std::unordered_set<std::string> genders, std::string excludeName);
|
|
||||||
void sendHistory(std::string toSession);
|
|
||||||
protected:
|
|
||||||
struct Connection {
|
|
||||||
Connection(const std::string &id, Client *client, const std::function<void ()> &fct);
|
|
||||||
public:
|
|
||||||
Client *client() const;
|
|
||||||
std::string sessionId() const;
|
|
||||||
std::function<void ()> fct();
|
|
||||||
std::string userName() const;
|
|
||||||
std::string country() const;
|
|
||||||
int age() const;
|
|
||||||
std::string gender() const;
|
|
||||||
void setClient(Client *client);
|
|
||||||
void addBroadcast(Wt::Json::Object broadcast);
|
|
||||||
std::list<Wt::Json::Object> getBroadcasts(bool clear = false);
|
|
||||||
std::unordered_map<std::string, std::vector<std::string> > blockings_;
|
|
||||||
bool setSessionId(std::string searchedSessionId, std::string newSessionId);
|
|
||||||
private:
|
|
||||||
std::string sessionId_;
|
|
||||||
Client *client_;
|
|
||||||
std::function<void()> fct_;
|
|
||||||
int age_;
|
|
||||||
std::list<Wt::Json::Object> broadcastFifo;
|
|
||||||
};
|
|
||||||
private:
|
|
||||||
Wt::WServer *wtServer_;
|
|
||||||
bool stop_{false};
|
|
||||||
mutable std::mutex mutex_;
|
|
||||||
std::thread thread_;
|
|
||||||
bool stop;
|
|
||||||
std::vector<std::unique_ptr<Connection> > connections_;
|
|
||||||
Wt::WDate lastCountriesDownload_;
|
|
||||||
Wt::WString countriesDownloadUrl_{"https://pkgstore.datahub.io/core/country-list/data_csv/data/d7c9d7cfb42cb69f4422dec222dbbaa8/data_csv.csv"};
|
|
||||||
std::map<Wt::WString, Wt::WString> countriesMap_;
|
|
||||||
std::string responseData_;
|
|
||||||
Wt::WDateTime lastTimeoutCheck_;
|
|
||||||
std::unordered_map<std::string, MessageQueue> conversations_;
|
|
||||||
std::unordered_map<std::string, std::set<std::string> > blockings_;
|
|
||||||
std::vector<Client *> toDisconnect_;
|
|
||||||
void run();
|
|
||||||
Wt::Json::Object logoutBroadcast();
|
|
||||||
static size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* output);
|
|
||||||
bool parseCountriesData();
|
|
||||||
void reSetSessionIdInMessages(std::string oldSessionId, std::string newSessionId);
|
|
||||||
Wt::Json::Object createUserList();
|
|
||||||
void sendMessageQueueToSession(std::string receiverSessionId, std::string user1, std::string user2, std::vector<Message> messages);
|
|
||||||
void addMessageToSessionBroadcast(std::string sessionId, Wt::Json::Object message);
|
|
||||||
void sendMessageCount(std::string toSessionId);
|
|
||||||
void sendBlockedMessage(std::string sessionId, std::string toUserName);
|
|
||||||
void sendBlockDone(std::string sessionId, std::string toUserName);
|
|
||||||
void sendUnblockDone(std::string sessionId, std::string toUserName);
|
|
||||||
void checkAndLogStart();
|
|
||||||
void logClientLogin(const Wt::Json::Object &clientJson);
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // BROADCAST_H
|
|
||||||
23
src/main.cpp
23
src/main.cpp
@@ -1,23 +0,0 @@
|
|||||||
#include "broadcast.h"
|
|
||||||
#include "app.h"
|
|
||||||
#include <Wt/WServer.h>
|
|
||||||
#include <Wt/WSound.h>
|
|
||||||
|
|
||||||
std::unique_ptr<Wt::WApplication> createApplication(const Wt::WEnvironment& env, Broadcast& server)
|
|
||||||
{
|
|
||||||
return std::make_unique<App>(env, server);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
|
||||||
Wt::WServer server(argc, argv, WTHTTP_CONFIGURATION);
|
|
||||||
Broadcast chatServer(&server);
|
|
||||||
server.addEntryPoint(Wt::EntryPointType::Application,
|
|
||||||
std::bind(createApplication, std::placeholders::_1,
|
|
||||||
std::ref(chatServer)));
|
|
||||||
if (server.start()) {
|
|
||||||
int sig = Wt::WServer::waitForShutdown();
|
|
||||||
std::cerr << "Shutting down: (signal = " << sig << ")" << std::endl;
|
|
||||||
server.stop();
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user