Remove CMake configuration and application source files. This includes the deletion of CMakeLists.txt, application logic in app.cpp and app.h, and broadcast functionality in broadcast.cpp. This cleanup streamlines the project structure by removing unused files and configurations.
This commit is contained in:
@@ -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() {
|
||||
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 = '';
|
||||
}
|
||||
|
||||
|
||||
@@ -185,6 +185,10 @@ export const useChatStore = defineStore('chat', () => {
|
||||
handleWebSocketMessage({ type: 'historyResults', ...data });
|
||||
});
|
||||
|
||||
socketInstance.on('commandResult', (data) => {
|
||||
handleWebSocketMessage({ type: 'commandResult', ...data });
|
||||
});
|
||||
|
||||
socketInstance.on('unreadChats', (data) => {
|
||||
handleWebSocketMessage({ type: 'unreadChats', ...data });
|
||||
});
|
||||
@@ -287,6 +291,27 @@ export const useChatStore = defineStore('chat', () => {
|
||||
case 'historyResults':
|
||||
historyResults.value = data.results;
|
||||
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':
|
||||
unreadChatsCount.value = data.count || 0;
|
||||
break;
|
||||
@@ -354,19 +379,23 @@ export const useChatStore = defineStore('chat', () => {
|
||||
}
|
||||
|
||||
const messageId = Date.now().toString();
|
||||
const trimmed = message.trim();
|
||||
const isCommand = trimmed.startsWith('/');
|
||||
socket.value.emit('message', {
|
||||
toUserName,
|
||||
message,
|
||||
message: trimmed,
|
||||
messageId
|
||||
});
|
||||
|
||||
// Lokal hinzufügen
|
||||
messages.value.push({
|
||||
from: userName.value,
|
||||
message,
|
||||
timestamp: new Date().toISOString(),
|
||||
self: true
|
||||
});
|
||||
// Lokal hinzufügen (außer bei Commands, die serverseitig beantwortet werden)
|
||||
if (!isCommand) {
|
||||
messages.value.push({
|
||||
from: userName.value,
|
||||
message: trimmed,
|
||||
timestamp: new Date().toISOString(),
|
||||
self: true
|
||||
});
|
||||
}
|
||||
|
||||
// Timeout zurücksetzen bei Aktivität
|
||||
resetTimeoutTimer();
|
||||
|
||||
7
logs/chat-users.json
Normal file
7
logs/chat-users.json
Normal file
@@ -0,0 +1,7 @@
|
||||
[
|
||||
{
|
||||
"username": "admin",
|
||||
"passwordHash": "sha256:494a715f7e9b4071aca61bac42ca858a309524e5864f0920030862a4ae7589be",
|
||||
"rights": ["stat", "kick"]
|
||||
}
|
||||
]
|
||||
@@ -18,6 +18,8 @@ class Client {
|
||||
this.loginTimeStamp = new Date();
|
||||
this.blockedUsers = new Set();
|
||||
this.socket = null; // Socket.IO Socket-Objekt
|
||||
this.chatAuth = null; // { username, rights: Set<string> }
|
||||
this.pendingChatLogin = null; // { step: 'username'|'password', username: string }
|
||||
}
|
||||
|
||||
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 conversations = new Map(); // Key: "user1:user2" (alphabetisch sortiert)
|
||||
|
||||
@@ -223,6 +323,313 @@ export function setupBroadcast(io, __dirname) {
|
||||
downloadCountries();
|
||||
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
|
||||
io.on('connection', (socket) => {
|
||||
const request = socket.handshake;
|
||||
@@ -598,6 +1005,11 @@ export function setupBroadcast(io, __dirname) {
|
||||
}
|
||||
|
||||
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) {
|
||||
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