/*virtual*/ void gui_filterbar_c::created() { set_theme_rect(CONSTASTR("filter"), false); filtereditheight = gui->theme().conf().get_int(CONSTASTR("filtereditheight"), 25); if (prf().get_options().is(UIOPT_SHOW_SEARCH_BAR)) { gui_textfield_c &e = (MAKE_CHILD<gui_textfield_c>(getrid(), L"", MAX_PATH, 0, false) << (gui_textedit_c::TEXTCHECKFUNC)DELEGATE(this, update_filter)); edit = &e; e.set_placeholder(TOOLTIP(TTT("Search", 277)), get_default_text_color(COL_PLACEHOLDER)); e.register_kbd_callback(DELEGATE(this, cancel_filter), SSK_ESC, false); } if (prf().get_options().is(UIOPT_TAGFILETR_BAR)) { fill_tags(); } search_in_messages = prf().is_loaded() && prf().get_options().is(MSGOP_FULL_SEARCH); if (!is_all()) refresh_list(); __super::created(); }
/*virtual*/ int gui_filterbar_c::full_search_s::iterate(int pass) { // mtype 0 == MTA_MESSAGE // mtype 107 == MTA_UNDELIVERED_MESSAGE ts::str_c where(CONSTASTR("(mtype == 0 or mtype == 107) and msg like \"%")); where.encode_pointer(&flt).append(CONSTASTR("\" order by mtime") ); db->read_table(CONSTASTR("history"), DELEGATE(this, reader), where); return R_DONE; }
/*virtual*/ void mainrect_c::created() { defaultthrdraw = DTHRO_BORDER | /*DTHRO_CENTER_HOLE |*/ DTHRO_CAPTION | DTHRO_CAPTION_TEXT; set_theme_rect(CONSTASTR("mainrect"), false); __super::created(); gui->make_app_buttons( m_rid ); auto uiroot = [](RID p)->RID { gui_hgroup_c &g = MAKE_VISIBLE_CHILD<gui_hgroup_c>(p); g.allow_move_splitter(true); g.leech(TSNEW(leech_fill_parent_s)); g.leech(TSNEW(leech_save_proportions_s, CONSTASTR("main_splitter"), CONSTASTR("7060,12940"))); return g.getrid(); }; RID hg = uiroot(m_rid); RID cl = MAKE_CHILD<gui_contactlist_c>( hg ); RID chat = MAKE_CHILD<gui_conversation_c>( hg ); hg.call_restore_signal(); gmsg<ISOGM_SELECT_CONTACT>(&contacts().get_self(), 0).send(); // 1st selected item, yo g_app->F_ALLOW_AUTOUPDATE = !g_app->F_READONLY_MODE; if (const theme_rect_s *tr = themerect()) { if (tr->captextadd.x >= 18) { int sz = tr->captextadd.x - 2; ts::bitmap_c icon, rsz; if (icon.load_from_file(CONSTWSTR("icon.png"))) { rsz.create_ARGB(ts::ivec2(sz)); icon.resize_to( rsz.extbody(), ts::FILTER_BOX_LANCZOS3 ); rsz.premultiply(); icons[0] = rsz; } if (icon.load_from_file(CONSTWSTR("icon-offline.png"))) { rsz.create_ARGB(ts::ivec2(sz)); icon.resize_to(rsz.extbody(), ts::FILTER_BOX_LANCZOS3); rsz.premultiply(); icons[1] = rsz; } } } }
void active_protocol_c::worker_check() #endif { ts::str_c ipcname(CONSTASTR("isotoxin_ap_")); uint64 utg = ts::uuid(); ipcname.append_as_hex(&utg, sizeof(utg)).append_char('_'); auto ww = syncdata.lock_write(); ww().flags.set(F_WORKER); ww().flags.clear(F_WORKER_STOPED); ipcname.append( ww().data.tag ); ww.unlock(); // ipc allocated at stack isotoxin_ipc_s ipcs(ipcname, DELEGATE(this,cmdhandler)); if (ipcs.ipc_ok) { ipcp = &ipcs; push_debug_settings(); ipcp->send(ipcw(AQ_SET_PROTO) << syncdata.lock_read()().data.tag); ipcp->wait_loop(DELEGATE(this, tick)); auto w = syncdata.lock_write(); ipcp = nullptr; w().flags.clear(F_WORKER); w().flags.set(F_WORKER_STOPED); w.unlock(); spinlock::auto_simple_lock l(lbsync); for(data_header_s *dh : locked_bufs) ipcs.junct.unlock_buffer(dh); } else syncdata.lock_write()().flags.clear(F_WORKER); }
void active_protocol_c::set_configurable( const configurable_s &c, bool force_send ) { ASSERT(c.initialized); auto w = syncdata.lock_write(); if (!w().flags.is(F_CONFIGURABLE_RCVD)) { w().data.configurable = c; // just update, not send return; } configurable_s oldc = std::move(w().data.configurable); w().data.configurable = c; if (!check_netaddr(w().data.configurable.proxy.proxy_addr)) w().data.configurable.proxy.proxy_addr = CONSTASTR(DEFAULT_PROXY); if (force_send || oldc != w().data.configurable) { if (ipcp) { oldc = w().data.configurable; w.unlock(); ipcw s(AQ_CONFIGURABLE); s << (int)5; s << CONSTASTR( CFGF_PROXY_TYPE ) << ts::amake<int>(oldc.proxy.proxy_type); s << CONSTASTR( CFGF_PROXY_ADDR ) << oldc.proxy.proxy_addr; s << CONSTASTR( CFGF_SERVER_PORT ) << ts::amake<int>(oldc.server_port); s << CONSTASTR( CFGF_IPv6_ENABLE ) << (oldc.ipv6_enable ? CONSTASTR("1") : CONSTASTR("0")); s << CONSTASTR( CFGF_UDP_ENABLE ) << (oldc.udp_enable ? CONSTASTR("1") : CONSTASTR("0")); ipcp->send(s); // do not save config now // protocol will initiate save procedure itself w = syncdata.lock_write(); if (w().current_state == CR_NETWORK_ERROR) { w().current_state = CR_OK; // set to ok now. if error still exist, state will be set back to CR_NETWORK_ERROR by protocol w().flags.set(F_ONLINE_SWITCH); w.unlock(); ipcp->send(ipcw(AQ_ONLINE)); } } } }
bool active_protocol_c::cmdhandler(ipcr r) { switch(r.header().cmd) { case HA_CMD_STATUS: { commands_e c = (commands_e)r.get<int>(); cmd_result_e s = (cmd_result_e)r.get<int>(); if (c == AQ_SET_PROTO) { if (s == CR_OK) { priority = r.get<int>(); features = r.get<int>(); conn_features = r.get<int>(); auto desc = r.getastr(); auto desc_t = r.getastr(); audio_fmt.sampleRate = r.get<int>(); audio_fmt.channels = r.get<short>(); audio_fmt.bitsPerSample = r.get<short>(); auto w = syncdata.lock_write(); w().current_state = CR_OK; w().description.set_as_utf8(desc); w().description_t.set_as_utf8(desc_t); w().icon.setcopy(r.getastr()); ipcp->send(ipcw(AQ_SET_CONFIG) << w().data.config); ipcp->send(ipcw(AQ_SET_NAME) << (w().data.user_name.is_empty() ? prf().username() : w().data.user_name)); ipcp->send(ipcw(AQ_SET_STATUSMSG) << (w().data.user_statusmsg.is_empty() ? prf().userstatus() : w().data.user_statusmsg)); ipcp->send(ipcw(AQ_SET_AVATAR) << w().data.avatar); if (w().manual_cos != COS_ONLINE) set_ostate( w().manual_cos ); ipcp->send(ipcw(AQ_INIT_DONE)); if (0 != (w().data.options & active_protocol_data_s::O_AUTOCONNECT)) { ipcp->send(ipcw(AQ_ONLINE)); w().flags.set(F_ONLINE_SWITCH); } w().flags.set(F_SET_PROTO_OK); w.unlock(); gmsg<ISOGM_PROTO_LOADED> *m = TSNEW( gmsg<ISOGM_PROTO_LOADED>, id ); m->send_to_main_thread(); } else { return false; } } else if (c == AQ_SET_CONFIG || c == AQ_ONLINE) { if (s != CR_OK) { syncdata.lock_write()().current_state = s; goto we_shoud_broadcast_result; } } else { we_shoud_broadcast_result: DMSG( "cmd status: " << (int)c << (int)s ); gmsg<ISOGM_CMD_RESULT> *m = TSNEW(gmsg<ISOGM_CMD_RESULT>, id, c, s); m->send_to_main_thread(); } } break; case HQ_UPDATE_CONTACT: { gmsg<ISOGM_UPDATE_CONTACT> *m = TSNEW( gmsg<ISOGM_UPDATE_CONTACT> ); m->key.protoid = id; m->key.contactid = r.get<int>(); m->mask = r.get<int>(); m->pubid = r.getastr(); m->name = r.getastr(); m->statusmsg = r.getastr(); m->avatar_tag = r.get<int>(); m->state = (contact_state_e)r.get<int>(); m->ostate = (contact_online_state_e)r.get<int>(); m->gender = (contact_gender_e)r.get<int>(); /*int grants =*/ r.get<int>(); if (0 != (m->mask & CDM_MEMBERS)) // groupchat members { ASSERT( m->key.is_group() ); int cnt = r.get<int>(); m->members.reserve(cnt); for(int i=0; i<cnt; ++i) m->members.add( r.get<int>() ); } if (0 != (m->mask & CDM_DETAILS)) m->details = r.getastr(); m->send_to_main_thread(); } break; case HQ_MESSAGE: { gmsg<ISOGM_INCOMING_MESSAGE> *m = TSNEW(gmsg<ISOGM_INCOMING_MESSAGE>); m->groupchat.contactid = r.get<int>(); m->groupchat.protoid = m->groupchat.contactid ? id : 0; m->sender.protoid = id; m->sender.contactid = r.get<int>(); m->mt = (message_type_app_e)r.get<int>(); m->create_time = r.get<uint64>(); m->msgutf8 = r.getastr(); m->send_to_main_thread(); } break; case HQ_SAVE: syncdata.lock_write()().flags.set(F_SAVE_REQUEST); break; case HA_DELIVERED: { gmsg<ISOGM_DELIVERED> *m = TSNEW(gmsg<ISOGM_DELIVERED>, r.get<uint64>()); m->send_to_main_thread(); } break; case HA_CONFIG: { int sz; if (const void *d = r.get_data(sz)) { ts::md5_c md5; md5.update(d,sz); md5.done(); const void *md5r = r.read_data(16); if (md5r && 0 == memcmp(md5r, md5.result(), 16)) { auto w = syncdata.lock_write(); w().data.config.clear(); w().data.config.append_buf(d, sz); w().flags.set(F_CONFIG_OK|F_CONFIG_UPDATED); lastconfig = ts::Time::current(); } else { syncdata.lock_write()().flags.set(F_CONFIG_FAIL); } } } break; case HA_CONFIGURABLE: { auto w = syncdata.lock_write(); w().flags.set(F_CONFIGURABLE_RCVD); if (w().data.configurable.initialized) { configurable_s oldc = std::move(w().data.configurable); w.unlock(); set_configurable(oldc,true); } else { int n = r.get<int>(); for (int i = 0; i < n; ++i) { ts::str_c f = r.getastr(); ts::str_c v = r.getastr(); if (f.equals(CONSTASTR(CFGF_PROXY_TYPE))) w().data.configurable.proxy.proxy_type = v.as_int(); else if (f.equals(CONSTASTR(CFGF_PROXY_ADDR))) w().data.configurable.proxy.proxy_addr = v; else if (f.equals(CONSTASTR(CFGF_PROXY_ADDR))) w().data.configurable.proxy.proxy_addr = v; else if (f.equals(CONSTASTR(CFGF_SERVER_PORT))) w().data.configurable.server_port = v.as_int(); else if (f.equals(CONSTASTR(CFGF_IPv6_ENABLE))) w().data.configurable.ipv6_enable = v.as_int() != 0; else if (f.equals(CONSTASTR(CFGF_UDP_ENABLE))) w().data.configurable.udp_enable = v.as_int() != 0; w().data.configurable.initialized = true; } } } break; case HQ_AUDIO: { int gid = r.get<int>(); contact_key_s ck; ck.protoid = id | (gid << 16); // assume 65536 unique groups max ck.contactid = r.get<int>(); s3::Format fmt; fmt.sampleRate = r.get<int>(); fmt.channels = r.get<short>(); fmt.bitsPerSample = r.get<short>(); int dsz; const void *data = r.get_data(dsz); auto rd = syncdata.lock_read(); float vol = rd().volume; int dsp_flags = rd().dsp_flags; rd.unlock(); int dspf = 0; if (0 != (dsp_flags & DSP_SPEAKERS_NOISE)) dspf |= fmt_converter_s::FO_NOISE_REDUCTION; if (0 != (dsp_flags & DSP_SPEAKERS_AGC)) dspf |= fmt_converter_s::FO_GAINER; g_app->mediasystem().play_voice(ts::ref_cast<uint64>(ck), fmt, data, dsz, vol, dspf); /* ts::Time t = ts::Time::current(); static int cntc = 0; static ts::Time prevt = t; if ((t-prevt) >= 0) { prevt += 1000; DMSG("ccnt: " << cntc); cntc = 0; } ++cntc; */ } break; case HQ_STREAM_OPTIONS: { int gid = r.get<int>(); contact_key_s ck; ck.protoid = id | (gid << 16); // assume 65536 unique groups max ck.contactid = r.get<int>(); int so = r.get<int>(); ts::ivec2 sosz; sosz.x = r.get<int>(); sosz.y = r.get<int>(); gmsg<ISOGM_PEER_STREAM_OPTIONS> *m = TSNEW(gmsg<ISOGM_PEER_STREAM_OPTIONS>, ck, so, sosz); m->send_to_main_thread(); } break; case HQ_VIDEO: { ASSERT( r.sz < 0, "HQ_VIDEO must be xchg buffer" ); spinlock::auto_simple_lock l(lbsync); locked_bufs.add((data_header_s *)r.d); l.unlock(); incoming_video_frame_s *f = (incoming_video_frame_s *)(r.d + sizeof(data_header_s)); TSNEW( video_frame_decoder_c, this, f ); // not memory leak! } break; case AQ_CONTROL_FILE: { gmsg<ISOGM_FILE> *m = TSNEW(gmsg<ISOGM_FILE>); m->utag = r.get<uint64>(); m->fctl = (file_control_e)r.get<int>(); m->send_to_main_thread(); } break; case HQ_INCOMING_FILE: { gmsg<ISOGM_FILE> *m = TSNEW(gmsg<ISOGM_FILE>); m->sender.protoid = id; m->sender.contactid = r.get<int>(); m->utag = r.get<uint64>(); m->filesize = r.get<uint64>(); m->filename.set_as_utf8(r.getastr()); m->send_to_main_thread(); } break; case HQ_QUERY_FILE_PORTION: { gmsg<ISOGM_FILE> *m = TSNEW(gmsg<ISOGM_FILE>); m->utag = r.get<uint64>(); m->offset = r.get<uint64>(); m->filesize = r.get<int>(); m->send_to_main_thread(); } break; case HQ_FILE_PORTION: { gmsg<ISOGM_FILE> *m = TSNEW(gmsg<ISOGM_FILE>); m->utag = r.get<uint64>(); m->offset = r.get<uint64>(); int dsz; const void *data = r.get_data(dsz); m->data.set_size(dsz); memcpy(m->data.data(), data, dsz); m->send_to_main_thread(); } break; case HQ_AVATAR_DATA: { gmsg<ISOGM_AVATAR> *m = TSNEW(gmsg<ISOGM_AVATAR>); m->contact.protoid = id; m->contact.contactid = r.get<int>(); m->tag = r.get<int>(); int dsz; const void *data = r.get_data(dsz); m->data.set_size(dsz); memcpy(m->data.data(), data, dsz); m->send_to_main_thread(); } break; case HQ_EXPORT_DATA: { int dsz; const void *data = r.get_data(dsz); gmsg<ISOGM_EXPORT_PROTO_DATA> *m = TSNEW(gmsg<ISOGM_EXPORT_PROTO_DATA>, id); m->buf.set_size(dsz); memcpy(m->buf.data(), data, dsz); m->send_to_main_thread(); } break; case HQ_TYPING: { gmsg<ISOGM_TYPING> *m = TSNEW(gmsg<ISOGM_TYPING>); int gid = r.get<int>(); contact_key_s ck; m->contact.protoid = id | (gid << 16); // assume 65536 unique groups max m->contact.contactid = r.get<int>(); m->send_to_main_thread(); } break; } return true; }
mainrect_c::mainrect_c(MAKE_ROOT<mainrect_c> &data):gui_control_c(data) { rrect = data.rect; mrect = cfg().get<ts::irect>( CONSTASTR("main_rect_monitor"), ts::wnd_get_max_size(data.rect) ); }
void mainrect_c::onclosesave() { cfg().param(CONSTASTR("main_rect_pos"), ts::amake<ts::ivec2>(rrect.lt)); cfg().param(CONSTASTR("main_rect_size"), ts::amake<ts::ivec2>(rrect.size())); cfg().param(CONSTASTR("main_rect_monitor"), ts::amake<ts::irect>(mrect)); }
int proc_sign(const ts::wstrings_c & pars) { if (pars.size() < 3) return 0; ts::wstr_c arch = pars.get(1); ts::fix_path( arch, FNO_SIMPLIFY ); ts::wstr_c proc = pars.get(2); ts::fix_path( proc, FNO_SIMPLIFY ); if (!is_file_exists(arch.as_sptr())) { Print(FOREGROUND_RED, "arch file not found: %s\n", to_str(arch).cstr()); return 0; } if (!is_file_exists(proc.as_sptr())) { Print(FOREGROUND_RED, "proc file not found: %s\n", to_str(proc).cstr()); return 0; } ts::buf_c b; b.load_from_disk_file(arch); int archlen = b.size(); ts::md5_c md5; md5.update(b.data(), b.size()); md5.done(); ts::abp_c bp; b.load_from_disk_file(proc); bp.load(b.cstr()); ts::wstr_c procpath = ts::fn_get_path(proc); auto pa = [&]( ts::asptr p ) ->ts::wstr_c { return ts::fn_join(procpath, to_wstr(bp.get_string(p))); }; b.load_from_disk_file( pa(CONSTASTR("ver")) ); ts::str_c ver = b.cstr(); ver.replace_all('/','.').trim(); ts::str_c ss(CONSTASTR("ver=")); ss.append( ver ); ss.append(CONSTASTR("\r\nurl=")); ts::str_c path = bp.get_string(CONSTASTR("path")); path.replace_all(CONSTASTR("%ver%"), ver); path.replace_all(CONSTASTR("%https%"), CONSTASTR("https://")); path.replace_all(CONSTASTR("%http%"), CONSTASTR("http://")); path.appendcvt(ts::fn_get_name_with_ext(arch)); ss.append(path); ss.append(CONSTASTR("\r\nsize=")); ss.append_as_uint(archlen); ss.append(CONSTASTR("\r\nmd5=")); ss.append_as_hex(md5.result(), 16); unsigned char pk[crypto_sign_PUBLICKEYBYTES]; unsigned char sk[crypto_sign_SECRETKEYBYTES]; b.clear(); b.load_from_disk_file( pa(CONSTASTR("sk")) ); if (b.size() != crypto_sign_SECRETKEYBYTES) { rebuild: crypto_sign_keypair(pk, sk); FILE *f = _wfopen(pa(CONSTASTR("sk")), L"wb"); fwrite(sk, 1, sizeof(sk), f); fclose(f); ts::str_c spk; for(int i=0;i<crypto_sign_PUBLICKEYBYTES;++i) spk.append(CONSTASTR("0x")).append_as_hex(pk[i]).append(CONSTASTR(", ")); spk.trunc_length(2); f = _wfopen(pa(CONSTASTR("pk")), L"wb"); fwrite(spk.cstr(), 1, spk.get_length(), f); fclose(f); } else { memcpy(sk, b.data(), crypto_sign_SECRETKEYBYTES); crypto_sign_ed25519_sk_to_pk(pk, sk); b.load_from_disk_file( pa(CONSTASTR("pk")) ); ts::token<char> t(b.cstr(), ','); int n = 0; for(;t; ++t, ++n) { if (n >= sizeof(pk)) goto rebuild; ts::str_c nx(*t); nx.trim(); if (pk[n] != (byte)nx.as_uint()) goto rebuild; } if (n < sizeof(pk)) goto rebuild; } unsigned char sig[crypto_sign_BYTES]; unsigned long long siglen; crypto_sign_detached(sig,&siglen, (const byte *)ss.cstr(), ss.get_length(), sk); ss.append(CONSTASTR("\r\nsign=")); ss.append_as_hex(sig, (int)siglen); if (CONSTASTR("github") == bp.get_string(CONSTASTR("wiki"))) { ss.insert(0,CONSTASTR("[begin]\r\n")); ss.replace_all(CONSTASTR("\r\n"), CONSTASTR("`<br>\r\n`")); ss.replace_all(CONSTASTR("[begin]`"), CONSTASTR("[begin]")); ss.append(CONSTASTR("`<br>\r\n[end]<br>\r\n")); } FILE *f = _wfopen(pa(CONSTASTR("result")), L"wb"); fwrite(ss.cstr(), 1, ss.get_length(), f); fclose(f); return 0; }