Compare commits
49 Commits
8ff0f13109
...
master
Author | SHA1 | Date | |
---|---|---|---|
9e42508428 | |||
e77e57fa78 | |||
bc09f94a70 | |||
7f07b90a79 | |||
f160ad1e0b | |||
754310ef00 | |||
1a032ce260 | |||
77fffb744e | |||
4a59a83eca | |||
bb9da772bc | |||
446a4939f5 | |||
71d93329c5 | |||
4b7ef79f38 | |||
4b39541d93 | |||
618ed4915e | |||
da9067ab34 | |||
4e6193a09e | |||
2c80406795 | |||
e8e9126faa | |||
80bf8f5afd | |||
949929f490 | |||
8b3af55834 | |||
343c8e7012 | |||
e459e1c166 | |||
6f239880ee | |||
e8f69c0948 | |||
0ea096c695 | |||
bd1f46349b | |||
77936081b5 | |||
6b1d949810 | |||
516b264a96 | |||
8dcede652e | |||
ee638d3a10 | |||
d00b3c6f8d | |||
de3f845918 | |||
113a9ec099 | |||
f9a43c30cc | |||
a747053a48 | |||
910029bf4f | |||
1c10d4da4c | |||
c74ccbaff1 | |||
92cf42ead5 | |||
b0b117e615 | |||
3b7f1ba312 | |||
632f4d3fe1 | |||
51c5d9b06c | |||
f83abab0a0 | |||
bd30bc8fd5 | |||
f9eae6ede9 |
11
.github/workflows/cd.yml
vendored
11
.github/workflows/cd.yml
vendored
@ -46,8 +46,11 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Dependencies
|
#- name: Install Dependencies
|
||||||
run: sudo apt update && sudo apt -y install nix
|
## TODO: is 2.6 new enough?
|
||||||
|
#run: sudo apt update && sudo apt -y install nix
|
||||||
|
|
||||||
|
- uses: cachix/install-nix-action@v24
|
||||||
|
|
||||||
- name: Nix build
|
- name: Nix build
|
||||||
run: nix build '.#static'
|
run: nix build '.#static'
|
||||||
@ -70,7 +73,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
|
run: vcpkg install pkgconf:x64-windows libsodium:x64-windows-static pthreads:x64-windows-static
|
||||||
|
|
||||||
# setup vs env
|
# setup vs env
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
@ -78,7 +81,7 @@ jobs:
|
|||||||
arch: amd64
|
arch: amd64
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
|
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
||||||
|
4
.github/workflows/ci.yml
vendored
4
.github/workflows/ci.yml
vendored
@ -59,7 +59,7 @@ jobs:
|
|||||||
submodules: recursive
|
submodules: recursive
|
||||||
|
|
||||||
- name: Install Dependencies
|
- name: Install Dependencies
|
||||||
run: vcpkg install libsodium:x64-windows-static pthreads:x64-windows-static
|
run: vcpkg install pkgconf:x64-windows libsodium:x64-windows-static pthreads:x64-windows-static
|
||||||
|
|
||||||
# setup vs env
|
# setup vs env
|
||||||
- uses: ilammy/msvc-dev-cmd@v1
|
- uses: ilammy/msvc-dev-cmd@v1
|
||||||
@ -67,7 +67,7 @@ jobs:
|
|||||||
arch: amd64
|
arch: amd64
|
||||||
|
|
||||||
- name: Configure CMake
|
- name: Configure CMake
|
||||||
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static
|
run: cmake -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_TOOLCHAIN_FILE=C:/vcpkg/scripts/buildsystems/vcpkg.cmake -DVCPKG_TARGET_TRIPLET=x64-windows-static -DPKG_CONFIG_EXECUTABLE=C:/vcpkg/installed/x64-windows/tools/pkgconf/pkgconf.exe
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} -j 4
|
||||||
|
@ -1,48 +1,61 @@
|
|||||||
cmake_minimum_required(VERSION 3.9 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.14...3.24 FATAL_ERROR)
|
||||||
|
|
||||||
# cmake setup begin
|
# cmake setup begin
|
||||||
project(tomato)
|
project(totato)
|
||||||
|
|
||||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
set(TOTATO_STANDALONE ON)
|
||||||
# defaulting to debug mode, if not specified
|
else()
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
set(TOTATO_STANDALONE OFF)
|
||||||
set(CMAKE_BUILD_TYPE "Debug")
|
|
||||||
endif()
|
endif()
|
||||||
|
message("II TOTATO_STANDALONE " ${TOTATO_STANDALONE})
|
||||||
|
|
||||||
# setup my vim ycm :D
|
#option(TOTATO_BUILD_PLUGINS "Build the toxic_games plugins" ${TOTATO_STANDALONE})
|
||||||
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
|
||||||
|
|
||||||
# more paths
|
if (TOTATO_STANDALONE)
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
# defaulting to debug mode, if not specified
|
||||||
|
if(NOT CMAKE_BUILD_TYPE)
|
||||||
|
set(CMAKE_BUILD_TYPE "Debug")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# setup my vim ycm :D
|
||||||
|
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
|
||||||
|
|
||||||
|
# more paths
|
||||||
|
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib")
|
||||||
|
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||||
|
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
|
||||||
|
endif()
|
||||||
|
|
||||||
# external libs
|
# external libs
|
||||||
add_subdirectory(./external) # before increasing warn levels, sad :(
|
add_subdirectory(./external) # before increasing warn levels, sad :(
|
||||||
|
|
||||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
if (TOTATO_STANDALONE)
|
||||||
|
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||||
|
|
||||||
# bump up warning levels appropriately for clang, gcc & msvc
|
# bump up warning levels appropriately for clang, gcc & msvc
|
||||||
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
if (${CMAKE_CXX_COMPILER_ID} STREQUAL "GNU" OR ${CMAKE_CXX_COMPILER_ID} STREQUAL "Clang")
|
||||||
add_compile_options(
|
add_compile_options(
|
||||||
-Wall -Wextra # Reasonable and standard
|
-Wall -Wextra # Reasonable and standard
|
||||||
-Wpedantic # Warn if non-standard C++ is used
|
-Wpedantic # Warn if non-standard C++ is used
|
||||||
-Wunused # Warn on anything being unused
|
-Wunused # Warn on anything being unused
|
||||||
#-Wconversion # Warn on type conversions that may lose data
|
#-Wconversion # Warn on type conversions that may lose data
|
||||||
#-Wsign-conversion # Warn on sign conversions
|
#-Wsign-conversion # Warn on sign conversions
|
||||||
-Wshadow # Warn if a variable declaration shadows one from a parent context
|
-Wshadow # Warn if a variable declaration shadows one from a parent context
|
||||||
)
|
)
|
||||||
|
|
||||||
if (NOT WIN32)
|
if (NOT WIN32)
|
||||||
#link_libraries(-fsanitize=address,undefined)
|
#link_libraries(-fsanitize=address,undefined)
|
||||||
#link_libraries(-fsanitize=undefined)
|
#link_libraries(-fsanitize=undefined)
|
||||||
endif()
|
endif()
|
||||||
elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
elseif (${CMAKE_CXX_COMPILER_ID} STREQUAL "MSVC")
|
||||||
if (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
if (CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
|
||||||
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||||
|
endif()
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
21
external/CMakeLists.txt
vendored
21
external/CMakeLists.txt
vendored
@ -1,17 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.14...3.24 FATAL_ERROR)
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
# TODO: move entt dep into solanaceae_contact
|
|
||||||
if (NOT TARGET EnTT::EnTT)
|
|
||||||
FetchContent_Declare(EnTT
|
|
||||||
GIT_REPOSITORY https://github.com/skypjack/entt.git
|
|
||||||
GIT_TAG v3.12.2
|
|
||||||
EXCLUDE_FROM_ALL
|
|
||||||
)
|
|
||||||
FetchContent_MakeAvailable(EnTT)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if (NOT TARGET solanaceae_util)
|
if (NOT TARGET solanaceae_util)
|
||||||
FetchContent_Declare(solanaceae_util
|
FetchContent_Declare(solanaceae_util
|
||||||
GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_util.git
|
GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_util.git
|
||||||
@ -48,6 +38,15 @@ if (NOT TARGET solanaceae_plugin)
|
|||||||
FetchContent_MakeAvailable(solanaceae_plugin)
|
FetchContent_MakeAvailable(solanaceae_plugin)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if (NOT TARGET solanaceae_object_store)
|
||||||
|
FetchContent_Declare(solanaceae_object_store
|
||||||
|
GIT_REPOSITORY https://github.com/Green-Sky/solanaceae_object_store.git
|
||||||
|
GIT_TAG master
|
||||||
|
EXCLUDE_FROM_ALL
|
||||||
|
)
|
||||||
|
FetchContent_MakeAvailable(solanaceae_object_store)
|
||||||
|
endif()
|
||||||
|
|
||||||
add_subdirectory(./toxcore)
|
add_subdirectory(./toxcore)
|
||||||
|
|
||||||
if (NOT TARGET solanaceae_toxcore)
|
if (NOT TARGET solanaceae_toxcore)
|
||||||
|
228
external/toxcore/CMakeLists.txt
vendored
228
external/toxcore/CMakeLists.txt
vendored
@ -1,169 +1,54 @@
|
|||||||
cmake_minimum_required(VERSION 3.14 FATAL_ERROR)
|
cmake_minimum_required(VERSION 3.13...3.16 FATAL_ERROR)
|
||||||
|
|
||||||
if (NOT TARGET toxcore)
|
if (NOT TARGET toxcore)
|
||||||
|
# HACK: support old libsodium find
|
||||||
# for find sodium
|
# libs should handle this case themselfs
|
||||||
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)
|
||||||
|
|
||||||
|
set(EXPERIMENTAL_API ON CACHE BOOL "" FORCE)
|
||||||
|
set(UNITTEST OFF CACHE BOOL "" FORCE)
|
||||||
|
set(BOOTSTRAP_DAEMON OFF CACHE BOOL "" FORCE)
|
||||||
|
#if (TOMATO_TOX_AV)
|
||||||
|
# set(BUILD_TOXAV ON CACHE BOOL "" FORCE)
|
||||||
|
# set(MUST_BUILD_TOXAV ON CACHE BOOL "" FORCE)
|
||||||
|
#endif()
|
||||||
|
|
||||||
|
|
||||||
include(FetchContent)
|
include(FetchContent)
|
||||||
|
|
||||||
FetchContent_Declare(toxcore
|
FetchContent_Declare(toxcore
|
||||||
# waiting for events on master
|
GIT_REPOSITORY https://github.com/TokTok/c-toxcore.git
|
||||||
GIT_REPOSITORY https://github.com/Green-Sky/c-toxcore.git
|
GIT_TAG v0.2.20
|
||||||
GIT_TAG ngc_events
|
|
||||||
EXCLUDE_FROM_ALL
|
EXCLUDE_FROM_ALL
|
||||||
)
|
)
|
||||||
|
|
||||||
FetchContent_GetProperties(toxcore)
|
FetchContent_GetProperties(toxcore)
|
||||||
if(NOT toxcore_POPULATED)
|
if(NOT toxcore_POPULATED)
|
||||||
FetchContent_Populate(toxcore)
|
# pupulates and adds cmake subdir
|
||||||
|
FetchContent_MakeAvailable(toxcore)
|
||||||
|
|
||||||
# TODO: should this all be in the populated if??
|
# TODO: should this all be in the populated if??
|
||||||
|
|
||||||
#set(TOX_DIR "${CMAKE_CURRENT_SOURCE_DIR}/c-toxcore/")
|
|
||||||
set(TOX_DIR "${toxcore_SOURCE_DIR}/")
|
set(TOX_DIR "${toxcore_SOURCE_DIR}/")
|
||||||
|
|
||||||
# TODO: shared
|
#message("II BUILD_TOXAV: ${BUILD_TOXAV}")
|
||||||
add_library(toxcore STATIC
|
|
||||||
${TOX_DIR}third_party/cmp/cmp.c
|
|
||||||
${TOX_DIR}third_party/cmp/cmp.h
|
|
||||||
|
|
||||||
${TOX_DIR}toxcore/announce.c
|
# the sad case
|
||||||
${TOX_DIR}toxcore/announce.h
|
add_library(toxcore INTERFACE)
|
||||||
${TOX_DIR}toxcore/bin_pack.c
|
|
||||||
${TOX_DIR}toxcore/bin_pack.h
|
|
||||||
${TOX_DIR}toxcore/bin_unpack.c
|
|
||||||
${TOX_DIR}toxcore/bin_unpack.h
|
|
||||||
${TOX_DIR}toxcore/ccompat.c
|
|
||||||
${TOX_DIR}toxcore/ccompat.h
|
|
||||||
${TOX_DIR}toxcore/crypto_core.c
|
|
||||||
${TOX_DIR}toxcore/crypto_core.h
|
|
||||||
${TOX_DIR}toxcore/DHT.c
|
|
||||||
${TOX_DIR}toxcore/DHT.h
|
|
||||||
${TOX_DIR}toxcore/events/conference_connected.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_invite.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_message.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_peer_list_changed.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_peer_name.c
|
|
||||||
${TOX_DIR}toxcore/events/conference_title.c
|
|
||||||
${TOX_DIR}toxcore/events/events_alloc.c
|
|
||||||
${TOX_DIR}toxcore/events/events_alloc.h
|
|
||||||
${TOX_DIR}toxcore/events/file_chunk_request.c
|
|
||||||
${TOX_DIR}toxcore/events/file_recv.c
|
|
||||||
${TOX_DIR}toxcore/events/file_recv_chunk.c
|
|
||||||
${TOX_DIR}toxcore/events/file_recv_control.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_connection_status.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_lossless_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_lossy_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_message.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_name.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_read_receipt.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_request.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_status.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_status_message.c
|
|
||||||
${TOX_DIR}toxcore/events/friend_typing.c
|
|
||||||
${TOX_DIR}toxcore/events/self_connection_status.c
|
|
||||||
${TOX_DIR}toxcore/events/group_custom_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/group_custom_private_packet.c
|
|
||||||
${TOX_DIR}toxcore/events/group_invite.c
|
|
||||||
${TOX_DIR}toxcore/events/group_join_fail.c
|
|
||||||
${TOX_DIR}toxcore/events/group_message.c
|
|
||||||
${TOX_DIR}toxcore/events/group_moderation.c
|
|
||||||
${TOX_DIR}toxcore/events/group_password.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_exit.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_join.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_limit.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_name.c
|
|
||||||
${TOX_DIR}toxcore/events/group_peer_status.c
|
|
||||||
${TOX_DIR}toxcore/events/group_privacy_state.c
|
|
||||||
${TOX_DIR}toxcore/events/group_private_message.c
|
|
||||||
${TOX_DIR}toxcore/events/group_self_join.c
|
|
||||||
${TOX_DIR}toxcore/events/group_topic.c
|
|
||||||
${TOX_DIR}toxcore/events/group_topic_lock.c
|
|
||||||
${TOX_DIR}toxcore/events/group_voice_state.c
|
|
||||||
${TOX_DIR}toxcore/forwarding.c
|
|
||||||
${TOX_DIR}toxcore/forwarding.h
|
|
||||||
${TOX_DIR}toxcore/friend_connection.c
|
|
||||||
${TOX_DIR}toxcore/friend_connection.h
|
|
||||||
${TOX_DIR}toxcore/friend_requests.c
|
|
||||||
${TOX_DIR}toxcore/friend_requests.h
|
|
||||||
${TOX_DIR}toxcore/group.c
|
|
||||||
${TOX_DIR}toxcore/group.h
|
|
||||||
${TOX_DIR}toxcore/group_announce.c
|
|
||||||
${TOX_DIR}toxcore/group_announce.h
|
|
||||||
${TOX_DIR}toxcore/group_moderation.c
|
|
||||||
${TOX_DIR}toxcore/group_moderation.h
|
|
||||||
${TOX_DIR}toxcore/group_chats.c
|
|
||||||
${TOX_DIR}toxcore/group_chats.h
|
|
||||||
${TOX_DIR}toxcore/group_common.h
|
|
||||||
${TOX_DIR}toxcore/group_connection.c
|
|
||||||
${TOX_DIR}toxcore/group_connection.h
|
|
||||||
${TOX_DIR}toxcore/group_onion_announce.c
|
|
||||||
${TOX_DIR}toxcore/group_onion_announce.h
|
|
||||||
${TOX_DIR}toxcore/group_pack.c
|
|
||||||
${TOX_DIR}toxcore/group_pack.h
|
|
||||||
${TOX_DIR}toxcore/LAN_discovery.c
|
|
||||||
${TOX_DIR}toxcore/LAN_discovery.h
|
|
||||||
${TOX_DIR}toxcore/list.c
|
|
||||||
${TOX_DIR}toxcore/list.h
|
|
||||||
${TOX_DIR}toxcore/logger.c
|
|
||||||
${TOX_DIR}toxcore/logger.h
|
|
||||||
${TOX_DIR}toxcore/Messenger.c
|
|
||||||
${TOX_DIR}toxcore/Messenger.h
|
|
||||||
${TOX_DIR}toxcore/mem.c
|
|
||||||
${TOX_DIR}toxcore/mem.h
|
|
||||||
${TOX_DIR}toxcore/mono_time.c
|
|
||||||
${TOX_DIR}toxcore/mono_time.h
|
|
||||||
${TOX_DIR}toxcore/net_crypto.c
|
|
||||||
${TOX_DIR}toxcore/net_crypto.h
|
|
||||||
${TOX_DIR}toxcore/network.c
|
|
||||||
${TOX_DIR}toxcore/network.h
|
|
||||||
${TOX_DIR}toxcore/onion_announce.c
|
|
||||||
${TOX_DIR}toxcore/onion_announce.h
|
|
||||||
${TOX_DIR}toxcore/onion.c
|
|
||||||
${TOX_DIR}toxcore/onion_client.c
|
|
||||||
${TOX_DIR}toxcore/onion_client.h
|
|
||||||
${TOX_DIR}toxcore/onion.h
|
|
||||||
${TOX_DIR}toxcore/ping_array.c
|
|
||||||
${TOX_DIR}toxcore/ping_array.h
|
|
||||||
${TOX_DIR}toxcore/ping.c
|
|
||||||
${TOX_DIR}toxcore/ping.h
|
|
||||||
${TOX_DIR}toxcore/shared_key_cache.c
|
|
||||||
${TOX_DIR}toxcore/shared_key_cache.h
|
|
||||||
${TOX_DIR}toxcore/state.c
|
|
||||||
${TOX_DIR}toxcore/state.h
|
|
||||||
${TOX_DIR}toxcore/TCP_client.c
|
|
||||||
${TOX_DIR}toxcore/TCP_client.h
|
|
||||||
${TOX_DIR}toxcore/TCP_common.c
|
|
||||||
${TOX_DIR}toxcore/TCP_common.h
|
|
||||||
${TOX_DIR}toxcore/TCP_connection.c
|
|
||||||
${TOX_DIR}toxcore/TCP_connection.h
|
|
||||||
${TOX_DIR}toxcore/TCP_server.c
|
|
||||||
${TOX_DIR}toxcore/TCP_server.h
|
|
||||||
${TOX_DIR}toxcore/timed_auth.c
|
|
||||||
${TOX_DIR}toxcore/timed_auth.h
|
|
||||||
${TOX_DIR}toxcore/tox_api.c
|
|
||||||
${TOX_DIR}toxcore/tox.c
|
|
||||||
${TOX_DIR}toxcore/tox_dispatch.c
|
|
||||||
${TOX_DIR}toxcore/tox_dispatch.h
|
|
||||||
${TOX_DIR}toxcore/tox_events.c
|
|
||||||
${TOX_DIR}toxcore/tox_events.h
|
|
||||||
${TOX_DIR}toxcore/tox.h
|
|
||||||
${TOX_DIR}toxcore/tox_private.c
|
|
||||||
${TOX_DIR}toxcore/tox_private.h
|
|
||||||
${TOX_DIR}toxcore/tox_unpack.c
|
|
||||||
${TOX_DIR}toxcore/tox_unpack.h
|
|
||||||
${TOX_DIR}toxcore/util.c
|
|
||||||
${TOX_DIR}toxcore/util.h
|
|
||||||
|
|
||||||
${TOX_DIR}toxencryptsave/defines.h
|
if (TARGET toxcore_static)
|
||||||
${TOX_DIR}toxencryptsave/toxencryptsave.c
|
target_link_libraries(toxcore INTERFACE toxcore_static)
|
||||||
${TOX_DIR}toxencryptsave/toxencryptsave.h
|
|
||||||
)
|
|
||||||
|
|
||||||
# HACK: "install" api headers into self
|
# the ideal case
|
||||||
# this is dirty, should be binary dir
|
#add_library(toxcore ALIAS toxcore_static)
|
||||||
# TODO: add the others
|
else()
|
||||||
|
target_link_libraries(toxcore INTERFACE toxcore_shared)
|
||||||
|
|
||||||
|
# the ideal case
|
||||||
|
#add_library(toxcore ALIAS toxcore_shared)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
# HACK: "install" api headers into binary dir
|
||||||
configure_file(
|
configure_file(
|
||||||
${TOX_DIR}toxcore/tox.h
|
${TOX_DIR}toxcore/tox.h
|
||||||
${toxcore_BINARY_DIR}/include/tox/tox.h
|
${toxcore_BINARY_DIR}/include/tox/tox.h
|
||||||
@ -179,54 +64,37 @@ if (NOT TARGET toxcore)
|
|||||||
${toxcore_BINARY_DIR}/include/tox/tox_private.h
|
${toxcore_BINARY_DIR}/include/tox/tox_private.h
|
||||||
@ONLY
|
@ONLY
|
||||||
)
|
)
|
||||||
|
configure_file(
|
||||||
|
${TOX_DIR}toxencryptsave/toxencryptsave.h
|
||||||
|
${toxcore_BINARY_DIR}/include/tox/toxencryptsave.h
|
||||||
|
@ONLY
|
||||||
|
)
|
||||||
|
#configure_file(
|
||||||
|
# ${TOX_DIR}toxav/toxav.h
|
||||||
|
# ${toxcore_BINARY_DIR}/include/tox/toxav.h
|
||||||
|
# @ONLY
|
||||||
|
#)
|
||||||
|
|
||||||
target_include_directories(toxcore PRIVATE "${TOX_DIR}toxcore")
|
target_include_directories(toxcore INTERFACE ${toxcore_BINARY_DIR}/include/)
|
||||||
target_include_directories(toxcore INTERFACE "${TOX_DIR}") #toxencryptsave
|
|
||||||
target_include_directories(toxcore PUBLIC "${toxcore_BINARY_DIR}/include/")
|
|
||||||
|
|
||||||
target_compile_definitions(toxcore PUBLIC USE_IPV6=1)
|
|
||||||
#target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_DEBUG)
|
|
||||||
target_compile_definitions(toxcore PUBLIC MIN_LOGGER_LEVEL=LOGGER_LEVEL_INFO)
|
|
||||||
|
|
||||||
find_package(unofficial-sodium CONFIG QUIET)
|
|
||||||
find_package(sodium QUIET)
|
find_package(sodium QUIET)
|
||||||
if(unofficial-sodium_FOUND) # vcpkg
|
if(unofficial-sodium_FOUND) # vcpkg
|
||||||
if(TARGET unofficial-sodium::sodium)
|
if(TARGET unofficial-sodium::sodium)
|
||||||
target_link_libraries(toxcore unofficial-sodium::sodium)
|
target_link_libraries(toxcore INTERFACE unofficial-sodium::sodium)
|
||||||
endif()
|
endif()
|
||||||
if(TARGET unofficial-sodium::sodium_config_public)
|
if(TARGET unofficial-sodium::sodium_config_public)
|
||||||
target_link_libraries(toxcore unofficial-sodium::sodium_config_public)
|
target_link_libraries(toxcore INTERFACE unofficial-sodium::sodium_config_public)
|
||||||
endif()
|
endif()
|
||||||
elseif(sodium_FOUND)
|
elseif(sodium_FOUND)
|
||||||
target_link_libraries(toxcore sodium)
|
target_link_libraries(toxcore INTERFACE sodium)
|
||||||
else()
|
else()
|
||||||
message(SEND_ERROR "missing libsodium")
|
message(SEND_ERROR "missing libsodium")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(WIN32)
|
#if(BUILD_TOXAV)
|
||||||
target_link_libraries(toxcore ws2_32 iphlpapi)
|
# set_target_properties(toxcore PROPERTIES TOX_HAS_TOXAV ON)
|
||||||
endif()
|
#endif()
|
||||||
|
|
||||||
find_package(pthreads QUIET)
|
|
||||||
if(TARGET PThreads4W::PThreads4W)
|
|
||||||
target_link_libraries(toxcore PThreads4W::PThreads4W)
|
|
||||||
else()
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
|
||||||
find_package(Threads REQUIRED)
|
|
||||||
target_link_libraries(toxcore Threads::Threads)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(DHT_Bootstrap EXCLUDE_FROM_ALL
|
|
||||||
${TOX_DIR}other/DHT_bootstrap.c
|
|
||||||
${TOX_DIR}other/bootstrap_node_packets.h
|
|
||||||
${TOX_DIR}other/bootstrap_node_packets.c
|
|
||||||
${TOX_DIR}testing/misc_tools.h
|
|
||||||
${TOX_DIR}testing/misc_tools.c
|
|
||||||
)
|
|
||||||
|
|
||||||
target_link_libraries(DHT_Bootstrap toxcore)
|
|
||||||
|
|
||||||
endif(NOT toxcore_POPULATED)
|
endif(NOT toxcore_POPULATED)
|
||||||
|
|
||||||
endif(NOT TARGET toxcore)
|
endif(NOT TARGET toxcore)
|
||||||
|
|
||||||
|
8
flake.lock
generated
8
flake.lock
generated
@ -20,16 +20,16 @@
|
|||||||
},
|
},
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"locked": {
|
"locked": {
|
||||||
"lastModified": 1694553957,
|
"lastModified": 1736692550,
|
||||||
"narHash": "sha256-8o15HEax53lBJjjcr5VHMpuuT6vBcrzSNB6y2iGlPaU=",
|
"narHash": "sha256-7tk8xH+g0sJkKLTJFOxphJxxOjMDFMWv24nXslaU2ro=",
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"rev": "e7fe745d22df5fa282b321e577fe18d4f62e0f0b",
|
"rev": "7c4869c47090dd7f9f1bdfb49a22aea026996815",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
},
|
},
|
||||||
"original": {
|
"original": {
|
||||||
"owner": "NixOS",
|
"owner": "NixOS",
|
||||||
"ref": "release-23.05",
|
"ref": "release-24.11",
|
||||||
"repo": "nixpkgs",
|
"repo": "nixpkgs",
|
||||||
"type": "github"
|
"type": "github"
|
||||||
}
|
}
|
||||||
|
41
flake.nix
41
flake.nix
@ -4,7 +4,7 @@
|
|||||||
# https://youtu.be/7ZeTP_S6ZVI
|
# https://youtu.be/7ZeTP_S6ZVI
|
||||||
|
|
||||||
inputs = {
|
inputs = {
|
||||||
nixpkgs.url = "github:NixOS/nixpkgs/release-23.05";
|
nixpkgs.url = "github:NixOS/nixpkgs/release-24.11";
|
||||||
flake-utils.url = "github:numtide/flake-utils";
|
flake-utils.url = "github:numtide/flake-utils";
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -14,11 +14,12 @@
|
|||||||
pkgs = import nixpkgs { inherit system; };
|
pkgs = import nixpkgs { inherit system; };
|
||||||
|
|
||||||
# get deps
|
# get deps
|
||||||
|
# TODO: move to inputs and lock file
|
||||||
toxcore-src = pkgs.fetchFromGitHub {
|
toxcore-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "c-toxcore";
|
owner = "TokTok"; repo = "c-toxcore";
|
||||||
fetchSubmodules = true;
|
fetchSubmodules = true;
|
||||||
rev = "d4b06edc2a35bad51b0f0950d74f61c8c70630ab"; # ngc_events
|
rev = "v0.2.20";
|
||||||
hash = "sha256-P7wTojRQRtvTx+h9+QcFdO381hniWWpAy5Yv63KWWZA=";
|
hash = "sha256-jJk3K1wDG84NtMQBmNvSDRMPYUsYIzjE0emiZ4Ugbhk=";
|
||||||
};
|
};
|
||||||
entt-src = pkgs.fetchFromGitHub {
|
entt-src = pkgs.fetchFromGitHub {
|
||||||
owner = "skypjack"; repo = "entt";
|
owner = "skypjack"; repo = "entt";
|
||||||
@ -27,33 +28,38 @@
|
|||||||
};
|
};
|
||||||
solanaceae_util-src = pkgs.fetchFromGitHub {
|
solanaceae_util-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "solanaceae_util";
|
owner = "Green-Sky"; repo = "solanaceae_util";
|
||||||
rev = "57d7178e76b41c5d0f8117fc8fb5791b4108cdc0";
|
rev = "6cbcc9463ce3c4344e06d74d7df67175ada83b5f";
|
||||||
hash = "sha256-CjBj1iYlJsLMsZvp857FrsmStV4AJ7SD7L+hzOgZMpg=";
|
hash = "sha256-puWLMzCWLBQEsslIJE9sGA7fqp8v93J4zixyu64TqhY=";
|
||||||
};
|
};
|
||||||
solanaceae_contact-src = pkgs.fetchFromGitHub {
|
solanaceae_contact-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "solanaceae_contact";
|
owner = "Green-Sky"; repo = "solanaceae_contact";
|
||||||
rev = "2d73c7272c3c254086fa067ccfdfb4072c20f7c9";
|
rev = "e2917c497c91f91f8febcd1f43e462fad8359305";
|
||||||
hash = "sha256-t6UWKMvWqXGvmsjx1JSc6fOawrzzXndaOpBntoKhLW0=";
|
hash = "sha256-gM9aT+lk+TmgiLyIeaGvHSpo55C+RNEnJvzFPLXrVMc=";
|
||||||
};
|
};
|
||||||
solanaceae_message3-src = pkgs.fetchFromGitHub {
|
solanaceae_message3-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "solanaceae_message3";
|
owner = "Green-Sky"; repo = "solanaceae_message3";
|
||||||
rev = "48fb5f0889404370006ae12b3637a77d7d4ba485";
|
rev = "e55fb46027f16a1bc078f797ae9fcc7609d15659";
|
||||||
hash = "sha256-kFA90EpAH/BciHDD7NwZs7KL1cDcGVQZCRjOazxMbvM=";
|
hash = "sha256-BdwHBCXWLiVL26djyasQEPW1PbwKCkeXdUivkPaQD3c=";
|
||||||
};
|
};
|
||||||
solanaceae_plugin-src = pkgs.fetchFromGitHub {
|
solanaceae_plugin-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "solanaceae_plugin";
|
owner = "Green-Sky"; repo = "solanaceae_plugin";
|
||||||
rev = "eeab3109e76907a0e3e8c526956ff0fa9b3bd3a2";
|
rev = "54cd23433df4acedede51e932f27d16fe4f35548";
|
||||||
hash = "sha256-knW8S4VK/U3xAWFyczSNXwx2ZA9hq2XSyr39Xh2Nsgs=";
|
hash = "sha256-Yy58w1PJFzIiN8kjqe7zerG9HewcdlBcN9P/YsjFCQs=";
|
||||||
};
|
};
|
||||||
solanaceae_toxcore-src = pkgs.fetchFromGitHub {
|
solanaceae_toxcore-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "solanaceae_toxcore";
|
owner = "Green-Sky"; repo = "solanaceae_toxcore";
|
||||||
rev = "d05875f489577e9a2c26234810058b41c3236cf7";
|
rev = "727c341899a82c911a27a5cac6d09bb23ce06b1d";
|
||||||
hash = "sha256-uQVEkTn9ww/LVhPOqrq/iKIFSaDC6/BNrYGNUg+LrzA=";
|
hash = "sha256-pI0ZKX6h/DMC9m0z4yC38kqGRP34ES12U9LcuO14fO0=";
|
||||||
};
|
};
|
||||||
solanaceae_tox-src = pkgs.fetchFromGitHub {
|
solanaceae_tox-src = pkgs.fetchFromGitHub {
|
||||||
owner = "Green-Sky"; repo = "solanaceae_tox";
|
owner = "Green-Sky"; repo = "solanaceae_tox";
|
||||||
rev = "89e74b35f83d888f8aa2e5230811b8a5e2b101a7";
|
rev = "8ad10978b96837eb7949f32ef433c5b37c2aa458";
|
||||||
hash = "sha256-PQw2290ahYfU13tHGzBttwrvZBXK+wKh6UF4xfUaRWQ=";
|
hash = "sha256-0eV8tf1CDG1xHxKmDHBMSP/5hMoB2qRagOj1meHcEFY=";
|
||||||
|
};
|
||||||
|
solanaceae_object_store-src = pkgs.fetchFromGitHub {
|
||||||
|
owner = "Green-Sky"; repo = "solanaceae_object_store";
|
||||||
|
rev = "18d2888e3452074245375f329d90520ac250b595";
|
||||||
|
hash = "sha256-vfFepPHj58c8YBSa8G8bJjD6gcCj65T0Kx5aEhqsjok=";
|
||||||
};
|
};
|
||||||
|
|
||||||
pname = "totato";
|
pname = "totato";
|
||||||
@ -65,7 +71,6 @@
|
|||||||
cmake
|
cmake
|
||||||
ninja
|
ninja
|
||||||
pkg-config
|
pkg-config
|
||||||
git # cmake FetchContent
|
|
||||||
];
|
];
|
||||||
|
|
||||||
cmakeFlags = [
|
cmakeFlags = [
|
||||||
@ -78,7 +83,9 @@
|
|||||||
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_PLUGIN=${solanaceae_plugin-src}"
|
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_PLUGIN=${solanaceae_plugin-src}"
|
||||||
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_TOXCORE=${solanaceae_toxcore-src}"
|
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_TOXCORE=${solanaceae_toxcore-src}"
|
||||||
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_TOX=${solanaceae_tox-src}"
|
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_TOX=${solanaceae_tox-src}"
|
||||||
|
"-DFETCHCONTENT_SOURCE_DIR_SOLANACEAE_OBJECT_STORE=${solanaceae_object_store-src}"
|
||||||
"-DFETCHCONTENT_SOURCE_DIR_JSON=${pkgs.nlohmann_json.src}" # we care less about version here
|
"-DFETCHCONTENT_SOURCE_DIR_JSON=${pkgs.nlohmann_json.src}" # we care less about version here
|
||||||
|
"-DFETCHCONTENT_SOURCE_DIR_ZSTD=${pkgs.zstd.src}"
|
||||||
];
|
];
|
||||||
|
|
||||||
# TODO: replace with install command
|
# TODO: replace with install command
|
||||||
|
@ -12,14 +12,28 @@ add_executable(totato
|
|||||||
./message_cleanser.hpp
|
./message_cleanser.hpp
|
||||||
./message_cleanser.cpp
|
./message_cleanser.cpp
|
||||||
|
|
||||||
./message_command_dispatcher.hpp
|
./managment_commands.hpp
|
||||||
./message_command_dispatcher.cpp
|
./managment_commands.cpp
|
||||||
|
|
||||||
|
./config_commands.hpp
|
||||||
|
./config_commands.cpp
|
||||||
|
|
||||||
|
./tox_commands.hpp
|
||||||
|
./tox_commands.cpp
|
||||||
|
|
||||||
|
./fun_commands.hpp
|
||||||
|
./fun_commands.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
|
set_target_properties(totato PROPERTIES POSITION_INDEPENDENT_CODE ON)
|
||||||
|
# probably not enough
|
||||||
|
target_compile_definitions(totato PUBLIC ENTT_API_EXPORT)
|
||||||
|
|
||||||
target_compile_features(totato PUBLIC cxx_std_17)
|
target_compile_features(totato PUBLIC cxx_std_17)
|
||||||
target_link_libraries(totato PUBLIC
|
target_link_libraries(totato PUBLIC
|
||||||
solanaceae_util
|
solanaceae_util
|
||||||
solanaceae_contact
|
solanaceae_contact
|
||||||
|
solanaceae_contact_impl
|
||||||
solanaceae_message3
|
solanaceae_message3
|
||||||
|
|
||||||
solanaceae_plugin
|
solanaceae_plugin
|
||||||
@ -28,6 +42,8 @@ target_link_libraries(totato PUBLIC
|
|||||||
solanaceae_tox_contacts
|
solanaceae_tox_contacts
|
||||||
solanaceae_tox_messages
|
solanaceae_tox_messages
|
||||||
|
|
||||||
|
solanaceae_object_store
|
||||||
|
|
||||||
nlohmann_json::nlohmann_json
|
nlohmann_json::nlohmann_json
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -2,21 +2,18 @@
|
|||||||
|
|
||||||
#include "./tox_client.hpp"
|
#include "./tox_client.hpp"
|
||||||
|
|
||||||
// TODO: add more events
|
AutoDirty::AutoDirty(ToxClient& tc) : _tc(tc), _tep_sr(_tc.newSubRef(this)) {
|
||||||
|
// TODO: add more events
|
||||||
void AutoDirty::subscribe(void) {
|
_tep_sr
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_SELF_CONNECTION_STATUS);
|
.subscribe(Tox_Event_Type::TOX_EVENT_SELF_CONNECTION_STATUS)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_FRIEND_CONNECTION_STATUS);
|
.subscribe(Tox_Event_Type::TOX_EVENT_FRIEND_CONNECTION_STATUS)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_FRIEND_REQUEST);
|
.subscribe(Tox_Event_Type::TOX_EVENT_FRIEND_REQUEST)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_GROUP_INVITE);
|
.subscribe(Tox_Event_Type::TOX_EVENT_GROUP_INVITE)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_GROUP_SELF_JOIN);
|
.subscribe(Tox_Event_Type::TOX_EVENT_GROUP_SELF_JOIN)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_GROUP_PEER_JOIN);
|
.subscribe(Tox_Event_Type::TOX_EVENT_GROUP_PEER_JOIN)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_GROUP_PEER_EXIT);
|
.subscribe(Tox_Event_Type::TOX_EVENT_GROUP_PEER_EXIT)
|
||||||
_tc.subscribe(this, Tox_Event::TOX_EVENT_CONFERENCE_INVITE);
|
.subscribe(Tox_Event_Type::TOX_EVENT_CONFERENCE_INVITE)
|
||||||
}
|
;
|
||||||
|
|
||||||
AutoDirty::AutoDirty(ToxClient& tc) : _tc(tc) {
|
|
||||||
subscribe();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AutoDirty::onToxEvent(const Tox_Event_Self_Connection_Status*) {
|
bool AutoDirty::onToxEvent(const Tox_Event_Self_Connection_Status*) {
|
||||||
|
@ -8,8 +8,7 @@ class ToxClient;
|
|||||||
// sets ToxClient dirty on some events
|
// sets ToxClient dirty on some events
|
||||||
class AutoDirty : public ToxEventI {
|
class AutoDirty : public ToxEventI {
|
||||||
ToxClient& _tc;
|
ToxClient& _tc;
|
||||||
|
ToxEventProviderI::SubscriptionReference _tep_sr;
|
||||||
void subscribe(void); // private
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
AutoDirty(ToxClient& tc);
|
AutoDirty(ToxClient& tc);
|
||||||
|
66
src/config_commands.cpp
Normal file
66
src/config_commands.cpp
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
#include "./managment_commands.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/contact_store_i.hpp>
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/message_command_dispatcher.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void registerConfigCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
) {
|
||||||
|
mcd.registerCommand(
|
||||||
|
"Config", "conf",
|
||||||
|
"set-string",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
// x x x
|
||||||
|
// 01234
|
||||||
|
if (params.size() < 5) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
// split params into:
|
||||||
|
// - module
|
||||||
|
// - category
|
||||||
|
const auto first_space_pos = params.find_first_of(' ');
|
||||||
|
|
||||||
|
// x x x
|
||||||
|
// 01234
|
||||||
|
if (first_space_pos >= int64_t(params.size())-2) {
|
||||||
|
// TODO: error?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto second_space_pos = params.find_first_of(' ', first_space_pos+1);
|
||||||
|
if (second_space_pos >= params.size()-2) {
|
||||||
|
// TODO: error?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto fist_word = params.substr(0, first_space_pos);
|
||||||
|
const auto second_word = params.substr(first_space_pos+1, second_space_pos);
|
||||||
|
const auto rest_word = params.substr(second_space_pos+1);
|
||||||
|
|
||||||
|
|
||||||
|
//conf.set("MessageCommandDispatcher", group, params, true);
|
||||||
|
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"he"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"Set the config value for a category.",
|
||||||
|
MessageCommandDispatcher::Perms::ADMIN // yes, always
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
16
src/config_commands.hpp
Normal file
16
src/config_commands.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/contact/fwd.hpp>
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
class MessageCommandDispatcher;
|
||||||
|
struct ConfigModelI;
|
||||||
|
|
||||||
|
void registerConfigCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
);
|
||||||
|
|
51
src/fun_commands.cpp
Normal file
51
src/fun_commands.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "./managment_commands.hpp"
|
||||||
|
|
||||||
|
//#include <solanaceae/util/config_model.hpp>
|
||||||
|
#include <solanaceae/contact/contact_store_i.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/message_command_dispatcher.hpp>
|
||||||
|
|
||||||
|
//#include <solanaceae/contact/components.hpp>
|
||||||
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
|
||||||
|
#include <random>
|
||||||
|
|
||||||
|
void registerFunCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
) {
|
||||||
|
mcd.registerCommand(
|
||||||
|
"fun", "fun",
|
||||||
|
"dance",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
static std::default_random_engine rng{std::random_device{}()};
|
||||||
|
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
static const std::array<std::string_view, 12> dances {
|
||||||
|
"DANCE",
|
||||||
|
"(~^.^)~",
|
||||||
|
"♪┌|∵|┘♪",
|
||||||
|
"~( °٢° )~",
|
||||||
|
"m/...(>.<)…m/",
|
||||||
|
"(~‾⌣‾)~",
|
||||||
|
"└[∵┌]└[ ∵ ]┘[┐∵]┘",
|
||||||
|
"♨(⋆‿⋆)♨",
|
||||||
|
"ヾ(*´∀`*)ノ",
|
||||||
|
"ლ(o◡oლ)",
|
||||||
|
"┌(★o☆)┘",
|
||||||
|
"ヘ(^_^ヘ)",
|
||||||
|
};
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
dances.at(rng()%dances.size())
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"Make totato dance.",
|
||||||
|
MessageCommandDispatcher::Perms::EVERYONE
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
15
src/fun_commands.hpp
Normal file
15
src/fun_commands.hpp
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
class MessageCommandDispatcher;
|
||||||
|
struct ConfigModelI;
|
||||||
|
|
||||||
|
void registerFunCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
);
|
||||||
|
|
162
src/main.cpp
162
src/main.cpp
@ -1,6 +1,7 @@
|
|||||||
|
#include <solanaceae/object_store/object_store.hpp>
|
||||||
#include <solanaceae/util/simple_config_model.hpp>
|
#include <solanaceae/util/simple_config_model.hpp>
|
||||||
#include <solanaceae/contact/contact_model3.hpp>
|
#include <solanaceae/contact/contact_store_impl.hpp>
|
||||||
#include <solanaceae/message3/registry_message_model.hpp>
|
#include <solanaceae/message3/registry_message_model_impl.hpp>
|
||||||
#include <solanaceae/message3/message_time_sort.hpp>
|
#include <solanaceae/message3/message_time_sort.hpp>
|
||||||
#include <solanaceae/plugin/plugin_manager.hpp>
|
#include <solanaceae/plugin/plugin_manager.hpp>
|
||||||
#include <solanaceae/toxcore/tox_event_logger.hpp>
|
#include <solanaceae/toxcore/tox_event_logger.hpp>
|
||||||
@ -13,10 +14,26 @@
|
|||||||
#include "./tox_client.hpp"
|
#include "./tox_client.hpp"
|
||||||
#include "./auto_dirty.hpp"
|
#include "./auto_dirty.hpp"
|
||||||
#include "./message_cleanser.hpp"
|
#include "./message_cleanser.hpp"
|
||||||
#include "./message_command_dispatcher.hpp"
|
#include <solanaceae/message3/message_command_dispatcher.hpp>
|
||||||
|
|
||||||
|
#include "./managment_commands.hpp"
|
||||||
|
#include "./config_commands.hpp"
|
||||||
|
#include "./tox_commands.hpp"
|
||||||
|
#include "./fun_commands.hpp"
|
||||||
|
#include <solanaceae/message3/components.hpp> // TODO: move uptime
|
||||||
|
|
||||||
|
//#include <solanaceae/message3/components.hpp>
|
||||||
|
//#include <solanaceae/contact/components.hpp>
|
||||||
|
//#include <solanaceae/tox_contacts/components.hpp>
|
||||||
|
//#include <solanaceae/toxcore/utils.hpp>
|
||||||
|
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
|
||||||
|
#include <entt/entt.hpp>
|
||||||
|
#include <entt/fwd.hpp>
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
#include <cmath>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
@ -31,6 +48,16 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// why is min not variadic?
|
||||||
|
template<typename... T>
|
||||||
|
float min_var(float v0, T... args) {
|
||||||
|
if constexpr (sizeof...(args) == 0) {
|
||||||
|
return v0;
|
||||||
|
} else {
|
||||||
|
return std::min(v0, min_var(args...));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::atomic_bool quit = false;
|
std::atomic_bool quit = false;
|
||||||
|
|
||||||
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) || defined (_WIN32)
|
#if defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) || defined (_WIN32)
|
||||||
@ -111,7 +138,10 @@ int main(int argc, char** argv) {
|
|||||||
signal(SIGINT, sigint_handler);
|
signal(SIGINT, sigint_handler);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
auto last_time = std::chrono::steady_clock::now();
|
const auto started_at = std::chrono::steady_clock::now();
|
||||||
|
auto last_time_tick = std::chrono::steady_clock::now();
|
||||||
|
|
||||||
|
ObjectStore2 os;
|
||||||
|
|
||||||
std::string config_path {"config.json"};
|
std::string config_path {"config.json"};
|
||||||
|
|
||||||
@ -155,35 +185,35 @@ int main(int argc, char** argv) {
|
|||||||
// TODO: name
|
// TODO: name
|
||||||
}
|
}
|
||||||
|
|
||||||
Contact3Registry cr;
|
ContactStore4Impl cs;
|
||||||
RegistryMessageModel rmm{cr};
|
RegistryMessageModelImpl rmm{cs};
|
||||||
MessageTimeSort mts{rmm};
|
MessageTimeSort mts{rmm};
|
||||||
MessageCleanser mc{cr, rmm};
|
MessageCleanser mc{cs, rmm, conf};
|
||||||
MessageCommandDispatcher mcd{cr, rmm, conf};
|
MessageCommandDispatcher mcd{cs, rmm, conf};
|
||||||
|
|
||||||
{ // setup basic commands for bot
|
{ // setup basic commands for bot
|
||||||
mcd.registerCommand(
|
mcd.registerCommand(
|
||||||
"host", "",
|
"host", "",
|
||||||
"info",
|
"info",
|
||||||
[](std::string_view) -> bool {
|
[](std::string_view, Message3Handle m) -> bool {
|
||||||
std::cout << "INFO got called :)\n";
|
std::cout << "INFO got called :)\n";
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
"Get basic information about this bot"
|
"Get basic information about this bot"
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PluginManager pm;
|
|
||||||
|
|
||||||
ToxEventLogger tel{std::cout}; // TODO: config
|
|
||||||
|
|
||||||
// TODO: password?
|
// TODO: password?
|
||||||
ToxClient tc{conf.get_string("tox", "save_file_path").value(), ""};
|
ToxClient tc{conf, conf.get_string("tox", "save_file_path").value(), ""};
|
||||||
tel.subscribeAll(tc);
|
ToxEventLogger tel{tc, std::cout}; // TODO: config
|
||||||
|
tel.subscribeAll();
|
||||||
{ // name stuff
|
{ // name stuff
|
||||||
auto name = tc.toxSelfGetName();
|
auto name = tc.toxSelfGetName();
|
||||||
if (name.empty()) {
|
if (name.empty()) {
|
||||||
name = "totato";
|
name = conf.get_string("tox", "name").value_or("totato");
|
||||||
}
|
}
|
||||||
conf.set("tox", "name", name);
|
conf.set("tox", "name", name);
|
||||||
tc.setSelfName(name); // TODO: this is ugly
|
tc.setSelfName(name); // TODO: this is ugly
|
||||||
@ -193,14 +223,19 @@ int main(int argc, char** argv) {
|
|||||||
|
|
||||||
ToxPrivateImpl tpi{tc.getTox()};
|
ToxPrivateImpl tpi{tc.getTox()};
|
||||||
AutoDirty ad{tc};
|
AutoDirty ad{tc};
|
||||||
ToxContactModel2 tcm{cr, tc, tc};
|
ToxContactModel2 tcm{cs, tc, tc};
|
||||||
ToxMessageManager tmm{rmm, cr, tcm, tc, tc};
|
ToxMessageManager tmm{rmm, cs, tcm, tc, tc};
|
||||||
ToxTransferManager ttm{rmm, cr, tcm, tc, tc};
|
ToxTransferManager ttm{rmm, cs, tcm, tc, tc, os};
|
||||||
|
|
||||||
|
PluginManager pm;
|
||||||
|
|
||||||
{ // setup plugin instances
|
{ // setup plugin instances
|
||||||
|
g_provideInstance<ObjectStore2>("ObjectStore2", "host", &os);
|
||||||
|
|
||||||
g_provideInstance<ConfigModelI>("ConfigModelI", "host", &conf);
|
g_provideInstance<ConfigModelI>("ConfigModelI", "host", &conf);
|
||||||
g_provideInstance<Contact3Registry>("Contact3Registry", "host", &cr);
|
g_provideInstance<ContactStore4I>("ContactStore4I", "host", &cs);
|
||||||
g_provideInstance<RegistryMessageModel>("RegistryMessageModel", "host", &rmm);
|
g_provideInstance<RegistryMessageModelI>("RegistryMessageModelI", "host", &rmm);
|
||||||
|
g_provideInstance<MessageCommandDispatcher>("MessageCommandDispatcher", "host", &mcd);
|
||||||
|
|
||||||
g_provideInstance<ToxI>("ToxI", "host", &tc);
|
g_provideInstance<ToxI>("ToxI", "host", &tc);
|
||||||
g_provideInstance<ToxPrivateI>("ToxPrivateI", "host", &tpi);
|
g_provideInstance<ToxPrivateI>("ToxPrivateI", "host", &tpi);
|
||||||
@ -232,30 +267,93 @@ int main(int argc, char** argv) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerManagementCommands(mcd, conf, cs, rmm);
|
||||||
|
// TODO: finish impl
|
||||||
|
//registerConfigCommands(mcd, conf, cs, rmm);
|
||||||
|
registerToxCommands(mcd, conf, cs, rmm, tc, tpi);
|
||||||
|
registerFunCommands(mcd, conf, cs, rmm);
|
||||||
|
|
||||||
|
mcd.registerCommand(
|
||||||
|
"totato", "",
|
||||||
|
"uptime",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
const auto uptime = (std::chrono::steady_clock::now() - started_at);
|
||||||
|
|
||||||
|
const auto days = std::chrono::duration_cast<std::chrono::duration<int64_t, std::ratio<86400>>>(uptime);
|
||||||
|
const auto hours = std::chrono::duration_cast<std::chrono::hours>(uptime) - std::chrono::duration_cast<std::chrono::hours>(days);
|
||||||
|
const auto minutes = (std::chrono::duration_cast<std::chrono::minutes>(uptime) - std::chrono::duration_cast<std::chrono::minutes>(days)) - std::chrono::duration_cast<std::chrono::minutes>(hours);
|
||||||
|
const auto seconds = ((std::chrono::duration_cast<std::chrono::seconds>(uptime) - std::chrono::duration_cast<std::chrono::seconds>(days)) - std::chrono::duration_cast<std::chrono::seconds>(hours)) - std::chrono::duration_cast<std::chrono::seconds>(minutes);
|
||||||
|
|
||||||
|
std::string reply_text;
|
||||||
|
reply_text += "totato uptime: ";
|
||||||
|
reply_text += std::to_string(days.count());
|
||||||
|
reply_text += "d ";
|
||||||
|
reply_text += std::to_string(hours.count());
|
||||||
|
reply_text += "h ";
|
||||||
|
reply_text += std::to_string(minutes.count());
|
||||||
|
reply_text += "min ";
|
||||||
|
reply_text += std::to_string(seconds.count());
|
||||||
|
reply_text += "s (";
|
||||||
|
reply_text += std::to_string(std::chrono::duration_cast<std::chrono::seconds>(uptime).count());
|
||||||
|
reply_text += "s)";
|
||||||
|
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
reply_text
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"get current uptime.",
|
||||||
|
MessageCommandDispatcher::Perms::EVERYONE // mod?
|
||||||
|
);
|
||||||
|
|
||||||
conf.dump();
|
conf.dump();
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(10)); // at startup, just to be safe
|
std::this_thread::sleep_for(std::chrono::milliseconds(25)); // at startup, just to be safe
|
||||||
|
|
||||||
|
float last_min_interval {0.1f};
|
||||||
while (!quit) {
|
while (!quit) {
|
||||||
//auto new_time = std::chrono::steady_clock::now();
|
auto new_time = std::chrono::steady_clock::now();
|
||||||
|
const float time_delta_tick = std::chrono::duration<float, std::chrono::seconds::period>(new_time - last_time_tick).count();
|
||||||
|
|
||||||
quit = !tc.iterate();
|
// TODO: implement the equivalent of screen->nextTick() for plugs
|
||||||
tcm.iterate(/*time_delta*/0.02f);
|
const bool tick = time_delta_tick >= last_min_interval;
|
||||||
ttm.iterate();
|
|
||||||
|
|
||||||
mts.iterate();
|
if (tick) {
|
||||||
|
quit = !tc.iterate(time_delta_tick);
|
||||||
|
tcm.iterate(time_delta_tick);
|
||||||
|
ttm.iterate();
|
||||||
|
|
||||||
pm.tick(/*time_delta*/0.02f);
|
mts.iterate();
|
||||||
|
|
||||||
mc.iterate(0.02f);
|
const float pm_interval = pm.tick(time_delta_tick);
|
||||||
|
const float mc_interval = mc.iterate(time_delta_tick);
|
||||||
|
const float mcd_interval = mcd.iterate(time_delta_tick);
|
||||||
|
const float tox_interval = std::pow(tc.toxIterationInterval(), 1.6f) / 1000.f;
|
||||||
|
|
||||||
//std::this_thread::sleep_for( // time left to get to 60fps
|
last_min_interval = min_var(
|
||||||
//std::chrono::duration<float, std::chrono::seconds::period>(0.0166f) // 60fps frame duration
|
pm_interval,
|
||||||
//- std::chrono::duration<float, std::chrono::seconds::period>(std::chrono::steady_clock::now() - new_time) // time used for rendering
|
mc_interval,
|
||||||
//);
|
mcd_interval,
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(20)); // HACK: until i figure out the best main loop
|
tox_interval
|
||||||
|
);
|
||||||
|
|
||||||
|
// dont sleep and do an extra check
|
||||||
|
|
||||||
|
last_time_tick = new_time;
|
||||||
|
//std::cout << "M: time_delta_tick: " << time_delta_tick << "\n";
|
||||||
|
//std::cout << "M: last_min_interval: " << last_min_interval << " (t:" << tox_interval << " p:" << pm_interval << ")\n";
|
||||||
|
} else {
|
||||||
|
// TODO: replace with something that works on windows
|
||||||
|
const float sleep_dur = std::max(last_min_interval-time_delta_tick, 0.001f);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(int64_t(sleep_dur*1000)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
conf.dump();
|
||||||
|
|
||||||
std::cout << "\nTOTATO shutting down...\n";
|
std::cout << "\nTOTATO shutting down...\n";
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
135
src/managment_commands.cpp
Normal file
135
src/managment_commands.cpp
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
#include "./managment_commands.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/contact_store_i.hpp>
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/message_command_dispatcher.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
#include <solanaceae/util/utils.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
static std::optional<Contact4> getContactFromIDStr(
|
||||||
|
ContactStore4I& cs,
|
||||||
|
std::string_view id_str
|
||||||
|
) {
|
||||||
|
const std::vector<uint8_t> id = hex2bin(id_str);
|
||||||
|
const auto found_contact = cs.getOneContactByID(ByteSpan{id});
|
||||||
|
|
||||||
|
if (static_cast<bool>(found_contact)) {
|
||||||
|
return found_contact;
|
||||||
|
} else {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string getStatusFromContact(
|
||||||
|
ContactHandle4 c
|
||||||
|
) {
|
||||||
|
std::string status_str;
|
||||||
|
|
||||||
|
// name
|
||||||
|
if (c.all_of<Contact::Components::Name>()) {
|
||||||
|
status_str += " name: " + c.get<Contact::Components::Name>().name;
|
||||||
|
} else {
|
||||||
|
status_str += " name: not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
// connection state
|
||||||
|
if (c.all_of<Contact::Components::ConnectionState>()) {
|
||||||
|
status_str += "\n connection: " + std::to_string(c.get<Contact::Components::ConnectionState>().state);
|
||||||
|
} else {
|
||||||
|
status_str += "\n connection: not found";
|
||||||
|
}
|
||||||
|
|
||||||
|
return status_str;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool handleContactAddToGroup(
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm,
|
||||||
|
|
||||||
|
std::string_view params,
|
||||||
|
Message3Handle m,
|
||||||
|
|
||||||
|
const std::string_view group
|
||||||
|
) {
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
// TODO: move parameter parsing to mcd
|
||||||
|
if (params.empty()) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
std::string{"error: command requires the ID for the contact to promote to "} + std::string{group}
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto target_opt = getContactFromIDStr(cs, params);
|
||||||
|
if (!target_opt.has_value()) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error: unknown contact\n"
|
||||||
|
"For practicality reasons the contact has to be observed once, before it can be added."
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string reply;
|
||||||
|
|
||||||
|
if (conf.get_bool("MessageCommandDispatcher", group, params).value_or(false)) {
|
||||||
|
reply += "warning: contact already ";
|
||||||
|
reply += group;
|
||||||
|
reply += "!\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.set("MessageCommandDispatcher", group, params, true);
|
||||||
|
|
||||||
|
reply += "Added '";
|
||||||
|
reply += params;
|
||||||
|
reply += "' to the ";
|
||||||
|
reply += group;
|
||||||
|
reply += "s.\n";
|
||||||
|
reply += getStatusFromContact(cs.contactHandle(target_opt.value()));
|
||||||
|
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
reply
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void registerManagementCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
) {
|
||||||
|
mcd.registerCommand(
|
||||||
|
"Management", "manage",
|
||||||
|
"admin-add",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
return handleContactAddToGroup(conf, cs, rmm, params, m, "admin");
|
||||||
|
},
|
||||||
|
"Add an admin by ID.",
|
||||||
|
MessageCommandDispatcher::Perms::ADMIN
|
||||||
|
);
|
||||||
|
|
||||||
|
mcd.registerCommand(
|
||||||
|
"Management", "manage",
|
||||||
|
"mod-add",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
return handleContactAddToGroup(conf, cs, rmm, params, m, "moderator");
|
||||||
|
},
|
||||||
|
"Add a moderator by ID.",
|
||||||
|
MessageCommandDispatcher::Perms::ADMIN
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
16
src/managment_commands.hpp
Normal file
16
src/managment_commands.hpp
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/contact/fwd.hpp>
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
class MessageCommandDispatcher;
|
||||||
|
struct ConfigModelI;
|
||||||
|
|
||||||
|
void registerManagementCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm
|
||||||
|
);
|
||||||
|
|
@ -1,20 +1,28 @@
|
|||||||
#include "./message_cleanser.hpp"
|
#include "./message_cleanser.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/contact_store_i.hpp>
|
||||||
#include <solanaceae/contact/components.hpp>
|
#include <solanaceae/contact/components.hpp>
|
||||||
#include <solanaceae/message3/components.hpp>
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
#include <solanaceae/util/utils.hpp>
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
MessageCleanser::MessageCleanser(Contact3Registry& cr, RegistryMessageModel& rmm) : _cr(cr), _rmm(rmm) {
|
MessageCleanser::MessageCleanser(
|
||||||
// config
|
ContactStore4I& cs,
|
||||||
// has MessageCleanser::old_age
|
RegistryMessageModelI& rmm,
|
||||||
|
ConfigModelI& conf
|
||||||
|
) : _cs(cs), _rmm(rmm), _conf(conf) {
|
||||||
|
if (!_conf.has_int("MessageCleanser", "old_age_minutes")) {
|
||||||
|
_conf.set("MessageCleanser", "old_age_minutes", int64_t(_old_age_default));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageCleanser::~MessageCleanser(void) {
|
MessageCleanser::~MessageCleanser(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MessageCleanser::iterate(float time_delta) {
|
float MessageCleanser::iterate(float time_delta) {
|
||||||
_timer += time_delta;
|
_timer += time_delta;
|
||||||
if (_timer >= _interval) {
|
if (_timer >= _interval) {
|
||||||
_timer = 0.f;
|
_timer = 0.f;
|
||||||
@ -23,28 +31,46 @@ void MessageCleanser::iterate(float time_delta) {
|
|||||||
|
|
||||||
uint64_t now_ts = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
uint64_t now_ts = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
|
||||||
|
|
||||||
uint64_t deleted_count{0};
|
const auto& cr = _cs.registry();
|
||||||
|
|
||||||
// TODO: iterate rmm directly
|
// TODO: iterate rmm directly
|
||||||
//_rmm.get();
|
//_rmm.get();
|
||||||
// workaround by iterating contacts
|
// workaround by iterating contacts
|
||||||
for (const auto& c : _cr.view<Contact::Components::TagBig>()) {
|
for (const auto& c : cr.view<Contact::Components::TagBig>()) {
|
||||||
if (auto* reg = _rmm.get(c); reg != nullptr) {
|
if (auto* reg = _rmm.get(c); reg != nullptr) {
|
||||||
|
float old_age {0.f};
|
||||||
|
{ // old age from conf
|
||||||
|
// TODO: find some way to extract this (maybe map into contact reg?)
|
||||||
|
if (const auto* id_comp = cr.try_get<Contact::Components::ID>(c); id_comp != nullptr) {
|
||||||
|
const auto id_hex = bin2hex(id_comp->data);
|
||||||
|
old_age = _conf.get_int("MessageCleanser", "old_age_minutes", id_hex).value_or(_old_age_default);
|
||||||
|
} else {
|
||||||
|
old_age = _conf.get_int("MessageCleanser", "old_age_minutes").value_or(_old_age_default);
|
||||||
|
}
|
||||||
|
old_age *= 60.f; // to sec
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<Message3> to_remove;
|
std::vector<Message3> to_remove;
|
||||||
// assuming all messages have Timestamp comp
|
// assuming all messages have Timestamp comp
|
||||||
reg->view<Message::Components::Timestamp>().each([this, now_ts, &to_remove](const Message3 ent, const Message::Components::Timestamp& ts) {
|
reg->view<Message::Components::Timestamp>().each([this, now_ts, old_age, &to_remove](const Message3 ent, const Message::Components::Timestamp& ts) {
|
||||||
if (now_ts >= ts.ts + static_cast<uint64_t>(_old_age*1000.f)) {
|
if (now_ts >= ts.ts + static_cast<uint64_t>(old_age*1000.f)) {
|
||||||
to_remove.push_back(ent);
|
to_remove.push_back(ent);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
reg->destroy(to_remove.cbegin(), to_remove.cend());
|
//reg->destroy(to_remove.cbegin(), to_remove.cend());
|
||||||
deleted_count += to_remove.size();
|
// we need to notify for every destruction, and give every listener a last chance
|
||||||
|
for (const auto c : to_remove) {
|
||||||
|
_rmm.throwEventDestroy(*reg, c);
|
||||||
|
reg->destroy(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!to_remove.empty()) {
|
||||||
|
std::cout << "MC: cleaned up " << to_remove.size() << ", age >= " << old_age << "sec\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deleted_count > 0) {
|
|
||||||
std::cout << "MC: cleaned up " << deleted_count << "\n";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return _interval - _timer;
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <solanaceae/message3/registry_message_model.hpp>
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
class MessageCleanser {
|
class MessageCleanser {
|
||||||
Contact3Registry& _cr;
|
ContactStore4I& _cs;
|
||||||
RegistryMessageModel& _rmm;
|
RegistryMessageModelI& _rmm;
|
||||||
|
ConfigModelI& _conf;
|
||||||
|
|
||||||
|
static constexpr int64_t _old_age_default{150}; // minutes
|
||||||
|
|
||||||
float _old_age{150.f*60.f}; // max 150min
|
|
||||||
float _interval{3.f*60.f}; // every 3min
|
float _interval{3.f*60.f}; // every 3min
|
||||||
float _timer{0.f};
|
float _timer{0.f};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MessageCleanser(Contact3Registry& cr, RegistryMessageModel& rmm);
|
MessageCleanser(
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm,
|
||||||
|
ConfigModelI& conf
|
||||||
|
);
|
||||||
~MessageCleanser(void);
|
~MessageCleanser(void);
|
||||||
|
|
||||||
void iterate(float time_delta);
|
float iterate(float time_delta);
|
||||||
};
|
};
|
||||||
|
@ -1,203 +0,0 @@
|
|||||||
#include "./message_command_dispatcher.hpp"
|
|
||||||
|
|
||||||
#include <solanaceae/util/config_model.hpp>
|
|
||||||
#include <solanaceae/message3/components.hpp>
|
|
||||||
|
|
||||||
#include <utility>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
//MessageCommandDispatcher::Command::Command(Command&& other) :
|
|
||||||
//m(std::move(other.m)),
|
|
||||||
//m_prefix(std::move(other.m_prefix)),
|
|
||||||
//command(std::move(other.command)),
|
|
||||||
//fn(std::move(other.fn)),
|
|
||||||
//help_text(std::move(other.help_text))
|
|
||||||
//{
|
|
||||||
//// is this really needed?
|
|
||||||
//}
|
|
||||||
|
|
||||||
MessageCommandDispatcher::MessageCommandDispatcher(
|
|
||||||
Contact3Registry& cr,
|
|
||||||
RegistryMessageModel& rmm,
|
|
||||||
ConfigModelI& conf
|
|
||||||
) :
|
|
||||||
_cr(cr), _rmm(rmm), _conf(conf)
|
|
||||||
{
|
|
||||||
_rmm.subscribe(this, RegistryMessageModel_Event::message_construct);
|
|
||||||
|
|
||||||
{ // setup basic commands for bot
|
|
||||||
registerCommand(
|
|
||||||
"host", "",
|
|
||||||
"help",
|
|
||||||
[this](std::string_view params) -> bool {
|
|
||||||
return helpCommand(params);
|
|
||||||
},
|
|
||||||
"Get help"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
MessageCommandDispatcher::~MessageCommandDispatcher(void) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageCommandDispatcher::iterate(float time_delta) {
|
|
||||||
}
|
|
||||||
|
|
||||||
static std::string_view get_first_word(std::string_view text) {
|
|
||||||
if (text.empty()) {
|
|
||||||
return text;
|
|
||||||
}
|
|
||||||
|
|
||||||
// trim
|
|
||||||
const auto pos_first_non_space = text.find_first_not_of(' ');
|
|
||||||
if (pos_first_non_space == std::string_view::npos) {
|
|
||||||
// only contains spaces o.o
|
|
||||||
return ""; // should return text as is?
|
|
||||||
}
|
|
||||||
|
|
||||||
text = text.substr(pos_first_non_space);
|
|
||||||
|
|
||||||
const auto pos_first_space = text.find_first_of(' ');
|
|
||||||
if (pos_first_space == 0 || pos_first_space == std::string_view::npos) {
|
|
||||||
// does not contain spaces
|
|
||||||
// command is whole message
|
|
||||||
return text;
|
|
||||||
} else {
|
|
||||||
return text.substr(0, pos_first_space);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void MessageCommandDispatcher::registerCommand(
|
|
||||||
std::string_view m, // module
|
|
||||||
std::string_view m_prefix, // module prefix (if any)
|
|
||||||
std::string_view command, // command
|
|
||||||
std::function<bool(std::string_view params)>&& fn,
|
|
||||||
std::string_view help_text
|
|
||||||
) {
|
|
||||||
std::string full_command_string = std::string{m_prefix} + std::string{command};
|
|
||||||
|
|
||||||
if (_command_map.count(full_command_string)) {
|
|
||||||
std::cout << "MCD warning: overwriting existing '" << full_command_string << "'\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
_command_map[full_command_string] = Command{
|
|
||||||
std::string{m},
|
|
||||||
std::string{m_prefix},
|
|
||||||
std::string{command},
|
|
||||||
std::move(fn),
|
|
||||||
std::string{help_text}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageCommandDispatcher::helpCommand(std::string_view params) {
|
|
||||||
std::cout << "MCD: help got called '" << params << "'\n";
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageCommandDispatcher::onEvent(const Message::Events::MessageConstruct& e) {
|
|
||||||
if (!e.e.all_of<Message::Components::MessageText, Message::Components::TagUnread>()) {
|
|
||||||
std::cout << "MCD: got message that is not";
|
|
||||||
|
|
||||||
if (!e.e.all_of<Message::Components::MessageText>()) {
|
|
||||||
std::cout << " text";
|
|
||||||
}
|
|
||||||
if (!e.e.all_of<Message::Components::TagUnread>()) {
|
|
||||||
std::cout << " unread";
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (e.e.any_of<Message::Components::TagMessageIsAction>()) {
|
|
||||||
std::cout << "MCD: got message that is";
|
|
||||||
if (e.e.all_of<Message::Components::TagMessageIsAction>()) {
|
|
||||||
std::cout << " action";
|
|
||||||
}
|
|
||||||
std::cout << "\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string_view message_text = e.e.get<Message::Components::MessageText>().text;
|
|
||||||
|
|
||||||
if (message_text.empty()) {
|
|
||||||
// empty message?
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: skip unrelyable synced
|
|
||||||
|
|
||||||
// TODO: is private
|
|
||||||
|
|
||||||
// TODO: has the permissions
|
|
||||||
|
|
||||||
|
|
||||||
if (false) { // is private
|
|
||||||
} else {
|
|
||||||
// check for command prefix
|
|
||||||
if (
|
|
||||||
message_text.at(0) != '!' &&
|
|
||||||
message_text.at(0) != '/'
|
|
||||||
) {
|
|
||||||
// does not start with command prefix, not for us
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// remove c prefix
|
|
||||||
message_text = message_text.substr(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (message_text.empty()) {
|
|
||||||
// empty message?
|
|
||||||
std::cout << "MCD: got empty command\n";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "MCD: got command '" << message_text << "'\n";
|
|
||||||
|
|
||||||
|
|
||||||
std::string_view first_word;
|
|
||||||
std::string_view second_word;
|
|
||||||
|
|
||||||
first_word = get_first_word(message_text);
|
|
||||||
std::cout << "------- first_word:'" << first_word << "'\n";
|
|
||||||
if (first_word.size() != message_text.size()) {
|
|
||||||
second_word = get_first_word(
|
|
||||||
message_text.substr(
|
|
||||||
// TODO: optimize this
|
|
||||||
message_text.find(first_word)
|
|
||||||
+ first_word.size()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::cout << "------- second_word:'" << second_word << "' empty:" << second_word.empty() << "\n";
|
|
||||||
|
|
||||||
// first search first + space + second word
|
|
||||||
if (!second_word.empty()) {
|
|
||||||
std::string query {first_word};
|
|
||||||
query += " ";
|
|
||||||
query += second_word;
|
|
||||||
|
|
||||||
const auto command_it = _command_map.find(query);
|
|
||||||
if (command_it != _command_map.cend()) {
|
|
||||||
command_it->second.fn(message_text);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// then seach first word only
|
|
||||||
const auto command_it = _command_map.find(std::string{first_word});
|
|
||||||
if (command_it != _command_map.cend()) {
|
|
||||||
command_it->second.fn(message_text);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MessageCommandDispatcher::onEvent(const Message::Events::MessageUpdated&) {
|
|
||||||
// do i need this?
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <solanaceae/message3/registry_message_model.hpp>
|
|
||||||
|
|
||||||
// fwd
|
|
||||||
struct ConfigModelI;
|
|
||||||
|
|
||||||
class MessageCommandDispatcher : public RegistryMessageModelEventI {
|
|
||||||
Contact3Registry& _cr;
|
|
||||||
RegistryMessageModel& _rmm;
|
|
||||||
ConfigModelI& _conf;
|
|
||||||
|
|
||||||
struct Command {
|
|
||||||
std::string m; // module
|
|
||||||
std::string m_prefix; // module prefix (if any)
|
|
||||||
std::string command; // command
|
|
||||||
std::function<bool(std::string_view params)> fn;
|
|
||||||
std::string help_text;
|
|
||||||
|
|
||||||
//Command(const Command&) = delete;
|
|
||||||
};
|
|
||||||
std::unordered_map<std::string, Command> _command_map;
|
|
||||||
|
|
||||||
public:
|
|
||||||
MessageCommandDispatcher(Contact3Registry& cr, RegistryMessageModel& rmm, ConfigModelI& conf);
|
|
||||||
~MessageCommandDispatcher(void);
|
|
||||||
|
|
||||||
void iterate(float time_delta); // do we?
|
|
||||||
|
|
||||||
// module command/command <param type(s)>
|
|
||||||
// permissions?
|
|
||||||
// - user(s)
|
|
||||||
// - group(s)
|
|
||||||
// - everyone else?
|
|
||||||
// callable
|
|
||||||
// help text?
|
|
||||||
|
|
||||||
|
|
||||||
void registerCommand(
|
|
||||||
std::string_view m, // module
|
|
||||||
std::string_view m_prefix, // module prefix (if any)
|
|
||||||
std::string_view command, // command
|
|
||||||
std::function<bool(std::string_view params)>&& fn,
|
|
||||||
std::string_view help_text
|
|
||||||
);
|
|
||||||
|
|
||||||
// generates a help
|
|
||||||
bool helpCommand(std::string_view params);
|
|
||||||
|
|
||||||
protected: // mm
|
|
||||||
bool onEvent(const Message::Events::MessageConstruct& e) override;
|
|
||||||
bool onEvent(const Message::Events::MessageUpdated& e) override;
|
|
||||||
};
|
|
||||||
|
|
@ -2,8 +2,9 @@
|
|||||||
|
|
||||||
// meh, change this
|
// meh, change this
|
||||||
#include <exception>
|
#include <exception>
|
||||||
|
#include <stdexcept>
|
||||||
#include <system_error>
|
#include <system_error>
|
||||||
#include <toxencryptsave/toxencryptsave.h>
|
#include <tox/toxencryptsave.h>
|
||||||
|
|
||||||
#include <sodium.h>
|
#include <sodium.h>
|
||||||
|
|
||||||
@ -18,12 +19,13 @@ static void eee(std::string& mod) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ToxClient::ToxClient(std::string_view save_path, std::string_view save_password) :
|
ToxClient::ToxClient(ConfigModelI& conf, std::string_view save_path, std::string_view save_password) :
|
||||||
_tox_profile_path(save_path), _tox_profile_password(save_password)
|
_tox_profile_path(save_path), _tox_profile_password(save_password)
|
||||||
{
|
{
|
||||||
TOX_ERR_OPTIONS_NEW err_opt_new;
|
TOX_ERR_OPTIONS_NEW err_opt_new;
|
||||||
Tox_Options* options = tox_options_new(&err_opt_new);
|
Tox_Options* options = tox_options_new(&err_opt_new);
|
||||||
assert(err_opt_new == TOX_ERR_OPTIONS_NEW::TOX_ERR_OPTIONS_NEW_OK);
|
assert(err_opt_new == TOX_ERR_OPTIONS_NEW::TOX_ERR_OPTIONS_NEW_OK);
|
||||||
|
std::string tmp_proxy_host; // the string needs to survive until options is freed
|
||||||
|
|
||||||
std::vector<uint8_t> profile_data{};
|
std::vector<uint8_t> profile_data{};
|
||||||
if (!_tox_profile_path.empty()) {
|
if (!_tox_profile_path.empty()) {
|
||||||
@ -67,6 +69,41 @@ ToxClient::ToxClient(std::string_view save_path, std::string_view save_password)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tox_options_set_ipv6_enabled(options, conf.get_bool("tox", "ipv6_enabled").value_or(true));
|
||||||
|
tox_options_set_udp_enabled(options, conf.get_bool("tox", "udp_enabled").value_or(true));
|
||||||
|
tox_options_set_local_discovery_enabled(options, conf.get_bool("tox", "local_discovery_enabled").value_or(true));
|
||||||
|
// TODO: should this be exposed?
|
||||||
|
tox_options_set_dht_announcements_enabled(options, conf.get_bool("tox", "dht_announcements_enabled").value_or(true));
|
||||||
|
|
||||||
|
const size_t proxy_conf_sum = conf.has_string("tox", "proxy_type")
|
||||||
|
+ conf.has_string("tox", "proxy_host")
|
||||||
|
+ conf.has_int("tox", "proxy_port")
|
||||||
|
;
|
||||||
|
// if all proxy parts defined
|
||||||
|
if (proxy_conf_sum == 3) {
|
||||||
|
const std::string_view proxy_type_str = conf.get_string("tox", "proxy_type").value();
|
||||||
|
if (proxy_type_str == "HTTP") {
|
||||||
|
tox_options_set_proxy_type(options, Tox_Proxy_Type::TOX_PROXY_TYPE_HTTP);
|
||||||
|
} else if (proxy_type_str == "SOCKS5") {
|
||||||
|
tox_options_set_proxy_type(options, Tox_Proxy_Type::TOX_PROXY_TYPE_SOCKS5);
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("invalid proxy type in config, terminating to be safe");
|
||||||
|
}
|
||||||
|
|
||||||
|
tmp_proxy_host = conf.get_string("tox", "proxy_host").value();
|
||||||
|
tox_options_set_proxy_host(options, tmp_proxy_host.c_str());
|
||||||
|
|
||||||
|
tox_options_set_proxy_port(options, conf.get_int("tox", "proxy_port").value());
|
||||||
|
} else if (proxy_conf_sum > 0) {
|
||||||
|
throw std::runtime_error("config only partly specified proxy, terminating to be safe");
|
||||||
|
}
|
||||||
|
|
||||||
|
tox_options_set_start_port(options, conf.get_int("tox", "start_port").value_or(0));
|
||||||
|
tox_options_set_end_port(options, conf.get_int("tox", "end_port").value_or(0));
|
||||||
|
tox_options_set_tcp_port(options, conf.get_int("tox", "tcp_port").value_or(0));
|
||||||
|
tox_options_set_hole_punching_enabled(options, conf.get_bool("tox", "hole_punching_enabled").value_or(true));
|
||||||
|
tox_options_set_experimental_groups_persistence(options, true);
|
||||||
|
|
||||||
TOX_ERR_NEW err_new;
|
TOX_ERR_NEW err_new;
|
||||||
_tox = tox_new(options, &err_new);
|
_tox = tox_new(options, &err_new);
|
||||||
tox_options_free(options);
|
tox_options_free(options);
|
||||||
@ -118,10 +155,13 @@ ToxClient::ToxClient(std::string_view save_path, std::string_view save_password)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ToxClient::~ToxClient(void) {
|
ToxClient::~ToxClient(void) {
|
||||||
|
if (_tox_profile_dirty) {
|
||||||
|
saveToxProfile();
|
||||||
|
}
|
||||||
tox_kill(_tox);
|
tox_kill(_tox);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ToxClient::iterate(void) {
|
bool ToxClient::iterate(float time_delta) {
|
||||||
Tox_Err_Events_Iterate err_e_it = TOX_ERR_EVENTS_ITERATE_OK;
|
Tox_Err_Events_Iterate err_e_it = TOX_ERR_EVENTS_ITERATE_OK;
|
||||||
auto* events = tox_events_iterate(_tox, false, &err_e_it);
|
auto* events = tox_events_iterate(_tox, false, &err_e_it);
|
||||||
if (err_e_it == TOX_ERR_EVENTS_ITERATE_OK && events != nullptr) {
|
if (err_e_it == TOX_ERR_EVENTS_ITERATE_OK && events != nullptr) {
|
||||||
@ -133,7 +173,8 @@ bool ToxClient::iterate(void) {
|
|||||||
|
|
||||||
tox_events_free(events);
|
tox_events_free(events);
|
||||||
|
|
||||||
if (_tox_profile_dirty) {
|
_save_heat -= time_delta;
|
||||||
|
if (_tox_profile_dirty && _save_heat <= 0.f) {
|
||||||
saveToxProfile();
|
saveToxProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,5 +218,6 @@ void ToxClient::saveToxProfile(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_tox_profile_dirty = false;
|
_tox_profile_dirty = false;
|
||||||
|
_save_heat = 10.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
|
||||||
#include <solanaceae/toxcore/tox_default_impl.hpp>
|
#include <solanaceae/toxcore/tox_default_impl.hpp>
|
||||||
#include <solanaceae/toxcore/tox_event_interface.hpp>
|
#include <solanaceae/toxcore/tox_event_interface.hpp>
|
||||||
#include <solanaceae/toxcore/tox_event_provider_base.hpp>
|
#include <solanaceae/toxcore/tox_event_provider_base.hpp>
|
||||||
@ -22,10 +24,10 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
|||||||
std::string _tox_profile_path;
|
std::string _tox_profile_path;
|
||||||
std::string _tox_profile_password;
|
std::string _tox_profile_password;
|
||||||
bool _tox_profile_dirty {true}; // set in callbacks
|
bool _tox_profile_dirty {true}; // set in callbacks
|
||||||
|
float _save_heat {0.f};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
//ToxClient(/*const CommandLine& cl*/);
|
ToxClient(ConfigModelI& conf, std::string_view save_path, std::string_view save_password);
|
||||||
ToxClient(std::string_view save_path, std::string_view save_password);
|
|
||||||
~ToxClient(void);
|
~ToxClient(void);
|
||||||
|
|
||||||
public: // tox stuff
|
public: // tox stuff
|
||||||
@ -34,7 +36,7 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
|||||||
void setDirty(void) { _tox_profile_dirty = true; }
|
void setDirty(void) { _tox_profile_dirty = true; }
|
||||||
|
|
||||||
// returns false when we shoul stop the program
|
// returns false when we shoul stop the program
|
||||||
bool iterate(void);
|
bool iterate(float time_delta);
|
||||||
void stop(void); // let it know it should exit
|
void stop(void); // let it know it should exit
|
||||||
|
|
||||||
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
|
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
|
||||||
@ -47,4 +49,3 @@ class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
|||||||
void saveToxProfile(void);
|
void saveToxProfile(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
220
src/tox_commands.cpp
Normal file
220
src/tox_commands.cpp
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
#include "./tox_commands.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/contact/contact_store_i.hpp>
|
||||||
|
#include <solanaceae/util/config_model.hpp>
|
||||||
|
#include <solanaceae/util/utils.hpp>
|
||||||
|
#include <solanaceae/toxcore/tox_interface.hpp>
|
||||||
|
#include <solanaceae/toxcore/tox_private_interface.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/message_command_dispatcher.hpp>
|
||||||
|
|
||||||
|
#include <solanaceae/message3/components.hpp>
|
||||||
|
#include <solanaceae/contact/components.hpp>
|
||||||
|
#include <solanaceae/tox_contacts/components.hpp>
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
void registerToxCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm,
|
||||||
|
ToxI& t,
|
||||||
|
ToxPrivateI& tp
|
||||||
|
) {
|
||||||
|
mcd.registerCommand(
|
||||||
|
"tox", "tox",
|
||||||
|
"status",
|
||||||
|
[&](std::string_view, Message3Handle m) -> bool {
|
||||||
|
const auto tox_self_status = t.toxSelfGetConnectionStatus();
|
||||||
|
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
std::string reply{"dht:"};
|
||||||
|
|
||||||
|
if (tox_self_status == Tox_Connection::TOX_CONNECTION_UDP) {
|
||||||
|
reply += "upd-direct";
|
||||||
|
} else if (tox_self_status == Tox_Connection::TOX_CONNECTION_TCP) {
|
||||||
|
reply += "tcp-relayed";
|
||||||
|
}
|
||||||
|
|
||||||
|
reply += "\ndht-closenum:";
|
||||||
|
reply += std::to_string(tp.toxDHTGetNumCloselist());
|
||||||
|
reply += "\ndht-closenum-announce-capable:";
|
||||||
|
reply += std::to_string(tp.toxDHTGetNumCloselistAnnounceCapable());
|
||||||
|
|
||||||
|
const auto& cr = cs.registry();
|
||||||
|
|
||||||
|
if (cr.all_of<Contact::Components::ToxFriendEphemeral>(contact_from)) {
|
||||||
|
const auto con_opt = t.toxFriendGetConnectionStatus(cr.get<Contact::Components::ToxFriendEphemeral>(contact_from).friend_number);
|
||||||
|
if (!con_opt.has_value() || con_opt.value() == Tox_Connection::TOX_CONNECTION_NONE) {
|
||||||
|
reply += "\nfriend:offline";
|
||||||
|
} else if (con_opt.value() == Tox_Connection::TOX_CONNECTION_UDP) {
|
||||||
|
reply += "\nfriend:udp-direct";
|
||||||
|
} else if (con_opt.value() == Tox_Connection::TOX_CONNECTION_TCP) {
|
||||||
|
reply += "\nfriend:tcp-relayed";
|
||||||
|
}
|
||||||
|
} else if (cr.all_of<Contact::Components::ToxGroupPeerEphemeral>(contact_from)) {
|
||||||
|
const auto [group_number, peer_number] = cr.get<Contact::Components::ToxGroupPeerEphemeral>(contact_from);
|
||||||
|
|
||||||
|
const auto [con_opt, _] = t.toxGroupPeerGetConnectionStatus(group_number, peer_number);
|
||||||
|
if (!con_opt.has_value() || con_opt.value() == Tox_Connection::TOX_CONNECTION_NONE) {
|
||||||
|
reply += "\ngroup-peer:offline";
|
||||||
|
} else if (con_opt.value() == Tox_Connection::TOX_CONNECTION_UDP) {
|
||||||
|
reply += "\ngroup-peer:udp-direct";
|
||||||
|
} else if (con_opt.value() == Tox_Connection::TOX_CONNECTION_TCP) {
|
||||||
|
reply += "\ngroup-peer:tcp-relayed";
|
||||||
|
}
|
||||||
|
} else if (cr.any_of<Contact::Components::ToxFriendPersistent, Contact::Components::ToxGroupPeerPersistent>(contact_from)) {
|
||||||
|
reply += "\noffline";
|
||||||
|
} else {
|
||||||
|
reply += "\nunk";
|
||||||
|
}
|
||||||
|
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
reply
|
||||||
|
);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"Query the tox status of dht and to you.",
|
||||||
|
MessageCommandDispatcher::Perms::EVERYONE
|
||||||
|
);
|
||||||
|
|
||||||
|
mcd.registerCommand(
|
||||||
|
"tox", "tox",
|
||||||
|
"add",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
if (params.size() != 38*2) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error adding friend, id is not the correct size!"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: add tcm interface
|
||||||
|
const auto [_, err] = t.toxFriendAdd(hex2bin(std::string{params}), "Add me, I am totato");
|
||||||
|
|
||||||
|
if (err == Tox_Err_Friend_Add::TOX_ERR_FRIEND_ADD_OK) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"freind request sent"
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error adding friend, error code " + std::to_string(err)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"add a tox friend by id"
|
||||||
|
);
|
||||||
|
|
||||||
|
mcd.registerCommand(
|
||||||
|
"tox", "tox",
|
||||||
|
"join",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
if (params.size() != 32*2) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error joining group, id is not the correct size!"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto name_opt = conf.get_string("tox", "name");
|
||||||
|
|
||||||
|
// TODO: add tcm interface
|
||||||
|
const auto [_, err] = t.toxGroupJoin(hex2bin(std::string{params}), std::string{name_opt.value_or("no-name-found")}, "");
|
||||||
|
if (err == Tox_Err_Group_Join::TOX_ERR_GROUP_JOIN_OK) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"joining group..."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error joining group, error code " + std::to_string(err)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"join a tox group by id"
|
||||||
|
);
|
||||||
|
|
||||||
|
mcd.registerCommand(
|
||||||
|
"tox", "tox",
|
||||||
|
"invite",
|
||||||
|
[&](std::string_view params, Message3Handle m) -> bool {
|
||||||
|
const auto contact_from = m.get<Message::Components::ContactFrom>().c;
|
||||||
|
|
||||||
|
// trim friend extra stuff
|
||||||
|
if (params.size() < 32*2) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error inviting, friend id is not the correct size!"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto friend_id = hex2bin(std::string{params.substr(0, 32*2)});
|
||||||
|
|
||||||
|
auto [friend_number_opt, err] = t.toxFriendByPublicKey(friend_id);
|
||||||
|
if (!friend_number_opt.has_value()) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error inviting, friend not found!"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& cr = cs.registry();
|
||||||
|
|
||||||
|
// get current group
|
||||||
|
if (!cr.all_of<Contact::Components::Parent>(contact_from)) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error inviting, not sent from group!"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
const auto contact_group = cr.get<Contact::Components::Parent>(contact_from).parent;
|
||||||
|
|
||||||
|
if (!cr.all_of<Contact::Components::ToxGroupEphemeral>(contact_from)) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error inviting, group not connected (what?!?)!"
|
||||||
|
);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto inv_err = t.toxGroupInviteFriend(
|
||||||
|
cr.get<Contact::Components::ToxGroupEphemeral>(contact_group).group_number,
|
||||||
|
friend_number_opt.value()
|
||||||
|
);
|
||||||
|
if (inv_err == Tox_Err_Group_Invite_Friend::TOX_ERR_GROUP_INVITE_FRIEND_OK) {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"invite sent..."
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
rmm.sendText(
|
||||||
|
contact_from,
|
||||||
|
"error inviting to group, error code " + std::to_string(inv_err)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
"invite a tox friend to the same tox group"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
20
src/tox_commands.hpp
Normal file
20
src/tox_commands.hpp
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/contact/fwd.hpp>
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
|
||||||
|
// fwd
|
||||||
|
class MessageCommandDispatcher;
|
||||||
|
struct ConfigModelI;
|
||||||
|
struct ToxI;
|
||||||
|
struct ToxPrivateI;
|
||||||
|
|
||||||
|
void registerToxCommands(
|
||||||
|
MessageCommandDispatcher& mcd,
|
||||||
|
ConfigModelI& conf,
|
||||||
|
ContactStore4I& cs,
|
||||||
|
RegistryMessageModelI& rmm,
|
||||||
|
ToxI& t,
|
||||||
|
ToxPrivateI& tp
|
||||||
|
);
|
||||||
|
|
@ -16,4 +16,20 @@ struct ToxPrivateImpl : public ToxPrivateI {
|
|||||||
uint16_t toxDHTGetNumCloselistAnnounceCapable(void) override {
|
uint16_t toxDHTGetNumCloselistAnnounceCapable(void) override {
|
||||||
return tox_dht_get_num_closelist_announce_capable(_tox);
|
return tox_dht_get_num_closelist_announce_capable(_tox);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::tuple<std::optional<std::string>, Tox_Err_Group_Peer_Query> toxGroupPeerGetIPAddress(uint32_t group_number, uint32_t peer_id) override {
|
||||||
|
Tox_Err_Group_Peer_Query err = TOX_ERR_GROUP_PEER_QUERY_OK;
|
||||||
|
size_t str_size = tox_group_peer_get_ip_address_size(_tox, group_number, peer_id, &err);
|
||||||
|
if (err != TOX_ERR_GROUP_PEER_QUERY_OK) {
|
||||||
|
return {std::nullopt, err};
|
||||||
|
}
|
||||||
|
std::string ip_str(str_size, '\0');
|
||||||
|
|
||||||
|
tox_group_peer_get_ip_address(_tox, group_number, peer_id, reinterpret_cast<uint8_t*>(ip_str.data()), &err);
|
||||||
|
if (err == TOX_ERR_GROUP_PEER_QUERY_OK) {
|
||||||
|
return {ip_str, err};
|
||||||
|
} else {
|
||||||
|
return {std::nullopt, err};
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user