summaryrefslogtreecommitdiff
path: root/protocols
diff options
context:
space:
mode:
Diffstat (limited to 'protocols')
-rw-r--r--protocols/Telegram/src/main.cpp20
-rw-r--r--protocols/Telegram/src/stdafx.h18
-rw-r--r--protocols/Telegram/src/t_callback.cpp4
-rw-r--r--protocols/Telegram/src/t_proto.cpp38
-rw-r--r--protocols/Telegram/src/t_proto.h4
-rw-r--r--protocols/Telegram/src/t_timers.cpp58
-rw-r--r--protocols/Telegram/src/t_utils.cpp197
7 files changed, 322 insertions, 17 deletions
diff --git a/protocols/Telegram/src/main.cpp b/protocols/Telegram/src/main.cpp
index ca4ccacb51..a186d24ca0 100644
--- a/protocols/Telegram/src/main.cpp
+++ b/protocols/Telegram/src/main.cpp
@@ -17,10 +17,27 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "stdafx.h"
+#include <delayimp.h>
+#pragma comment(lib, "delayimp.lib")
+
+FARPROC WINAPI delayHook(unsigned dliNotify, PDelayLoadInfo dli)
+{
+ switch (dliNotify)
+ {
+ case dliNotePreLoadLibrary:
+ return (FARPROC)LoadLibraryA(dli->szDll);
+ }
+ return NULL;
+}
+
+extern "C" PfnDliHook __pfnDliNotifyHook2 = delayHook;
+
+
int hLangpack;
HINSTANCE g_hInstance;
CLIST_INTERFACE *pcli;
char g_szMirVer[100];
+HANDLE hQueue;
PLUGININFOEX pluginInfo =
{
@@ -54,6 +71,7 @@ extern "C" __declspec(dllexport) const MUUID MirandaInterfaces[] = { MIID_PROTOC
extern "C" int __declspec(dllexport) Load(void)
{
+ hQueue = CreateTimerQueue();
mir_getLP(&pluginInfo);
mir_getCLI();
@@ -75,7 +93,7 @@ extern "C" int __declspec(dllexport) Load(void)
extern "C" int __declspec(dllexport) Unload(void)
{
-
+ DeleteTimerQueue(hQueue);
return 0;
}
diff --git a/protocols/Telegram/src/stdafx.h b/protocols/Telegram/src/stdafx.h
index bf44f897c1..2781bcf4f9 100644
--- a/protocols/Telegram/src/stdafx.h
+++ b/protocols/Telegram/src/stdafx.h
@@ -44,8 +44,26 @@ extern "C"
#include "tgl\tgl-net.h"
#include "tgl\tgl-timers.h"
#include "tgl\tgl-binlog.h"
+ #include "tgl\config.h"
+
+ struct event;
+ struct event_base;
+ event_base __declspec(dllimport) *event_base_new(void);
+ void *event_get_callback_arg(const void *ev);
+ struct event *event_new(void *, intptr_t, short, void(*)(intptr_t, short, void *), void *);
+ int event_del(void *);
+ int event_add(void *ev, const struct timeval *timeout);
+#define evtimer_new(b, cb, arg) event_new((b), -1, 0, (cb), (arg))
+ void event_free(void *);
+
+
+ void read_auth_file(struct tgl_state *TLS);
+ void read_state_file(struct tgl_state *TLS);
+ void write_auth_file(struct tgl_state *TLS);
+ void write_state_file(struct tgl_state *TLS);
}
+
struct MirTLS : public tgl_state, public MZeroedObject
{
struct CTelegramProto *m_proto;
diff --git a/protocols/Telegram/src/t_callback.cpp b/protocols/Telegram/src/t_callback.cpp
index 9045ab2716..1e097fc1e9 100644
--- a/protocols/Telegram/src/t_callback.cpp
+++ b/protocols/Telegram/src/t_callback.cpp
@@ -12,7 +12,7 @@ static void user_typing(tgl_state *TLS, tgl_user *U, enum tgl_typing_status stat
static void on_login_success(tgl_state *TLS)
{
-
+// write_auth_file(TLS);
}
static void on_login_failed(tgl_state *TLS)
@@ -22,7 +22,7 @@ static void on_login_failed(tgl_state *TLS)
static void on_ready(tgl_state *TLS)
{
-
+ tgl_do_update_contact_list(TLS, 0, 0);
}
void request_value(struct tgl_state *TLS, enum tgl_value_type type, const char *prompt, int num_values,
diff --git a/protocols/Telegram/src/t_proto.cpp b/protocols/Telegram/src/t_proto.cpp
index ee99a0caa9..a54ded0c61 100644
--- a/protocols/Telegram/src/t_proto.cpp
+++ b/protocols/Telegram/src/t_proto.cpp
@@ -21,15 +21,18 @@ CTelegramProto::CTelegramProto(const char* protoName, const TCHAR* userName) : P
{
TLS = new MirTLS(this);
- tgl_set_verbosity(TLS, 4);
+ tgl_set_verbosity(TLS, 10);
+ tgl_set_ev_base(TLS, event_base_new());
+
InitNetwork();
InitCallbacks();
- tgl_set_timer_methods(TLS, &tgl_libevent_timers);
+ extern struct tgl_timer_methods mtgl_libevent_timers;
- tgl_set_rsa_key(TLS, "tgl.pub");
+ tgl_set_timer_methods(TLS, &mtgl_libevent_timers);
+ tgl_set_rsa_key(TLS, "tgl.pub");
TLS->base_path = Utils_ReplaceVars("%miranda_profilesdir%\\%miranda_profilename%\\TGL_Data\\");
CreateDirectoryTree(TLS->base_path);
@@ -37,20 +40,18 @@ CTelegramProto::CTelegramProto(const char* protoName, const TCHAR* userName) : P
tgl_set_download_directory(TLS, CMStringA(FORMAT, "%s\\Downloads\\", TLS->base_path));
CreateDirectoryTree(TLS->downloads_directory);
-
-// tgl_register_app_id(TLS, TELEGRAM_API_ID, TELEGRAM_API_HASH);
-// tgl_set_app_version(TLS, g_szMirVer);
+ tgl_register_app_id(TLS, TELEGRAM_API_ID, TELEGRAM_API_HASH);
+ tgl_set_app_version(TLS, g_szMirVer);
tgl_init(TLS);
- ReadState();
- ReadAuth();
-
+ bl_do_dc_option(TLS, 1, "", 0, TELEGRAM_API_SERVER, strlen(TELEGRAM_API_SERVER), 443);
+ bl_do_set_working_dc(TLS, 1);
}
CTelegramProto::~CTelegramProto()
{
- SaveState();
+ tgl_free_all(TLS);
}
DWORD_PTR CTelegramProto::GetCaps(int type, MCONTACT)
@@ -118,9 +119,15 @@ int CTelegramProto::SendMsg(MCONTACT hContact, int flags, const char *msg)
return 0;
}
+void LoginThread(void* p)
+{
+ tgl_login(((CTelegramProto*)p)->TLS);
+}
+
int CTelegramProto::SetStatus(int iNewStatus)
{
- if (iNewStatus == ID_STATUS_ONLINE) tgl_login(TLS);
+ if (iNewStatus == ID_STATUS_ONLINE)
+ mir_forkthread(LoginThread, this);
return 0;
}
@@ -147,5 +154,14 @@ void CTelegramProto::TGLGetValue(tgl_value_type type, const char *prompt, int nu
{
case tgl_phone_number:
*result = getStringA("ID");
+ if (*result)
+ break;
+ default:
+ ENTER_STRING es = { sizeof(es) };
+ es.type = ESF_MULTILINE;
+ es.caption = mir_a2t(prompt);
+ EnterString(&es);
+ *result = mir_t2a(es.ptszResult);
+ mir_free((void*)es.caption);
};
} \ No newline at end of file
diff --git a/protocols/Telegram/src/t_proto.h b/protocols/Telegram/src/t_proto.h
index fadf3b179c..0e92605487 100644
--- a/protocols/Telegram/src/t_proto.h
+++ b/protocols/Telegram/src/t_proto.h
@@ -88,10 +88,10 @@ public:
void OnUserTyping(tgl_user *U, tgl_typing_status status);
-
+ MirTLS *TLS;
private:
- MirTLS *TLS;
+
static mir_cs accountsLock;
void ReadState();
diff --git a/protocols/Telegram/src/t_timers.cpp b/protocols/Telegram/src/t_timers.cpp
new file mode 100644
index 0000000000..c897247fab
--- /dev/null
+++ b/protocols/Telegram/src/t_timers.cpp
@@ -0,0 +1,58 @@
+
+#include "stdafx.h"
+
+extern HANDLE hQueue;
+
+struct tgl_timer
+{
+ tgl_state *TLS;
+ void(*cb)(struct tgl_state *TLS, void *arg);
+ void *arg;
+ HANDLE hTimer;
+};
+
+VOID CALLBACK WaitOrTimerCallback(
+ _In_ PVOID lpParameter,
+ _In_ BOOLEAN TimerOrWaitFired
+ )
+{
+ tgl_timer *p = (tgl_timer*)lpParameter;
+ p->cb(p->TLS, p->arg);
+ p->hTimer = 0;
+}
+
+
+struct tgl_timer *mtgl_timer_alloc (struct tgl_state *TLS, void (*cb)(struct tgl_state *TLS, void *arg), void *arg)
+{
+ tgl_timer *p = (tgl_timer *)calloc(sizeof (tgl_timer), 1);
+ p->TLS = TLS;
+ p->cb = cb;
+ p->arg = arg;
+ return p;
+}
+
+void mtgl_timer_insert (struct tgl_timer *t, double p)
+{
+ HANDLE hNewTimer = 0;
+ CreateTimerQueueTimer(&hNewTimer, hQueue, WaitOrTimerCallback, t, (DWORD)(p * 1000), 0, 0);
+ t->hTimer = hNewTimer;
+}
+
+void mtgl_timer_delete (struct tgl_timer *t) {
+ DeleteTimerQueueTimer(hQueue, t->hTimer, 0);
+ t->hTimer = 0;
+}
+
+void mtgl_timer_free (struct tgl_timer *t)
+{
+ if (t->hTimer) mtgl_timer_delete(t);
+ free(t);
+}
+
+
+struct tgl_timer_methods mtgl_libevent_timers = {
+ mtgl_timer_alloc,
+ mtgl_timer_insert,
+ mtgl_timer_delete,
+ mtgl_timer_free
+}; \ No newline at end of file
diff --git a/protocols/Telegram/src/t_utils.cpp b/protocols/Telegram/src/t_utils.cpp
index 16d9e1de4c..95a25123ae 100644
--- a/protocols/Telegram/src/t_utils.cpp
+++ b/protocols/Telegram/src/t_utils.cpp
@@ -1,5 +1,195 @@
#include "stdafx.h"
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <io.h>
+#include <stdio.h>
+
+#define DC_SERIALIZED_MAGIC 0x868aa81d
+#define STATE_FILE_MAGIC 0x28949a93
+#define SECRET_CHAT_FILE_MAGIC 0x37a1988a
+
+
+
+void read_state_file(struct tgl_state *TLS) {
+ CMStringA name(FORMAT, "%sstate", TLS->base_path);
+ int state_file_fd = open(name, O_CREAT | O_RDWR | O_BINARY, 0600);
+
+ if (state_file_fd < 0) {
+ return;
+ }
+ int version, magic;
+ if (read(state_file_fd, &magic, 4) < 4) { close(state_file_fd); return; }
+ if (magic != (int)STATE_FILE_MAGIC) { close(state_file_fd); return; }
+ if (read(state_file_fd, &version, 4) < 4 || version < 0) { close(state_file_fd); return; }
+ int x[4];
+ if (read(state_file_fd, x, 16) < 16) {
+ close(state_file_fd);
+ return;
+ }
+ int pts = x[0];
+ int qts = x[1];
+ int seq = x[2];
+ int date = x[3];
+ close(state_file_fd);
+ bl_do_set_seq(TLS, seq);
+ bl_do_set_pts(TLS, pts);
+ bl_do_set_qts(TLS, qts);
+ bl_do_set_date(TLS, date);
+ TLS->callback.logprintf("read state file: seq=%d pts=%d qts=%d date=%d", seq, pts, qts, date);
+}
+
+void write_state_file(struct tgl_state *TLS) {
+ int wseq;
+ int wpts;
+ int wqts;
+ int wdate;
+ wseq = TLS->seq; wpts = TLS->pts; wqts = TLS->qts; wdate = TLS->date;
+
+ CMStringA name(FORMAT, "%sstate", TLS->base_path);
+
+ int state_file_fd = open(name, O_CREAT | O_RDWR | O_BINARY, 0600);
+
+ if (state_file_fd < 0) {
+ return;
+ }
+ int x[6];
+ x[0] = STATE_FILE_MAGIC;
+ x[1] = 0;
+ x[2] = wpts;
+ x[3] = wqts;
+ x[4] = wseq;
+ x[5] = wdate;
+ assert(write(state_file_fd, x, 24) == 24);
+ close(state_file_fd);
+ TLS->callback.logprintf("wrote state file: wpts=%d wqts=%d wseq=%d wdate=%d", wpts, wqts, wseq, wdate);
+}
+
+void write_dc(struct tgl_dc *DC, void *extra) {
+ int auth_file_fd = *(int *)extra;
+ if (!DC) {
+ int x = 0;
+ assert(write(auth_file_fd, &x, 4) == 4);
+ return;
+ }
+ else {
+ int x = 1;
+ assert(write(auth_file_fd, &x, 4) == 4);
+ }
+
+ assert(DC->flags & TGLDCF_LOGGED_IN);
+
+ assert(write(auth_file_fd, &DC->options[0]->port, 4) == 4);
+ int l = strlen(DC->options[0]->ip);
+ assert(write(auth_file_fd, &l, 4) == 4);
+ assert(write(auth_file_fd, DC->options[0]->ip, l) == l);
+ assert(write(auth_file_fd, &DC->auth_key_id, 8) == 8);
+ assert(write(auth_file_fd, DC->auth_key, 256) == 256);
+}
+
+void write_auth_file(struct tgl_state *TLS) {
+ CMStringA name(FORMAT, "%sauth", TLS->base_path);
+ int auth_file_fd = open(name, O_CREAT | O_RDWR | O_BINARY, 0600);
+ if (auth_file_fd < 0) { return; }
+ int x = DC_SERIALIZED_MAGIC;
+ assert(write(auth_file_fd, &x, 4) == 4);
+ assert(write(auth_file_fd, &TLS->max_dc_num, 4) == 4);
+ assert(write(auth_file_fd, &TLS->dc_working_num, 4) == 4);
+
+ tgl_dc_iterator_ex(TLS, write_dc, &auth_file_fd);
+
+ assert(write(auth_file_fd, &TLS->our_id, 4) == 4);
+ close(auth_file_fd);
+ TLS->callback.logprintf("wrote auth file: magic=%d max_dc_num=%d dc_working_num=%d", x, TLS->max_dc_num, TLS->dc_working_num);
+}
+
+void read_dc(struct tgl_state *TLS, int auth_file_fd, int id, unsigned ver) {
+ int port = 0;
+ assert(read(auth_file_fd, &port, 4) == 4);
+ int l = 0;
+ assert(read(auth_file_fd, &l, 4) == 4);
+ assert(l >= 0 && l < 100);
+ char ip[100];
+ assert(read(auth_file_fd, ip, l) == l);
+ ip[l] = 0;
+
+ long long auth_key_id;
+ static unsigned char auth_key[256];
+ assert(read(auth_file_fd, &auth_key_id, 8) == 8);
+ assert(read(auth_file_fd, auth_key, 256) == 256);
+
+ bl_do_dc_option(TLS, id, "DC", 2, ip, l, port);
+ bl_do_set_auth_key(TLS, id, auth_key);
+ bl_do_dc_signed(TLS, id);
+ TLS->callback.logprintf("read dc: id=%d", id);
+}
+
+void empty_auth_file(struct tgl_state *TLS) {
+ TLS->callback.logprintf("initializing empty auth file");
+ if (TLS->test_mode) {
+ bl_do_dc_option(TLS, 1, "", 0, TG_SERVER_TEST_1, strlen(TG_SERVER_TEST_1), 443);
+ bl_do_dc_option(TLS, 2, "", 0, TG_SERVER_TEST_2, strlen(TG_SERVER_TEST_2), 443);
+ bl_do_dc_option(TLS, 3, "", 0, TG_SERVER_TEST_3, strlen(TG_SERVER_TEST_3), 443);
+ bl_do_set_working_dc(TLS, TG_SERVER_TEST_DEFAULT);
+ }
+ else {
+ bl_do_dc_option(TLS, 1, "", 0, TG_SERVER_1, strlen(TG_SERVER_1), 443);
+ bl_do_dc_option(TLS, 2, "", 0, TG_SERVER_2, strlen(TG_SERVER_2), 443);
+ bl_do_dc_option(TLS, 3, "", 0, TG_SERVER_3, strlen(TG_SERVER_3), 443);
+ bl_do_dc_option(TLS, 4, "", 0, TG_SERVER_4, strlen(TG_SERVER_4), 443);
+ bl_do_dc_option(TLS, 5, "", 0, TG_SERVER_5, strlen(TG_SERVER_5), 443);
+ bl_do_set_working_dc(TLS, TG_SERVER_DEFAULT);
+ }
+}
+
+void read_auth_file(struct tgl_state *TLS) {
+ CMStringA name(FORMAT, "%sauth", TLS->base_path);
+ int auth_file_fd = open(name, O_CREAT | O_RDWR | O_BINARY, 0600);
+ if (auth_file_fd < 0) {
+ empty_auth_file(TLS);
+ return;
+ }
+ assert(auth_file_fd >= 0);
+ unsigned x;
+ unsigned m;
+ if (read(auth_file_fd, &m, 4) < 4 || (m != DC_SERIALIZED_MAGIC)) {
+ close(auth_file_fd);
+ empty_auth_file(TLS);
+ return;
+ }
+ assert(read(auth_file_fd, &x, 4) == 4);
+ assert(x > 0);
+ int dc_working_num;
+ assert(read(auth_file_fd, &dc_working_num, 4) == 4);
+
+ int i;
+ for (i = 0; i <= (int)x; i++) {
+ int y;
+ assert(read(auth_file_fd, &y, 4) == 4);
+ if (y) {
+ read_dc(TLS, auth_file_fd, i, m);
+ }
+ }
+ bl_do_set_working_dc(TLS, dc_working_num);
+ int our_id;
+ int l = read(auth_file_fd, &our_id, 4);
+ if (l < 4) {
+ assert(!l);
+ }
+ if (our_id) {
+ bl_do_set_our_id(TLS, our_id);
+ }
+ close(auth_file_fd);
+ TLS->callback.logprintf("read auth file: dcs=%d dc_working_num=%d our_id=%d", x, dc_working_num, our_id);
+}
+
+
+
+
+
+
+
void CTelegramProto::ReadState()
{
DBVARIANT dbv = { 0 };
@@ -87,4 +277,9 @@ void CTelegramProto::ReadAuth()
}
db_free(&dbv);
-} \ No newline at end of file
+}
+
+
+void CTelegramProto::SaveAuth()
+{
+}