Exemple #1
0
/*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();
}
Exemple #2
0
/*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;
}
Exemple #3
0
/*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;
            }
        }
    }
}
Exemple #4
0
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);

}
Exemple #5
0
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));
            }
        }
    }

}
Exemple #6
0
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;
}
Exemple #7
0
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) );
}
Exemple #8
0
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));
}
Exemple #9
0
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;
}