forked from Green-Sky/tomato
add tox client and more setup
This commit is contained in:
parent
3a1c15f313
commit
a848a01527
@ -9,6 +9,9 @@ add_executable(tomato
|
|||||||
start_screen.cpp
|
start_screen.cpp
|
||||||
main_screen.hpp
|
main_screen.hpp
|
||||||
main_screen.cpp
|
main_screen.cpp
|
||||||
|
|
||||||
|
tox_client.hpp
|
||||||
|
tox_client.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_compile_features(tomato PUBLIC cxx_std_17)
|
target_compile_features(tomato PUBLIC cxx_std_17)
|
||||||
@ -17,7 +20,7 @@ target_link_libraries(tomato PUBLIC
|
|||||||
solanaceae_contact
|
solanaceae_contact
|
||||||
solanaceae_message3
|
solanaceae_message3
|
||||||
|
|
||||||
#solanaceae_plugin
|
solanaceae_plugin
|
||||||
|
|
||||||
solanaceae_toxcore
|
solanaceae_toxcore
|
||||||
solanaceae_tox_contacts
|
solanaceae_tox_contacts
|
||||||
|
@ -4,13 +4,55 @@
|
|||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
MainScreen::MainScreen(std::string save_path) {
|
MainScreen::MainScreen(std::string save_path) : rmm(cr), tc(save_path) {
|
||||||
|
tel.subscribeAll(tc);
|
||||||
|
|
||||||
|
conf.set("tox", "save_file_path", save_path);
|
||||||
|
|
||||||
|
{ // name stuff
|
||||||
|
auto name = tc.toxSelfGetName();
|
||||||
|
if (name.empty()) {
|
||||||
|
name = "tomato";
|
||||||
|
}
|
||||||
|
conf.set("tox", "name", name);
|
||||||
|
tc.setSelfName(name); // TODO: this is ugly
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: remove
|
||||||
|
std::cout << "own address: " << tc.toxSelfGetAddressStr() << "\n";
|
||||||
|
|
||||||
|
{ // setup plugin instances
|
||||||
|
g_provideInstance<ConfigModelI>("ConfigModelI", "host", &conf);
|
||||||
|
g_provideInstance<Contact3Registry>("Contact3Registry", "host", &cr);
|
||||||
|
g_provideInstance<RegistryMessageModel>("RegistryMessageModel", "host", &rmm);
|
||||||
|
|
||||||
|
g_provideInstance<ToxI>("ToxI", "host", &tc);
|
||||||
|
g_provideInstance<ToxEventProviderI>("ToxEventProviderI", "host", &tc);
|
||||||
|
|
||||||
|
// TODO: pm?
|
||||||
|
|
||||||
|
// graphics
|
||||||
|
g_provideInstance("ImGuiContext", "host", ImGui::GetCurrentContext());
|
||||||
|
//g_provideInstance<TextureUploaderI>("TextureUploaderI", "host", &ogltu);
|
||||||
|
}
|
||||||
|
|
||||||
|
conf.dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
Screen* MainScreen::poll(bool& quit) {
|
Screen* MainScreen::poll(bool& quit) {
|
||||||
|
auto new_time = std::chrono::high_resolution_clock::now();
|
||||||
|
const float time_delta {std::chrono::duration<float, std::chrono::seconds::period>(new_time - last_time).count()};
|
||||||
|
last_time = new_time;
|
||||||
|
|
||||||
|
quit = !tc.iterate();
|
||||||
|
|
||||||
|
pm.tick(time_delta);
|
||||||
|
|
||||||
|
{
|
||||||
bool open = !quit;
|
bool open = !quit;
|
||||||
ImGui::ShowDemoWindow(&open);
|
ImGui::ShowDemoWindow(&open);
|
||||||
quit = !open;
|
quit = !open;
|
||||||
|
}
|
||||||
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,33 @@
|
|||||||
|
|
||||||
#include "./screen.hpp"
|
#include "./screen.hpp"
|
||||||
|
|
||||||
|
#include <solanaceae/util/simple_config_model.hpp>
|
||||||
|
#include <solanaceae/contact/contact_model3.hpp>
|
||||||
|
#include <solanaceae/message3/registry_message_model.hpp>
|
||||||
|
#include <solanaceae/plugin/plugin_manager.hpp>
|
||||||
|
#include <solanaceae/toxcore/tox_event_logger.hpp>
|
||||||
|
|
||||||
|
#include "./tox_client.hpp"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
struct MainScreen final : public Screen {
|
struct MainScreen final : public Screen {
|
||||||
|
std::chrono::high_resolution_clock::time_point last_time = std::chrono::high_resolution_clock::now();
|
||||||
|
|
||||||
|
SimpleConfigModel conf;
|
||||||
|
Contact3Registry cr;
|
||||||
|
RegistryMessageModel rmm;
|
||||||
|
|
||||||
|
PluginManager pm;
|
||||||
|
|
||||||
|
ToxEventLogger tel{std::cout};
|
||||||
|
ToxClient tc;
|
||||||
|
|
||||||
|
//OpenGLTextureUploader ogltu;
|
||||||
|
|
||||||
|
|
||||||
MainScreen(std::string save_path);
|
MainScreen(std::string save_path);
|
||||||
~MainScreen(void) = default;
|
~MainScreen(void) = default;
|
||||||
|
|
||||||
|
@ -10,12 +10,13 @@ StartScreen::StartScreen(void) {
|
|||||||
Screen* StartScreen::poll(bool&) {
|
Screen* StartScreen::poll(bool&) {
|
||||||
|
|
||||||
// TODO: imgui tox profile selector?
|
// TODO: imgui tox profile selector?
|
||||||
// +------------------------
|
// +----------------------------
|
||||||
|
// | |*tox profile*| plugins |
|
||||||
// | +------+ +--------
|
// | +------+ +--------
|
||||||
// | | ICON | | fileselector/dropdown?
|
// | | ICON | | fileselector/dropdown?
|
||||||
// | | | | password input
|
// | | | | password input
|
||||||
// | +------+ +--------
|
// | +------+ +--------
|
||||||
// +------------------------
|
// +----------------------------
|
||||||
|
|
||||||
auto new_screen = std::make_unique<MainScreen>("tomato.tox");
|
auto new_screen = std::make_unique<MainScreen>("tomato.tox");
|
||||||
return new_screen.release();
|
return new_screen.release();
|
||||||
|
133
src/tox_client.cpp
Normal file
133
src/tox_client.cpp
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
#include "./tox_client.hpp"
|
||||||
|
|
||||||
|
#include <sodium.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <fstream>
|
||||||
|
#include <iostream>
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
ToxClient::ToxClient(std::string_view save_path) :
|
||||||
|
_tox_profile_path(save_path)
|
||||||
|
{
|
||||||
|
TOX_ERR_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);
|
||||||
|
|
||||||
|
std::vector<uint8_t> profile_data{};
|
||||||
|
if (!_tox_profile_path.empty()) {
|
||||||
|
std::ifstream ifile{_tox_profile_path, std::ios::binary};
|
||||||
|
|
||||||
|
if (ifile.is_open()) {
|
||||||
|
std::cout << "TOX loading save " << _tox_profile_path << "\n";
|
||||||
|
// fill savedata
|
||||||
|
while (ifile.good()) {
|
||||||
|
auto ch = ifile.get();
|
||||||
|
if (ch == EOF) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
profile_data.push_back(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (profile_data.empty()) {
|
||||||
|
std::cerr << "empty tox save\n";
|
||||||
|
} else {
|
||||||
|
// set options
|
||||||
|
tox_options_set_savedata_type(options, TOX_SAVEDATA_TYPE_TOX_SAVE);
|
||||||
|
tox_options_set_savedata_data(options, profile_data.data(), profile_data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
ifile.close(); // do i need this?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TOX_ERR_NEW err_new;
|
||||||
|
_tox = tox_new(options, &err_new);
|
||||||
|
tox_options_free(options);
|
||||||
|
if (err_new != TOX_ERR_NEW_OK) {
|
||||||
|
std::cerr << "tox_new failed with error code " << err_new << "\n";
|
||||||
|
throw std::runtime_error{"tox failed"};
|
||||||
|
}
|
||||||
|
|
||||||
|
// no callbacks, use events
|
||||||
|
tox_events_init(_tox);
|
||||||
|
|
||||||
|
// dht bootstrap
|
||||||
|
{
|
||||||
|
struct DHT_node {
|
||||||
|
const char *ip;
|
||||||
|
uint16_t port;
|
||||||
|
const char key_hex[TOX_PUBLIC_KEY_SIZE*2 + 1]; // 1 for null terminator
|
||||||
|
unsigned char key_bin[TOX_PUBLIC_KEY_SIZE];
|
||||||
|
};
|
||||||
|
|
||||||
|
DHT_node nodes[] =
|
||||||
|
{
|
||||||
|
// TODO: more/diff nodes
|
||||||
|
// you can change or add your own bs and tcprelays here, ideally closer to you
|
||||||
|
{"tox.plastiras.org", 443, "8E8B63299B3D520FB377FE5100E65E3322F7AE5B20A0ACED2981769FC5B43725", {}}, // LU tha14
|
||||||
|
{"tox2.plastiras.org", 33445, "B6626D386BE7E3ACA107B46F48A5C4D522D29281750D44A0CBA6A2721E79C951", {}}, // DE tha14
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
for (size_t i = 0; i < sizeof(nodes)/sizeof(DHT_node); i ++) {
|
||||||
|
sodium_hex2bin(
|
||||||
|
nodes[i].key_bin, sizeof(nodes[i].key_bin),
|
||||||
|
nodes[i].key_hex, sizeof(nodes[i].key_hex)-1,
|
||||||
|
NULL, NULL, NULL
|
||||||
|
);
|
||||||
|
tox_bootstrap(_tox, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL);
|
||||||
|
// TODO: use extra tcp option to avoid error msgs
|
||||||
|
// ... this is hardcore
|
||||||
|
tox_add_tcp_relay(_tox, nodes[i].ip, nodes[i].port, nodes[i].key_bin, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToxClient::~ToxClient(void) {
|
||||||
|
tox_kill(_tox);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ToxClient::iterate(void) {
|
||||||
|
Tox_Err_Events_Iterate err_e_it = TOX_ERR_EVENTS_ITERATE_OK;
|
||||||
|
auto* events = tox_events_iterate(_tox, false, &err_e_it);
|
||||||
|
if (err_e_it == TOX_ERR_EVENTS_ITERATE_OK && events != nullptr) {
|
||||||
|
_subscriber_raw(events);
|
||||||
|
|
||||||
|
// forward events to event handlers
|
||||||
|
dispatchEvents(events);
|
||||||
|
}
|
||||||
|
|
||||||
|
tox_events_free(events);
|
||||||
|
|
||||||
|
if (_tox_profile_dirty) {
|
||||||
|
saveToxProfile();
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxClient::subscribeRaw(std::function<void(const Tox_Events*)> fn) {
|
||||||
|
_subscriber_raw = fn;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToxClient::saveToxProfile(void) {
|
||||||
|
if (_tox_profile_path.empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
std::cout << "TOX saving\n";
|
||||||
|
|
||||||
|
std::vector<uint8_t> data{};
|
||||||
|
data.resize(tox_get_savedata_size(_tox));
|
||||||
|
tox_get_savedata(_tox, data.data());
|
||||||
|
|
||||||
|
std::ofstream ofile{_tox_profile_path, std::ios::binary};
|
||||||
|
// TODO: improve
|
||||||
|
for (const auto& ch : data) {
|
||||||
|
ofile.put(ch);
|
||||||
|
}
|
||||||
|
|
||||||
|
_tox_profile_dirty = false;
|
||||||
|
}
|
||||||
|
|
49
src/tox_client.hpp
Normal file
49
src/tox_client.hpp
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <solanaceae/toxcore/tox_default_impl.hpp>
|
||||||
|
#include <solanaceae/toxcore/tox_event_interface.hpp>
|
||||||
|
#include <solanaceae/toxcore/tox_event_provider_base.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <string_view>
|
||||||
|
#include <vector>
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
|
struct ToxEventI;
|
||||||
|
|
||||||
|
class ToxClient : public ToxDefaultImpl, public ToxEventProviderBase {
|
||||||
|
private:
|
||||||
|
bool _should_stop {false};
|
||||||
|
|
||||||
|
std::function<void(const Tox_Events*)> _subscriber_raw {[](const auto*) {}}; // only 1?
|
||||||
|
|
||||||
|
std::string _self_name;
|
||||||
|
|
||||||
|
std::string _tox_profile_path;
|
||||||
|
bool _tox_profile_dirty {true}; // set in callbacks
|
||||||
|
|
||||||
|
public:
|
||||||
|
//ToxClient(/*const CommandLine& cl*/);
|
||||||
|
ToxClient(std::string_view save_path);
|
||||||
|
~ToxClient(void);
|
||||||
|
|
||||||
|
public: // tox stuff
|
||||||
|
Tox* getTox(void) { return _tox; }
|
||||||
|
|
||||||
|
void setDirty(void) { _tox_profile_dirty = true; }
|
||||||
|
|
||||||
|
// returns false when we shoul stop the program
|
||||||
|
bool iterate(void);
|
||||||
|
void stop(void); // let it know it should exit
|
||||||
|
|
||||||
|
void setToxProfilePath(const std::string& new_path) { _tox_profile_path = new_path; }
|
||||||
|
void setSelfName(std::string_view new_name) { _self_name = new_name; toxSelfSetName(new_name); }
|
||||||
|
|
||||||
|
public: // raw events
|
||||||
|
void subscribeRaw(std::function<void(const Tox_Events*)> fn);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void saveToxProfile(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user